揭秘大模型:从原理到实战
上QQ阅读APP看书,第一时间看更新

2.3.2 Transformer输入表示

在Transformer模型中,每个单词的输入向量是由它的词嵌入向量和它的位置嵌入向量相加而成的,如图2-12所示。

图2-12 Transformer输入表示

词嵌入向量可以通过word2vec等模型预训练获取,同时也可以通过在Transformer中添加嵌入层获取。

在Transformer,不仅要对单词进行编码,还要对它们在句子中的位置进行编码。这是因为Transformer没有使用循环神经网络这样的循环结构,而是使用了全局的注意力机制(attention mechanism),导致无法直接捕捉单词之间的顺序关系;但是由于顺序关系对于自然语言处理任务是至关重要的,因此需要通过位置嵌入向量来保留单词在序列中的相对或绝对位置信息。

位置嵌入向量的维度要和词嵌入向量保持一致。有两种方法可以得到位置嵌入向量,一种是将其作为可学习的参数进行训练,另一种是根据预定义的公式直接计算。Transformer模型采用了第二种方法,其计算公式为

  (2-9)

其中,pos表示单词在句子中的位置,dmodel表示位置嵌入向量的维度。

代码清单2-2 生成词的位置嵌入向量

    def get_angles(pos, i, d_model):
        # i等价于式(2-9)中的2i和2i+1
        angle_rates = 1 / np.power(10000, (2*(i // 2))/ np.float32(d_model))
        return pos * angle_rates
    def positional_encoding(position, d_model):
        angle_rads = get_angles(np.arange(position)[:, np.newaxis],
                            np.arange(d_model)[np.newaxis,:], d_model)
        # 第2i项使用sin
        sines = np.sin(angle_rads[:, 0::2])
        # 第2i+1项使用cos
        cones = np.cos(angle_rads[:, 1::2])
        pos_encoding = np.concatenate([sines, cones], axis=-1)
        pos_encoding = pos_encoding[np.newaxis, ...]
        return tf.cast(pos_encoding, dtype=tf.float32)

上述代码中,函数positional_encoding()对应式(2-9)。下面的例子显示,输入当前位置为50,词嵌入维度为512,输出为位置嵌入向量形状。

代码清单2-3 查看词的位置嵌入向量形状示例

    pos_encoding = positional_encoding(50, 512)
    print(pos_encoding.shape)
    输出:(1, 50, 512)