首先抛出一个问题, 为什么Transformer 要有位置编码?

– 对于任何一门语言, 单词在句子中的位置和顺序都极为重要, 语序正确, 才能表达出正确含义

I do not like the story of the movie, but I do like the cast.
I do like the story of the movie, but I do not like the cast.

如上述两个句子, 仅是改变not位置, 表达的意思截然相反

Transformer抛弃了RNNCNN作为序列学习的基本模型, 我们知道, 循环神经网络本身就是一种顺序结构, 天然包含了词在序列中的位置信息, 当抛弃循环神经网络结构, 完全采用Attention取而代之, 这些词序信息就会丢失, 模型就没有办法直到每个词在句子中的相对位置和绝对位置, 因此, 有必要把词序信息加到词向量上帮助模型学习这些信息, 位置编码(Positional Encoding)就是用来解决这个问题的办法

一、什么是位置编码

transformerencoderdecoder中使用了Positional Encoding, 最终的输入就变为了:

input = word_embedding + positional_encoding

word_embedding : 词嵌入, 将token的维度从vocab_size映射到d_model(原论文中, d_model为512)

最终的输入通过词嵌入后的向量和位置编码矩阵相加得到, 所以positional_encoding也是d_model维度的向量

二、位置编码构造方法

2.1 用增长数值标记位置

  • 第一个token标记1, 第二个token标记2… 以此类推

这种方法存在一些问题:

  1. 模型可能遇见比训练时所用序列更长的序列, 不利于模型泛化
  2. 模型无法理解数字的含义, 可能认为大数字比小数字权重更高, 而非顺序更靠后
  3. 无法表达相对位置信息

2.2 用[0, 1]范围标记位置

为解决上述问题, 将数值限制在[0, 1]区间内, 对其等分切割, 假设有3个token, 则位置信息为[0, 0.5, 1]

这样产生的问题是, 序列长度不同, 相对距离也不同, 模型可能认为这是单词语义发生了变化

2.3 用二进制向量标记位置

由于位置信息最终会作用到word_embedding上, 比起用单一的数值, 更好的方式是使用和word_embedding同纬度的向量, 可以想到, 将数值转换成二进制形式

假设d_model = 3

d_model一般比较大(512, 1024…), 基本可以把每个token的位置都编码出来

但这样也存在问题, 不同单词间的位置变化不连续, 难以推测相对位置信息

2.4 用sin和cos函数交替标记位置

这是论文中提出的方法

三角函数有界且连续, 可以满足目前的需要

$$PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)$$

$$PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)$$

参数说明:

符号 含义
pos 当前位置(position index)
i 维度索引(dimension index)
d_model 模型维度(embedding size,例如512)
PE 位置编码矩阵(shape: [seq_len, d_model]

这里只给出计算公式, 数学推导网上优秀文章较多, 不再演示

三. 为什么可以直接将词向量和位置编码进行相加

这是一直困扰我的点, 仅是进行张量相加就可以达到添加位置信息的作用吗? 难道这样不会破坏词向量本身信息吗?

网上浏览了一些博主的文章和视频, 但是答案也并没那么明确, 有点大力出奇迹的意思

3.1、公式复习

Transformer 的输入是:
$$
X = E_{\text{word}} + E_{\text{pos}}
$$
其中:

  • $E_{word}$:词向量(表示词语语义)
  • $E_{pos}$:位置编码(表示词语在句子中的位置)
  • 维度相同(例如都为 $d_{model}=512$)

3.2、为什么相加就能引入位置信息?

1. 向量加法在嵌入空间中表示“组合信息”

在向量空间中,加法表示叠加不同的语义因素

比如:

  • “king” ≈ “man” + “royalty”
  • “Paris” - “France” + “Italy” ≈ “Rome”

同理:

把词向量和位置向量相加,就相当于在语义中叠加“第几个词”的信息。

也就是说,新的向量同时携带了词义和位置两种特征


2. 相加不会“覆盖”信息,而是“偏移”语义空间

我们可以把每个词向量看成在一个高维语义空间中的点。
加上位置编码后,等价于把它 沿着“位置维度方向”平移了一点

$$\text{new_embedding = semantic_embedding + position_offset}$$

所以模型看到的不是“词义被破坏”,而是“相同词在不同位置处于略微不同的方向”。
这使得 Transformer 能区分:

“I love you”和“You love I” 的区别。


3. 注意力机制会自动学会利用这些位置差异

在自注意力计算中,Q、K 向量都会从输入中线性变换得到:

$$
Q = XW_Q, \quad K = XW_K
$$
因此,位置信息通过 $E_{pos}$ 影响了 Query-Key 相似度。

当两个词位置不同、位置编码不同,它们的注意力权重分布也不同 → 模型能够学习“前后关系”。


3.3、为什么不会破坏词向量原始信息?

1. 相加是线性可逆的(在一定程度上)

如果两个向量空间的分布相对独立,线性相加仍能被后续层(线性变换)分离:

$$
W(E_{word}+E_{pos})=WE_{word}+WE_{pos}
$$
Transformer 的多层线性结构可以在后续层中重新分辨“语义部分”和“位置信息部分”。


2. 位置编码的幅度较小,不会淹没词向量

在实现时,位置编码通常被归一化或初始化为较小值(例如在 [-1,1] 范围内)。
这样词向量的主导语义仍然保留,只是轻微偏移 → 注入位置信息。


3. 高维空间中的“信息容量”巨大

在 512 维或更高的空间中,向量叠加后不会导致严重的信息重叠。
就像 RGB 图像里混合红色和绿色还能区分出“黄色”一样,
词义与位置信息叠加后仍可被网络区分和提取。