Transformer 模型:为什么在添加位置编码之前要对词嵌入进行缩放?

数据挖掘 张量流 nlp 变压器 注意机制
2021-09-21 10:21:36

查看 Transformer 模型的 Tensorflow 教程时,我意识到他们的编码器层(和解码器)的实现在添加位置编码之前通过嵌入维度的 sqrt 来缩放词嵌入。请注意,这与缩放点积注意力不同。

我在这里指的是 Encoder 类的调用方法的第 3 行:https ://www.tensorflow.org/tutorials/text/transformer#encoder

def call(self, x, training, mask):

  seq_len = tf.shape(x)[1]
  
  # adding embedding and position encoding.
  x = self.embedding(x) # (batch_size, input_seq_len, d_model)
  x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))
  x += self.pos_encoding[:, :seq_len, :]
  
  x = self.dropout(x, training=training)

  for i in range(self.num_layers):
    x = self.enc_layers[i](x, training, mask)

  return x # (batch_size, input_seq_len, d_model)

到目前为止,我在阅读的论文中找不到任何关于这种缩放的提及。人们总是将编码器的输入显示为 WE + PE,即词嵌入加位置编码。但是这个实现似乎使用了 sqrt(d_model) * WE + PE。

我的问题:

  1. 你见过论文中提到的这个额外的缩放步骤吗?我没有在“Attention is all you need”(Vaswani 等人)中找到它。
  2. 这种额外的缩放试图实现什么?
2个回答

这在原始的 Transformer 论文中指定,在第 3.4 节的末尾:

在此处输入图像描述

转录:

3.4 嵌入和 Softmax

与其他序列转导模型类似,我们使用学习嵌入将输入标记和输出标记转换为维度为 𝑑模型的向量。我们还使用通常的学习线性变换和 softmax 函数将解码器输出转换为预测的下一个令牌概率。在我们的模型中,我们在两个嵌入层和 pre-softmax 线性变换之间共享相同的权重矩阵,类似于 [24]。在嵌入层中,我们将这些权重乘以 √𝑑模型

作者在论文或其他任何地方都没有证明这一点是合理的。谷歌在最初的实施中特别提出了这个问题,但没有任何回应。

Transformer 的其他实现也想知道这是否真的需要(参见thisthisthis)。

一些假设的论点(来源)是:

  • 它用于解码器嵌入和解码器 pre-softmax 线性权重之间的共享权重。
  • 实际上并不需要它。
  • 就是让位置编码相对更小。这意味着当我们将它们相加时,嵌入向量中的原始含义不会丢失。

作为参考,还有其他讨论此问题的 StackExchange 问题(请参阅thisthis)。

谢谢!!我在我的(fairseq 转换器)代码研究中也错过了乘法,它有助于澄清我注意到的一个谜:(正弦,非学习)位置嵌入的初始化范围为 -1.0 到 +1.0 ,但词嵌入的初始化平均值为 0.0,sd 为embedding_dim ** -0.5(512 为 0.044,1024 为 0.03125)。

因此,从表面上看,位置嵌入会压倒来自单词嵌入的任何信号。

但现在我可以看到词嵌入按比例缩放math.sqrt(embed_dim)(512 为 22.6,1024 为 32),这又有意义了。

按照另一个答案中的链接,似乎是这样做的,因为可以在变压器模型的其他部分使用相同的嵌入,这决定了初始化值。