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

我在张量流中设置了RNN,该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一起传递.

对于代价函数,它是S形交叉熵(多类分类),我从m.outputs中获取最后一个值,然后使用tf.reduce_mean对其进行处理.

值得注意的是,我没有对损失函数做任何掩饰.我的理解是,仅当我尝试使用所有输出的所有损失之和时,才需要屏蔽.但是我只使用最后的输出.

现在,我在序列上添加了1000个填充零,但是大序列的长度仍仅为500,但是批处理的序列长度为1500.如果填充无效,则将获得与没有其他填充相同的知识.当我使用附加填充训练模型时,会对学习产生负面影响.另外,将序列长度限制为100可以改善结果.

问题:

>是否可以为sequence_lengths传递占位符变量?
>如果我仅使用dynamic_nn的最后一个输出,就不需要掩盖损失,我是否理解正确?
>我对此有何危险警告?

最佳答案

您可以为sequence_lengths传递一个占位符,并且在输入序列中使用填充时很有必要.到达PAD符号后,sequence_length参数告诉RNN停止计算.

您的序列越长,为了计算最终状态,降低信号质量(如果使用的是最后一个输出),将需要处理更多的填充.相反,请确保获得的“最后输出”与序列的长度相对应.例如,如果您的序列长度为7,则您想要的“最后输出”为output [6].

如果确实对dynamic_rnn()使用了序列长度参数,则会看到output [6]之后的所有输出都是零向量.

看到类似的问题:

variable-length rnn padding and mask out padding gradients