Machine learning 具有固定步长输出误差的TensorFlow RNN模型

Machine learning 具有固定步长输出误差的TensorFlow RNN模型,machine-learning,tensorflow,deep-learning,lstm,rnn,Machine Learning,Tensorflow,Deep Learning,Lstm,Rnn,我启动了一个非常简单的RNN项目来巩固我在TF方面的知识,基本上是一个使用LSTM和TF的简单序列生成器。该项目只是一个多对一序列生成,输入是一个4整数窗口,输出每个窗口只有一个浮点。输入的最小数目是1,最大数目是61,所以我可以从61向前预测。我刚刚使用了一批所有的输入,其中有shape[58,4,1],输出有shape[58,1]。为了更好地可视化,输入和输出写在下面 Inputs Labels [[[ 1],[ 2],[ 3],[ 4

我启动了一个非常简单的RNN项目来巩固我在TF方面的知识,基本上是一个使用LSTM和TF的简单序列生成器。该项目只是一个多对一序列生成,输入是一个4整数窗口,输出每个窗口只有一个浮点。输入的最小数目是1,最大数目是61,所以我可以从61向前预测。我刚刚使用了一批所有的输入,其中有shape[58,4,1],输出有shape[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个历元获得大约0.991的准确度,但是当我尝试预测从61到118的一些值时,所有预测值的输出都有一个固定的降阶,但不知怎的,它的行为是正确的

因为这个项目的目的只是为了学习基础知识,所以我决定在TF中使用最简单的函数,所以
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_state

tf.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) + b

output = 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.001
epochs = 500
kp_prob = 0.7

with 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]
在推理阶段,我有以下输出:

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。谢谢你们的帮助,很抱歉文字太长,我可以根据要求缩短

在推断过程中,您正在重置状态。所以在同一个输入上会得到两个不同的值,因为在这两种情况下网络的状态是不同的

要在预测后保持状态,您需要执行以下操作:

#iterate for each prediction {
  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)
}

此外,为了准确地获得第一次输入推理的训练结果,您需要首先展示所有训练示例,以确保以正确的状态开始推理。另一种方法是保存网络的状态,然后在预测过程中重用该状态。

在推断过程中,重置状态。所以在同一个输入上会得到两个不同的值,因为在这两种情况下网络的状态是不同的

要在预测后保持状态,您需要执行以下操作:

#iterate for each prediction {
  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)
}

此外,为了准确地获得第一次输入推理的训练结果,您需要首先展示所有训练示例,以确保以正确的状态开始推理。另一种方法是保存网络状态,然后在预测过程中可以重用。

效果非常好,非常感谢!我还试验了许多不同的输入:正常、缩放和一个热输入,所有这些输入都有和没有时间。很明显,只有缩放版才能正常工作。非常感谢!我还试验了许多不同的输入:正常、缩放和一个热输入,所有这些输入都有和没有时间。显然,只有缩放版本才能正常工作。