我目前正在尝试实现变压器的 PyTorch 版本并且有一个问题。
我注意到许多实现不仅将掩码应用于解码器,还应用于编码器。Transformer 的官方 TensorFlow 教程还指出,Transformer 使用了一种叫做“MultiHead Attention (with padding masking)”的东西。
我很困惑,为什么将掩码应用于编码器序列中的填充?
我目前正在尝试实现变压器的 PyTorch 版本并且有一个问题。
我注意到许多实现不仅将掩码应用于解码器,还应用于编码器。Transformer 的官方 TensorFlow 教程还指出,Transformer 使用了一种叫做“MultiHead Attention (with padding masking)”的东西。
我很困惑,为什么将掩码应用于编码器序列中的填充?
我没有意识到这个问题没有答案。如果我要尝试回答我自己的问题,我们会对源数据应用掩码,因为在数据通过 Encoder 子层后,填充序列会有值。我们不需要也不希望模型关注这些填充序列,因此我们将它们屏蔽掉。
它与解码器中的掩码略有不同,因为解码器中的掩码需要额外的步骤,即具有“无峰值”机制,因此我们的模型无法查看未来的令牌。
掩码只是为了确保编码器不注意填充标记。这是掩码缩放点积注意力的公式:
Softmax 输出一个概率分布。通过将掩码向量
设置为接近负无穷大的值,其中我们有填充标记,否则为 1,我们确保不注意这些标记。
我认为这可能是由于我们不想计算填充的损失,并且填充位置的权重应该为
答案是:我们不希望注意力中的 softmax 受到序列填充部分的影响。
序列有不同的长度:
但是嵌入中的这些值会影响注意力的输出,因为softmax:例如,如果我们有vector = [2, 0.5, 0.8, 1, 0, 0, 0, 0](最后4个值是填充部分),softmax 输出将是 [0.41, 0.09, 0.12, 0.15, 0.06, 0.06, 0.06, 0.06],但是,我们知道最后四个元素没有实际价值,不应该影响输出。
因此,我们创建掩码并在 softmax 之前应用它,将填充值设置为 -inf 或类似 -1e9 的值。例如,替换后的前一个向量将如下所示: [2, 0.5, 0.8, 1, -1e9, -1e9, -1e9, -1e9] 这里是 softmax 输出: [0.53, 0.12, 0.16, 0.19, 0, 0 , 0, 0]