为什么 Transformer 模型位置编码选择三角函数?
在 Positional Encoding 系列中,我们搞清楚了正余弦公式"怎么用"——它通过不同频率的波形,给每个词打上了独一无二的"位置指纹"。但知其然,更要知其所以然。Transformer 论文发布后,无数研究者都在问同一个问题:为什么偏偏是正弦和余弦? 为什么不用别的函数?
答案是——这背后藏着一个非常优雅的数学秘密。今天,我们就来亲手揭开它。
为什么偏偏选正余弦?· 建立推导起点
在这期深度解析中,我们将集中火力回答三个连环问题:
第一:为什么选正余弦?它到底有什么不可替代的特性?
第二:为什么不同维度的频率要不一样?
第三,也是最硬核的一个:位置编码和词向量是"逐位相加"的,两种信息混在一起,真的不会互相干扰吗?
今天,我们先死磕第一个问题。为了看清本质,我们需要做一件事——化繁为简。
真实的模型里,每个词的位置编码有 512 维,看着头晕。所以我们的第一步,是把视线聚焦到其中的一对维度上。
根据公式设计,维度是两两配对的:偶数位用正弦,奇数位用余弦。
我们就单独拎出这一对来看。对于一个特定的位置,它的编码其实就是一个简单的二维向量——上面是正弦值,下面是余弦值。
为了书写方便,我们把公式分母那一长串东西,统称为频率常数,用希腊字母欧米伽表示。你可以把它理解为这一对维度的"旋转速度"。
于是,位置的二维编码向量就可以写成画面上这个非常干净的形式。这就是我们整个推导的起点。现在,关键问题来了——假设我知道了某个位置的编码,我想知道往后偏移几个位置的新编码。我能不能不重新算,而是直接用旧编码经过某种"变换"来得到它?如果能,这个"变换"长什么样?带着这个疑问,进入推导环节。
三角函数展开推导 · 拨开云雾
我们的目标很明确——把偏移后的新编码展开,看看能不能用原来那个位置的编码来表示它。
怎么展开?答案就四个字:召唤高中记忆。没错,接下来你要看到的,是你在高中刷题时写过无数遍的三角函数和角公式。画面上就是那两行,第一行全是加号,第二行中间是个减号。别小看这个减号,它后面会发挥巨大作用。
现在,我们做一个简单的等量代换。让公式里的角度 A 等于当前位置的相位,角度 B 等于偏移量的相位。完美套入。好了,见证奇迹的时刻。我们分两行来展开。
先看第一行的正弦项。
直接套公式,把它拆开。注意看画面上的颜色——红色的项永远绑着原始位置,蓝色的项永远绑着偏移量。这一行的展开非常顺利,没有任何意外。
再看第二行的余弦项。同样套公式拆开,红色依然绑着原始位置,蓝色依然绑着偏移量。唯一的变化,就是中间变成了减号。到这里,展开完成了。但这只是表象,真正的魔法藏在整体的结构里。现在,请把目光聚焦在等号的右边。
发现了吗?等号右边,已经没有"偏移后的新角度"了!
所有的项,全都是原始位置的正弦和余弦的线性组合。而那些乘在旁边的系数,只跟偏移量有关,跟原始位置毫无关系!
这意味着什么?这意味着,新位置的编码,完全可以由旧位置的编码,乘以一个固定的矩阵变换而来!这个矩阵长什么样?当你把这两行结果重新塞回一个方阵里,你会看到一个令人起鸡皮疙瘩的事实
写成线性变换 · 旋转矩阵现身
上一步,我们把偏移后的编码展开了。等号右边变成了一堆正弦和余弦的线性组合。
但这还不够震撼。现在,我们要做一件更酷的事——把这些散落的项,重新组装成一个矩阵。
回顾一下上一步的结果。注意看画面的颜色:红色永远代表原始位置的相位,蓝色永远代表偏移量的相位。
如果我们把红色的项提出来作为"变量",把蓝色的项提取出来作为"系数"……
一个绝妙的结构浮现了!
把第一行的系数放在矩阵的第一行,第二行的系数放在矩阵的第二行,等号左边的向量放在左边,原始位置的向量放在右边。画面上出现了完整的矩阵乘法等式。请把你的目光锁定在中间那个方阵上。
左上角和右下角,是偏移量的余弦值;
右上角是正弦值;
左下角是负的正弦值。
如果你学过线性代数,这个结构绝对会让你虎躯一震——这赫然就是一个标准的二维旋转矩阵!
也就是说,刚才那长篇大论的三角函数展开,千言万语汇成一句话:新位置的编码,等于一个旋转矩阵,乘以旧位置的编码。整个位置编码的位移逻辑,从一坨复杂的三角函数,瞬间坍缩成了一个极其优雅的线性代数表达式。
更关键的是,请注意这个旋转矩阵的内部——它里面只有偏移量 k,完全没有绝对位置 pos 的影子。
这意味着什么?
意味着不管你是在句子的开头还是结尾,不管 pos 是 0 还是 10000,只要两个词相隔的距离 k 相同,它们位置编码之间的变换矩阵就完全一样。这就是正余弦方案最核心的魅力——天然具备相对位置感知能力。
旋转矩阵的三个核心结论
光看矩阵不够过瘾,我们把它画出来。
在左边这个二维坐标系里,我们画了一个单位圆。
这根蓝色的箭头,代表位置 pos 的编码向量。它与横轴的夹角,就是当前位置的相位。
现在,我们要走到 pos+k 的位置。看——向量转动了。
这根金色的箭头,就是新位置的编码。从蓝色到金色,中间扫过的这个夹角,就是偏移量 k 对应的相位。注意看画面上的提示:这个旋转的角度,只跟距离 k 有关。不管蓝色箭头一开始指向哪里,只要你让它转同样的角度,它感受到的"力"是完全一样的。
直观感受有了,基于这个旋转本质,我们能得出三个极其重要的结论。
第一,线性稳定性。
刚才说了,变换矩阵只跟相对距离 k 有关。这在深度学习里是个巨大的优势——模型在学习的时候,不需要去记住"第 0 个位置长什么样、第 100 个位置长什么样",它只需要学会一种通用的变换规则:"只要是往后偏移 k 个位置,就按固定角度转一下"。这极大地降低了模型的记忆负担。
第二,旋转的物理本质。
在所有几何变换里,旋转有一种独一无二的特质——它不拉伸、不压缩,只改变方向。
用数学语言说,它的行列式等于 1,它是正交矩阵。翻译成大白话就是:不管你怎么转,向量的长度永远不会变。
这意味着什么?意味着位置编码在参与后续计算时,不会因为变换而放大或衰减,信息的能量被完美守恒了。
第三,也是最实际的一点——它让模型更好学了。
Transformer 内部全是矩阵乘法。如果位置编码是某种复杂的非线性变换,模型很难用简单的线性层去捕捉它。但如果是旋转呢?
旋转本质上就是在捕捉向量之间的夹角关系。对于神经网络来说,学会"看夹角"比学会"猜复杂的非线性曲线"要容易得多。正余弦方案等于是在告诉模型:"别瞎猜了,我已经把位置关系变成了最简单的旋转,你直接学就好了。"
最后,让我们用三句话为"为什么选正余弦"画上句号。
第一,正余弦函数把干瘪的"排队顺序",升华成了高维空间里优美的"向量旋转角度"。
第二,旋转矩阵只由相对距离决定,天然具备全局一致的相对位置感知能力。
第三,这种纯粹的线性变换结构,让 Transformer 的学习过程更稳定、更高效。
这就是 Transformer 论文作者选择正余弦的底层逻辑——不是为了炫技,而是为了在数学上找到最干净、最利于模型学习的表达方式。
到这里,第一个问题彻底讲透了。但别忘了,我们还有第二个问题:为什么不同维度的频率要不一样?那些从极低频到极高频的波形,到底是怎么分工的?答案藏在一个极其巧妙的"二进制时钟"模拟里。我们下期见。
更多transformer,VIT,swin tranformer 参考头条号:人工智能研究所 v号:人工智能研究Suo, 启示AI科技动画详解transformer 在线视频教程
