2016-12-05 25 views
3

我在张量流中建立了一个RNN,它采用一个可变序列并在序列的末尾进行1个预测。带有可变长度序列的Tensorflow RNN,填充零影响学习

我零填充我的数据,以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的最后一个输出,我不需要掩盖损失?
  • 有没有在我怎么想出来的红旗?

回答

3

您可以传入sequence_lengths的占位符,并且在输入序列中使用填充时它是必需的。一旦达到PAD符号,sequence_length参数就会通知RNN停止计算。

序列越长,需要处理的填充越多,以计算最终状态,降低信号(如果使用的是最后一个输出)。相反,确保你得到的'最后输出'符合你序列的长度。例如,如果你的序列长度为7,那么你想要的'最后输出'是输出[6]。

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

看到这个类似的问题:

variable-length rnn padding and mask out padding gradients

+0

如何进行模型的这种影响速度?会有更少的计算,但我想知道这是否会被一些棘手的索引和连接所抵消。 –

+0

它提高了模型的速度,因为计算较少,但我不确定程度。如果你的模型有500次的时间步长,并且大部分时间你的序列长度为20,这将是非常重要的。尽管如此,这是一个极端的例子。 – user2827214