Tensorflow dynamic_rnn 参数含义

12

我很难理解那些晦涩的RNN文档。如果能帮我解决以下问题,将不胜感激。

tf.nn.dynamic_rnn(cell, inputs, sequence_length=None, initial_state=None, dtype=None, parallel_iterations=None, swap_memory=False, time_major=False, scope=None)

我很难理解这些参数与数学LSTM方程和RNN定义的关系。细胞展开大小在哪里?它是由输入的'max_time'维度定义的吗?批量大小只是将长数据分割为方便,还是与小批量SGD有关?输出状态是否跨批次传递?

1个回答

18

tf.nn.dynamic_rnn接收一个批次(使用小批量意义)的无关序列。

  • cell是您想要使用的实际单元格(LSTM,GRU等)
  • inputs的形状为batch_size x max_time x input_size,其中max_time是最长序列中的步骤数(但所有序列长度可以相同)
  • sequence_length是大小为batch_size的向量,其中每个元素给出批处理中每个序列的长度(如果所有序列的大小都相同,则将其保留为默认值。该参数定义了单元格展开大小。

隐藏状态处理

处理隐藏状态的常规方法是在dynamic_rnn之前定义一个初始状态张量,例如:

hidden_state_in = cell.zero_state(batch_size, tf.float32) 
output, hidden_state_out = tf.nn.dynamic_rnn(cell, 
                                             inputs,
                                             initial_state=hidden_state_in,
                                             ...)
在上面的代码片段中,hidden_state_inhidden_state_out的形状相同:[batch_size, ...]实际形状取决于所使用的单元类型,但重要的是第一个维度是批处理大小)。
这样,dynamic_rnn为每个序列都有一个初始隐藏状态。它会在每个时间步骤上自动传递输入参数inputs中每个序列的隐藏状态,并将hidden_state_out包含每个批次序列的最终输出状态。不会在同一批次序列之间传递隐藏状态,而只会在同一序列的时间步之间传递。

何时需要手动反馈隐藏状态?

通常,在训练时,每个批次都是无关的,因此在执行session.run(output)时不需要手动反馈隐藏状态。
然而,如果你在测试时需要每个时间步长的输出(即必须在每个时间步长上执行session.run()),则需要使用类似以下代码评估并反馈输出的隐藏状态:
output, hidden_state = sess.run([output, hidden_state_out],
                                feed_dict={hidden_state_in:hidden_state})
否则,TensorFlow将在每个时间步骤上仅使用默认的cell.zero_state(batch_size, tf.float32),这相当于在每个时间步骤重新初始化隐藏状态。

1
如果 batch_size = 1,这确实会发生。我们使用批量训练的原因是因为它使训练更加稳定。基于批次梯度平均值来更新权重比仅基于一个样本的梯度更新更有可能朝着正确的方向移动。 通常情况下,批处理大小大于1只在训练阶段有意义。 - Florentin Hennecker
感谢您的精彩解释。我有一个问题。如何显式控制变量batch_size的值或隐式推断它?有任何指导吗? - Kots
我不太确定你的意思,请您换个方式提问好吗? - Florentin Hennecker
这有点老了,但是你打算如何定义名为 hidden_state_in 的占位符的形状? - Kots
这是正确的,但tensorflow允许在feed_dict中传递张量对象。因此,请小心使用,因为dynamic_rnn的隐藏状态将是一个张量对象。 - abhi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接