有状态 RNN 中的时间反向传播

Backpropagation through time in stateful RNNs

如果我在 Keras 中使用有状态 RNN 来处理长度为 N 的序列,分为 N 个部分(每个时间步单独处理),

  1. 如何处理反向传播?它只影响最后一个时间步长,还是反向传播整个序列?
  2. 如果它不传播整个序列,有没有办法做到这一点?

关于 Keras 中的 RNN,您需要了解几件事。默认情况下,所有循环神经网络中的参数 return_sequences=False。这意味着在默认情况下,只有在处理完整个输入序列后 RNN 的激活才会作为输出返回。如果你想在每个时间步都有激活并分别优化每个时间步,你需要传递 return_sequences=True 作为参数 (https://keras.io/layers/recurrent/#recurrent).

接下来要知道的重要事情是有状态 RNN 所做的就是记住最后一次激活。因此,如果您有一个大输入序列并将其分解为较小的序列(我相信您正在这样做),则网络中的激活在处理第一个序列后会保留在网络中,因此在处理第一个序列时会影响网络中的激活第二序列。这与网络的优化方式无关,网络只是将输出与您给出的目标之间的差异最小化。

反向传播范围限于输入序列的第二维。即,如果您的数据是 (num_sequences, num_time_steps_per_seq, data_dim) 类型,则在价值 num_time_steps_per_seq 的时间范围内完成反向传播 看看

https://github.com/fchollet/keras/issues/3669

问题 1:如何处理反向传播?(因为 RNN 不仅像 basic_NN 那样垂直 fully-connected,而且还被认为是很深 - 在隐藏层中也有水平反向传播连接)

假设 batch_input_shape=(num_seq, 1, data_dim) - "Backprop 将被截断为 1 个时间步长,因为第二个维度是 1。不会执行梯度更新比第二维度的值更早。” - 参见 here

因此,如果 time_step >1 - 梯度将在 input_shape

的 second_dim 中分配的 time_step 中进一步更新
  • set return_sequences=True 为除最后一层之外的所有循环层(使用按需输出或进一步密集到所需输出)- - 需要 True 才能在 sliding_window 中从前一个到下一个的可传输序列滚动到 +1 -- 以便能够 backprop 根据已经估计的权重

  • return_state=True 用于获取返回的状态——LSTM 中的 2 个状态张量 [output, state_h, state_c = layers.LSTM(64, return_state=True, name="encoder")] 或 GRU [包括。 in shapes] -- “可以用在 encoder-decoder sequence-to-sequence 模型中,其中编码器最终状态用作解码器的初始状态。” ...

但请记住(对于任何情况):有状态训练不允许混洗,并且 time-consuming 与无状态训练相比

p.s.

如您所见 -- (c,h)tf( h,c) in keras -- h & c 都是元素输出,因此在批处理或multi-threaded训练

中都变得紧急