具有可变长度序列的Tensorflow RNN,填充零会影响学习

时间:2016-12-05 03:57:42

标签: python tensorflow

我在tensorflow中设置了一个带有变量序列的RNN,并在序列的末尾进行了1次预测。

我将数据填零为最多500个序列,但批量中的许多序列将少于500个。

我使用dynamic_rnn并将批处理中每个样本的序列长度传递给它:

# Get lstm cell output
m.outputs, m.states = tf.nn.dynamic_rnn(
    cell=lstm_cell,
    dtype=tf.float32,
    sequence_length=m.X_lengths,
    inputs=m.X)

其中m.X_lengths是作为张量的序列长度,它被设置为占位符变量。我将其传递给feed_dict

对于成本函数,它是sigmoid交叉熵(多类分类),我从m.outputs获取最后一个值,并用tf.reduce_mean处理它。

值得注意的是,我没有对损失函数进行任何掩蔽。我的理解是,只有当我试图使用所有输出中所有损失的总和时才需要屏蔽。但我只使用最后一个输出。

现在我已经在我的序列中添加了1000个填充零,但是如果仍然只有500,那么大序列长度,但批处理有1500个序列长度。如果填充没有效果,这将学习与没有额外填充相同的情况。当我用这种额外的填充学习训练模型时,学习会受到负面影响。将序列长度限制为100也可以改善结果。

问题:

  • 我可以传递sequence_lengths的占位符变量吗?
  • 如果我只使用dynamic_nn的最后一项输出,我是否理解我不需要掩盖损失?
  • 我是怎么想到的?

1 个答案:

答案 0 :(得分:4)

您可以传入sequence_lengths的占位符,并且在输入序列中使用填充时是必需的。 sequence_length参数告诉RNN在达到PAD符号后停止计算。

序列越长,计算最终状态必须处理的填充越多,信号降级(如果使用的是最后一个输出)。相反,请确保您获得的“最后输出”与序列的长度相对应。例如,如果您的序列长度为7,那么您想要的“最后输出”是输出[6]。

如果对sequence_rnn()使用序列长度参数,您将看到输出[6]之后的所有输出都只是零向量。

看到这个类似的问题:

variable-length rnn padding and mask out padding gradients