直接训练 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 取决于您在点积注意力中应用它的位置。
我正在研究一个问题,我想直接训练 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 取决于您在点积注意力中应用它的位置。