TensorFlow RNN-模型固定步长输出错误

我开始了一个非常简单的RNN项目来巩固我在TensorFlow中的知识,基本上是一个使用LSTM和TensorFlow的简单序列生成器。这个项目只是一个多对一的序列生成,输入是一个包含4个整数的窗口,每个窗口的输出只有一个浮点数。输入的最小值为1,最大值为61,所以我可以从61开始预测。我只是使用了一批所有输入,形状为[58,4,1],输出形状为[58,1]。为了更好的可视化,输入和输出已在下方列出。

        Inputs                     Labels[[[ 1],[ 2],[ 3],[ 4]], -------> [[0.0493], [[ 2],[ 3],[ 4],[ 5]], ------->  [0.0634], [[ 3],[ 4],[ 5],[ 6]], ------->  [0.0773], [[ 4],[ 5],[ 6],[ 7]], ------->  [0.0909],   ..   ..   ..   ..    ------->     ...  , [[55],[56],[57],[58]], ------->  [0.5503], [[56],[57],[58],[59]], ------->  [0.5567], [[57],[58],[59],[60]], ------->  [0.5630], [[58],[59],[60],[61]]] ------->  [0.5693]]

训练部分进行得很顺利,我在500个epoch后达到了大约0.991的准确率,但当我尝试从61预测到118时,所有的预测值都有一个固定的步长下降,但不知何故表现出正确的行为。

由于这个项目的目的是为了学习基础知识,我决定使用TensorFlow中最简单的函数,因此没有使用seq2seq设施。RNN的代码如下所示

def build_lstm(cell_lengh, cell_depth, batch_size, keep_prob):    def lstm_row(cell_length, keep_prob):        cell_row = tf.contrib.rnn.BasicLSTMCell(cell_lengh)        cell_row = tf.contrib.rnn.DropoutWrapper(cell_row, keep_prob)        return cell_row    cell = tf.contrib.rnn.MultiRNNCell([lstm_row(cell_lengh, keep_prob) for _ in range(cell_depth)])    initial_state = cell.zero_state(batch_size, tf.float32)    return cell, initial_statetf.reset_default_graph()inputs = tf.placeholder(tf.float32, [None, feature_length, 1], name='inputs')labels = tf.placeholder(tf.float32, [None, output_length], name='labels')keep_prob = tf.placeholder(tf.float32, name='kpprob')lstm_cell, initial_state = build_lstm(40, 2, batch_size=batch_size, keep_prob=keep_prob)lstm_output, final_state = tf.nn.dynamic_rnn(lstm_cell, inputs, initial_state=initial_state)lstm_outout_seq = lstm_output[:,-1,:]dense_0 = tf.layers.dense(inputs=lstm_outout_seq, units=120, activation=tf.nn.relu)dropout_0 = tf.layers.dropout(dense_0, rate=0.7)with tf.variable_scope('sigmoid'):    W = tf.Variable(tf.truncated_normal((120, 1), stddev=0.1), name='weights')    b = tf.Variable(tf.zeros(1), name='bias')logits = tf.matmul(dropout_0, W) + boutput = tf.nn.sigmoid(logits, name='output')loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=labels))correct_predictions = tf.abs(output - labels)total_correct = tf.ones_like(correct_predictions)accuracy = tf.reduce_mean(total_correct - correct_predictions)learning_rate = tf.placeholder(tf.float32, name='learning_rate')optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)l_rate = 0.001epochs = 500kp_prob = 0.7with tf.Session() as session:    session.run(tf.global_variables_initializer())    for e in range(epochs):        new_state = session.run([initial_state])        feeder = {            inputs: wnd_x,            labels: wnd_y_scl,            keep_prob: kp_prob,            learning_rate: l_rate,            initial_state: new_state        }        session_loss,        session_accuracy,        session_output, _,        last_state = session.run([loss, accuracy, output,                                  optimizer, final_state], feed_dict=feeder)        print('Epoch {0}/{1}:\t'.format(e, epochs),              'training loss {0}\t'.format(session_loss),              'accuracy {0}\t'.format(session_accuracy))    new_state = session.run([initial_state])    feeder = {        inputs: unseen_data_rsp,        keep_prob: 1.0,        initial_state: new_state    }    session_output = session.run([output], feed_dict=feeder)

如前所述,在推理阶段,预测值有固定的步长下降,但不知何故表现出正确的行为,即曲线的导数在时间步长上正确变化。

在训练阶段,我有以下输出:

Epoch 999/1000: training loss = 0.5913468599319458 | accuracy = 0.9909629225730896         Input               Label          Output[[ 1],[ 2],[ 3],[ 4]]  -->  [0.0493]  ...  [0.0591][[ 2],[ 3],[ 4],[ 5]]  -->  [0.0634]  ...  [0.0802][[ 3],[ 4],[ 5],[ 6]]  -->  [0.0773]  ...  [0.0777][[ 4],[ 5],[ 6],[ 7]]  -->  [0.0909]  ...  [0.1035]  ..   ..   ..   ..    ...     ...            ...[[55],[56],[57],[58]]  -->  [0.5503]  ...  [0.5609][[56],[57],[58],[59]]  -->  [0.5567]  ...  [0.5465][[57],[58],[59],[60]]  -->  [0.5630]  ...  [0.5543][[58],[59],[60],[61]]  -->  [0.5693]  ...  [0.5614]

在推理阶段,我有以下输出:

          Input                Prediction[[ 58],[ 59],[ 60],[ 61]]  -->  [0.4408][[ 59],[ 60],[ 61],[ 62]]  -->  [0.4459][[ 60],[ 61],[ 62],[ 63]]  -->  [0.4510][[ 61],[ 62],[ 63],[ 64]]  -->  [0.4559]  ...   ...   ...   ...    ...     ...[[112],[113],[114],[115]]  -->  [0.6089][[113],[114],[115],[116]]  -->  [0.6101][[114],[115],[116],[117]]  -->  [0.6113][[115],[116],[117],[118]]  -->  [0.6124]

如您所见,推理的第一个输入与训练的最后一个输入相同。我不理解的是为什么相同的输入会给我两个不同的输出,以及为什么这些输出有一个大约0.11的固定步长下降。感谢你们的任何帮助,很抱歉文本过长,如有需要我可以将其缩短。


回答:

在推理过程中,您重置了状态。因此,同样的输入在两种情况下得到不同的值是因为网络的状态不同。

要在预测后保持状态,您需要做类似以下的事情:

#对每个预测进行迭代 {  feeder = {    inputs: unseen_data_rsp,    keep_prob: 1.0,    initial_state: last_state  }  session_output, last_state = session.run([output,final_state], feed_dict=feeder)}

此外,要在推理的第一个输入上得到与训练结果完全相同的输出,您需要首先呈现所有训练示例,以确保您以正确的状态开始推理。另一种方法是保存网络的状态,然后在预测期间重用它。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注