原理
在之前的编码器 - 解码器介绍中,我们发现模型并没有记录时序相关信息,即没有感知不同词汇的位置顺序。这会导致一个问题,针对'我喜欢你'这句话,经过 Embedding 处理后,再进入编码器 - 解码器处理,最后生成的内容,是和输入'你喜欢我'最后生成的内容是一样的,但我们知道,这两句是含义完全不一样的语句。
加入位置编码,可以解决这个问题。位置编码通过给每个位置添加一个向量,这个向量包含了位置信息,然后把这个向量加到词汇向量上。
例如:
位置 1 向量:[0.1,0.2,0.3,...]
位置 2 向量:[0.4,0.5,0.6,...]
位置 3 向量:[0.7,0.8,0.9,...]
'我喜欢你',添加位置编码后:
'我'在位置 1:'我'的词向量 + 位置 1 向量
'喜欢'在位置 2:'喜欢'的词向量 + 位置 2 向量
'你'在位置 3:'你'的词向量 + 位置 3 向量
经过这样处理,Transformer 就可以区分词的位置了。
实现
在 Transformer 中,使用的是正弦位置编码。
正弦位置编码详解
- 参数
d_model: 8max_len: 10
- 位置索引
position: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
- 分母项
div_term: [1.0, 0.3162, 0.1, 0.0316]- 解释:
div_term = 10000^(-2i/d_model) i是维度索引(0, 2, 4, 6, ...),用于控制不同维度的频率
- 位置编码矩阵
- 形状:
torch.Size([10, 8]) - 数据:
位置 0: [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0] 位置 1: [0.8415, 0.5403, 0.3129, 0.9499, 0.0998, 0.9950, 0.0316, 0.9995] 位置 2: 位置 3: 位置 4: ...
- 形状:

