如何在编码器解码器模型训练期间填充序列
How to pad sequences during training for an encoder decoder model
我有一个用于字符级英语拼写校正的编码器-解码器模型,它是非常基本的东西,有两个 LSTM 编码器和另一个 LSTM 解码器。
然而,到目前为止,我一直在预填充编码器输入序列,如下所示:
abc -> -abc
defg -> defg
ad -> --ad
接下来我将数据分成几组具有相同的解码器输入长度,例如
train_data = {'15': [...], '16': [...], ...}
其中关键是解码器输入数据的长度,我一直在为循环中的每个长度训练一次模型。
但是,必须有更好的方法来做到这一点,例如在 EOS 字符之后或 SOS 字符之前填充等。但是如果是这种情况,我将如何更改损失函数以使该填充不是' t计入亏损?
进行填充的标准方法是将其放在序列结束标记之后,但填充的位置应该很重要。
如何不将填充的头寸包括在损失中的技巧是在减少损失之前掩盖它们。假设 PAD_ID
变量包含用于填充的符号的索引:
def custom_loss(y_true, y_pred):
mask = 1 - K.cast(K.equal(y_true, PAD_ID), K.floatx())
loss = K.categorical_crossentropy(y_true, y_pred) * mask
return K.sum(loss) / K.sum(mask)
我有一个用于字符级英语拼写校正的编码器-解码器模型,它是非常基本的东西,有两个 LSTM 编码器和另一个 LSTM 解码器。
然而,到目前为止,我一直在预填充编码器输入序列,如下所示:
abc -> -abc
defg -> defg
ad -> --ad
接下来我将数据分成几组具有相同的解码器输入长度,例如
train_data = {'15': [...], '16': [...], ...}
其中关键是解码器输入数据的长度,我一直在为循环中的每个长度训练一次模型。
但是,必须有更好的方法来做到这一点,例如在 EOS 字符之后或 SOS 字符之前填充等。但是如果是这种情况,我将如何更改损失函数以使该填充不是' t计入亏损?
进行填充的标准方法是将其放在序列结束标记之后,但填充的位置应该很重要。
如何不将填充的头寸包括在损失中的技巧是在减少损失之前掩盖它们。假设 PAD_ID
变量包含用于填充的符号的索引:
def custom_loss(y_true, y_pred):
mask = 1 - K.cast(K.equal(y_true, PAD_ID), K.floatx())
loss = K.categorical_crossentropy(y_true, y_pred) * mask
return K.sum(loss) / K.sum(mask)