标准位置编码
起源
由于原始的transformer模型不包含递归和卷积,为了使模型利用序列的顺序,原文在input embeddings 上加入了“位置编码”,位置编码的维度和input embeddings的维度 d m o d e l d_{model} dmodel一样大,所以两者可以相加。加入位置编码的位置如下图所示:
原理
使用不同频率的正弦和余弦函数:
其中 p o s pos pos是token在序列中的位置, i i i是维度,也就是说,位置编码的每一个维度对应于一个正弦波,波长从 2 π 2\pi 2π到 10000 10000 10000 × 2 π \times 2\pi ×2π形成几何级数。偶数用 s i n sin sin,单数用 c o s cos cos。
(下图展示位置编码的细节,来源在这)
证明:对于任何固定的偏移量 k k k, P E p o s + k PE_{pos+k} PEpos+k可以表示为 P E p o s PE_{pos} PEpos的线性函数。
P E ( p o s + k , 2 i ) = sin ( p o s + k 1000 0 2 i d ) = sin ( p o s 1000 0 2 i d + k 1000 0 2 i d ) PE(pos+k, 2i) = \sin\left(\frac{pos+k}{10000^{\frac{2i}{d}}}\right) = \sin\left(\frac{pos}{10000^{\frac{2i}{d}}} + \frac{k}{10000^{\frac{2i}{d}}}\right) PE(pos+k,2i)=sin(10000d2ipos+k)=sin(10000d2ipos+10000d2ik) P E ( p o s + k , 2 i + 1 ) = cos ( p o s + k 1000 0 2 i d ) = cos ( p o s 1000 0 2 i d + k 1000 0 2 i d ) PE(pos+k, 2i + 1) = \cos\left(\frac{pos+k}{10000^{\frac{2i}{d}}}\right) = \cos\left(\frac{pos}{10000^{\frac{2i}{d}}} + \frac{k}{10000^{\frac{2i}{d}}}\right) PE(pos+k,2i+1)=cos(10000d2ipos+k)=cos(10000d2ipos+10000d2ik)根据三角函数的和角公式:
sin ( a + b ) = sin a cos b + cos a sin b \sin(a + b) = \sin a \cos b + \cos a \sin b sin(a+b)=sinacosb+cosasinb cos ( a + b ) = cos a cos b − sin a sin b \cos(a + b) = \cos a \cos b - \sin a \sin b cos(a+b)=cosacosb−sinasinb因此可以得到:
P E ( p o s + k , 2 i ) = sin ( p o s 1000 0 2 i d ) cos ( k 1000 0 2 i d ) + cos ( p o s 1000 0 2 i d ) sin ( k 1000 0 2 i d ) PE(pos+k, 2i) = \sin\left(\frac{pos}{10000^{\frac{2i}{d}}}\right) \cos\left(\frac{k}{10000^{\frac{2i}{d}}}\right) + \cos\left(\frac{pos}{10000^{\frac{2i}{d}}}\right) \sin\left(\frac{k}{10000^{\frac{2i}{d}}}\right) PE(pos+k,2i)=sin(10000d2ipos)cos(10000d2ik)+cos(10000d2ipos)sin(10000d2ik)
P E ( p o s + k , 2 i + 1 ) = cos ( p o s 1000 0 2 i d ) cos ( k 1000 0 2 i d ) − sin ( p o s 1000 0 2 i d ) sin ( k 1000 0 2 i d ) PE(pos+k, 2i + 1) = \cos\left(\frac{pos}{10000^{\frac{2i}{d}}}\right) \cos\left(\frac{k}{10000^{\frac{2i}{d}}}\right) - \sin\left(\frac{pos}{10000^{\frac{2i}{d}}}\right) \sin\left(\frac{k}{10000^{\frac{2i}{d}}}\right) PE(pos+k,2i+1)=cos(10000d2ipos)cos(10000d2ik)−sin(10000d2ipos)sin(10000d2ik)线性函数的形式
可以看到 P E ( p o s + k , 2 i ) PE(pos+k, 2i) PE(pos+k,2i) 和 P E ( p o s + k , 2 i + 1 ) PE(pos+k, 2i + 1) PE(pos+k,2i+1) 的结果都是 P E ( p o s ) PE(pos) PE(pos) 和 sin ( k 1000 0 2 i d ) \sin\left(\frac{k}{10000^{\frac{2i}{d}}}\right) sin(10000d2ik) 或 cos ( k 1000 0 2 i d ) \cos\left(\frac{k}{10000^{\frac{2i}{d}}}\right) cos(10000d2ik) 的线性组合。由于 sin ( k 1000 0 2 i d ) \sin\left(\frac{k}{10000^{\frac{2i}{d}}}\right) sin(10000d2ik) 和 cos ( k 1000 0 2 i d ) \cos\left(\frac{k}{10000^{\frac{2i}{d}}}\right) cos(10000d2ik) 是固定值,所以我们可以将它们视为常数,从而使得整个表达式变成了 P E ( p o s ) PE(pos) PE(pos) 的线性函数。
得出结论:
对于任何固定的偏移量 k k k,都有:
P E p o s + k = f ( P E p o s ) PE_{pos+k} = f(PE_{pos}) PEpos+k=f(PEpos)其中 f f f 是一个线性函数。这证明了在 Transformer 的位置编码中,相对位置 P E p o s + k PE_{pos+k} PEpos+k 可以表示为 P E p o s PE_{pos} PEpos 的线性函数。
计算 P E p o s + k 与 P E p o s PE_{pos+k} 与PE_{pos} PEpos+k与PEpos的内积
Dot ( P E p o s , P E p o s + k ) = ∑ i = 0 d / 2 − 1 P E ( p o s , 2 i ) ⋅ P E ( p o s + k , 2 i ) + P E ( p o s , 2 i + 1 ) ⋅ P E ( p o s + k , 2 i + 1 ) \text{Dot}(PE_{pos}, PE_{pos+k}) = \sum_{i=0}^{d/2-1} PE(pos, 2i) \cdot PE(pos+k, 2i) + PE(pos, 2i + 1) \cdot PE(pos+k, 2i + 1) Dot(PEpos,PEpos+k)=i=0∑d/2−1PE(pos,2i)⋅PE(pos+k,2i)+PE(pos,2i+1)⋅PE(pos+k,2i+1)
将内积展开为:
Dot ( P E p o s , P E p o s + k ) = ∑ i = 0 d / 2 − 1 [ sin ( p o s 1000 0 2 i d ) sin ( p o s + k 1000 0 2 i d ) + cos ( p o s 1000 0 2 i d ) cos ( p o s + k 1000 0 2 i d ) ] \text{Dot}(PE_{pos}, PE_{pos+k}) = \sum_{i=0}^{d/2-1} \left[ \sin\left(\frac{pos}{10000^{\frac{2i}{d}}}\right) \sin\left(\frac{pos+k}{10000^{\frac{2i}{d}}}\right) + \cos\left(\frac{pos}{10000^{\frac{2i}{d}}}\right) \cos\left(\frac{pos+k}{10000^{\frac{2i}{d}}}\right) \right] Dot(PEpos,PEpos+k)=i=0∑d/2−1[sin(10000d2ipos)sin(10000d2ipos+k)+cos(10000d2ipos)cos(10000d2ipos+k)]
根据 sin ( a ) sin ( b ) + cos ( a ) cos ( b ) = cos ( a − b ) \sin(a) \sin(b) + \cos(a) \cos(b) = \cos(a - b) sin(a)sin(b)+cos(a)cos(b)=cos(a−b)可得:
Dot ( P E p o s , P E p o s + k ) = ∑ i = 0 d / 2 − 1 cos ( p o s + k 1000 0 2 i d − p o s 1000 0 2 i d ) = ∑ i = 0 d / 2 − 1 cos ( k 1000 0 2 i d ) \text{Dot}(PE_{pos}, PE_{pos+k}) = \sum_{i=0}^{d/2-1} \cos\left(\frac{pos+k}{10000^{\frac{2i}{d}}} - \frac{pos}{10000^{\frac{2i}{d}}}\right)= \sum_{i=0}^{d/2-1} \cos\left(\frac{k}{10000^{\frac{2i}{d}}}\right) Dot(PEpos,PEpos+k)=i=0∑d/2−1cos(10000d2ipos+k−10000d2ipos)=i=0∑d/2−1cos(10000d2ik)
结论
- 当 k k k 较小时,内积值较大,表示 P E p o s + k PE_{pos+k} PEpos+k 和 P E p o s PE_{pos} PEpos 的相似度较高,相对位置较近。
- 当 k k k 较大时,内积值减小,表示相似度降低,相对位置较远。
- c o s ( k ) = c o s ( − k ) cos(k)=cos(-k) cos(k)=cos(−k),因此该方法无法区别方向。
通俗理解
参考文章
最简单直观的加入位置信息的方式就是使用1,2,3,4,…直接对句子进行位置编码(one-hot)。用二进制转化举个例子:
上表中维度0,维度1,维度2,维度3拼成的数字就是该位置对应的二进制表示。可以看到每个维度(每一列)其实都是有周期的,并且周期是不同的。具体来说,每个比特位的变化率都是不一样的,越低位的变化越快(越往右边走,变化频率越快),红色位置0和1每个数字会变化一次,而黄色位,每8个数字才会变化一次。这样就能够说明使用多个周期不同的周期函数组成的多维度编码和递增序列编码其实是可以等价的。这也回答了为什么周期函数能够引入位置信息。
同样的道理,不同频率的sin正弦函数和cos余弦函数组合,通过调整三角函数的频率,可以实现这种低位到高位的变化,这样就能把位置信息表示出来。
缺点
- 位置编码是固定的,无法根据具体任务进行调整。
- 固定的位置编码对序列长度有限制。在处理长序列时,正弦和余弦函数的频率可能不足以捕捉所有的位置信息,导致信息丢失。
- 位置编码在训练阶段是静态的。这意味着在训练时确定的位置编码不适用于后续推理时的输入,尤其是推理序列长度大于训练序列长度。