我在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 回答
您可以传入sequence_lengths的占位符,并且在输入序列中使用填充时是必需的 . sequence_length参数告诉RNN在达到PAD符号后停止计算 .
序列越长,计算最终状态所需的填充越多,信号降级(如果使用的是最后一个输出) . 相反,请确保您获得的“最后输出”与序列的长度相对应 . 例如,如果您的序列长度为7,那么您想要的“最后输出”是输出[6] .
如果对sequence_rnn()使用序列长度参数,您将看到输出[6]之后的所有输出都只是零向量 .
看到这个类似的问题:
variable-length rnn padding and mask out padding gradients