直接训练 Transformer Encoder 层以及填充序列的正确方法

Training an Transformer Encoder layer directly and the proper way to pad sequences

我正在研究一个问题,我想直接训练 Transformer Encoder Layer(即没有嵌入层)。我已经有了将作为我的数据集处理的嵌入序列。我对如何处理 padding 和 attention mask 感到困惑,只是想确保我的理解是正确的。

我的序列长度从 3 到 130 不等。这是否意味着我应该填充所有序列以具有 130 个部分?如果是这样,我填充哪个值有关系吗?

对于注意力掩码,我相信我希望每个部分都关注序列中的所有其他部分。在 docs 中,我看到他们将其设置为只允许每个部分参与序列中较早的部分。这是最自然的方法还是仅用于语言建模任务?另外,为什么(在同一个 link 中)他们使用 -Inf 和 0 作为注意力掩码的值,而不是简单的 1 和 0?

作为一个小玩具示例,假设我的数据集中有两个样本,序列长度分别为 2 和 3(又名 3 是最大值):

s_1 = torch.Tensor([0.001, 0.002, ..., 0.768], [0.001, 0.002, ..., 0.768]) # length 2
s_2 = torch.Tensor([0.001, 0.002, ..., 0.768], [0.001, 0.002, ..., 0.768], [0.001, 0.002, ..., 0.768]) # length 3

这是否意味着我应该填充 s_1 使其长度为 3?并做类似的事情:

s_1 = torch.Tensor([0.001, 0.002, ..., 0.768], [0.001, 0.002, ..., 0.768], [0, 0, ..., 0])

然后我的注意力面具看起来像:

attn_mask_s1 = [[0    -Inf    0],
                [-Inf   0     0],
                [0      0     0]]


attn_mask_s2 = [[0     -Inf   -Inf],
                [-Inf   0     -Inf],
                [-Inf  -Inf    0  ]]

很抱歉将这么多问题打包成一个问题,但它们都打破了我对如何将数据传递到 TransformerEncoder 块的疑虑。

我的序列长度从 3 到 130 不等。这是否意味着我应该填充所有序列以具有 130 个部分?

不需要...transformer 的主要 属性 是序列长度是可变的(如果你看点积或多头注意力公式你可以看到)所以不需要填充。

对于注意力掩码,我相信我希望每个部分都关注序列中的所有其他部分。在文档中,我看到他们将其设置为只允许每个部分处理序列中较早的部分。这是最自然的方法还是仅适用于语言建模任务?

注意掩码用于学习顺序生成。您可以假设转换器就像一个 RNN,并且将一次生成一个标记的顺序数据。这就是在 Transformer 解码器中使用掩码的原因。如果这不适用于您的问题,您可以跳过它。

掩码是 -inf 还是 1 取决于您在点积注意力中应用它的位置。