Python 为什么在变压器模型中嵌入向量乘以常数?

Python 为什么在变压器模型中嵌入向量乘以常数?,python,tensorflow,deep-learning,attention-model,Python,Tensorflow,Deep Learning,Attention Model,我正在学习应用tensorflow官方文件中提出的变换模型 正如该节所说: 由于该模型不包含任何递归或卷积, 添加位置编码是为了向模型提供有关的一些信息 单词在句子中的相对位置 将位置编码向量添加到嵌入向量 我的理解是将位置编码向量直接添加到嵌入向量。但是当我查看代码时,我发现嵌入向量乘以一个常数 第节中的代码如下所示: class Encoder(tf.keras.layers.Layer): def __init__(self, num_layers, d_model, num_head

我正在学习应用tensorflow官方文件中提出的变换模型

正如该节所说:

由于该模型不包含任何递归或卷积, 添加位置编码是为了向模型提供有关的一些信息 单词在句子中的相对位置

将位置编码向量添加到嵌入向量

我的理解是将
位置编码向量
直接添加到
嵌入向量
。但是当我查看代码时,我发现
嵌入向量
乘以一个常数

第节中的代码如下所示:

class Encoder(tf.keras.layers.Layer):
  def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, 
               rate=0.1):
    super(Encoder, self).__init__()

    self.d_model = d_model
    self.num_layers = num_layers

    self.embedding = tf.keras.layers.Embedding(input_vocab_size, d_model)
    self.pos_encoding = positional_encoding(input_vocab_size, self.d_model)


    self.enc_layers = [EncoderLayer(d_model, num_heads, dff, rate) 
                       for _ in range(num_layers)]

    self.dropout = tf.keras.layers.Dropout(rate)

  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)
我们可以在
x+=self.pos\u编码[:,:seq\u len,:]之前看到
x*=tf.math.sqrt(tf.cast(self.d\u model,tf.float32))


那么,为什么在变压器模型中添加位置编码之前,嵌入向量要乘以一个常数呢?

我认为这种缩放的原因与应用于注意层的缩放无关。这可能是因为变压器共享嵌入层和输出softmax的权重。用于嵌入的比例与用于完全连接层的比例不同


transformer的一些实现使用这种缩放,即使它们实际上没有在输出层共享嵌入权重,但这可能是为了保持一致性(或错误)。只要确保嵌入的初始化是一致的。

我相信这种缩放的原因与应用于注意层的缩放无关。这可能是因为变压器共享嵌入层和输出softmax的权重。用于嵌入的比例与用于完全连接层的比例不同


transformer的一些实现使用这种缩放,即使它们实际上没有在输出层共享嵌入权重,但这可能是为了保持一致性(或错误)。只要确保嵌入的初始化是一致的。

环顾四周,我发现以下参数:

我们在添加之前增加嵌入值的原因是 使位置编码相对较小。这意味着 当我们添加时,嵌入向量中的原始含义不会丢失 他们在一起


环顾四周,我发现了这个论点:

我们在添加之前增加嵌入值的原因是 使位置编码相对较小。这意味着 当我们添加时,嵌入向量中的原始含义不会丢失 他们在一起


这看起来确实很奇怪,因为如果它是
/=
指的是paper@bluesummers规范化因子已在文档中实现,但不在此处。规范化因子是
自我注意的一部分
应该在添加
嵌入向量
位置编码
之后,所以我无法理解
嵌入向量
乘以常数。我得到了,再次修改它,它看起来确实像一个mistake@bluesummers我发现tensorflow的官方代码也使用这种计算方法。通过隐藏大小的sqrt对is
#规模嵌入的描述
@giser\u yugang我在这里找到了一个可能的解释。请参考看起来确实很奇怪,因为如果它是
/=
,指的是paper@bluesummers规范化因子已在文档中实现,但不在此处。规范化因子是
自我注意的一部分
应该在添加
嵌入向量
位置编码
之后,所以我无法理解
嵌入向量
乘以常数。我得到了,再次修改它,它看起来确实像一个mistake@bluesummers我发现tensorflow的官方代码也使用这种计算方法。通过隐藏大小的sqrt对is
#规模嵌入的描述
@giser\u yugang我在这里找到了一个可能的解释。请参考有趣的。。。因为我在谷歌搜索答案时偶然发现了这个问题——我如何确保位置嵌入(在我的模型中是一个相对较弱的信号)不会与实际的输入数据嵌入严重混淆。我们正在考虑减少位置的维数等,但用标量乘法放大I/p数据嵌入似乎是更好的选择。这似乎合乎逻辑。但这就是原因吗?下面的cfb似乎认为另一个有趣的地方。。。因为我在谷歌搜索答案时偶然发现了这个问题——我如何确保位置嵌入(在我的模型中是一个相对较弱的信号)不会与实际的输入数据嵌入严重混淆。我们正在考虑减少位置的维数等,但用标量乘法放大I/p数据嵌入似乎是更好的选择。这似乎合乎逻辑。但这就是原因吗?下面的cfb似乎不这么认为