11

我正在学习应用tensorflow 官方文档Transformer model for language understanding中Attention Is All You Need提出的Transform 模型。

正如位置编码部分所说:

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

位置编码向量被添加到嵌入向量中。

我的理解是positional encoding vector直接添加到embedding vector. 但是当我查看代码时,我发现embedding vector乘以一个常数。

编码器部分的代码如下:

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 *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))之前x += self.pos_encoding[:, :seq_len, :]

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

4

2 回答 2

12

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

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

于 2020-05-11T21:02:24.197 回答
3

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

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

于 2020-01-07T01:16:00.840 回答