注意力与 Transformer
读懂一句话,靠的不是逐字死记,而是随时回头「看一眼」最相关的词。这一章我们拆解让机器学会这种眼神的机制——注意力,以及由它搭起来的 Transformer。
9.1 序列问题:顺序本身就是信息
上一章的图像是「一眼看全」的数据,但世界上还有另一类数据:序列。语言、语音、股价、基因——它们的含义藏在顺序里。「动物没有过马路,因为它太累了」这句话,把「累」换成「宽」,「它」指的对象就彻底变了。
在注意力出现之前,处理序列的主力是循环神经网络(RNN)。它的思路像一个逐字阅读的人:读每个字时,把「到目前为止的总结」压缩进一个记忆向量,带着它读下一个字。这个设计有两个绕不开的麻烦:一是长距离遗忘——句子一长,开头的内容在记忆向量里被反复冲刷,读到结尾时早已面目模糊;二是必须串行——第 100 个字必须等前 99 个读完,无法并行,训练慢得让人着急。
把一整句话压缩成一个固定长度的记忆向量,就像让你用一句话转述整本书——无论多努力,细节都会丢。我们需要的不是更好的记性,而是随时可以翻回去查的能力。
9.2 注意力 = 软查询
想象你带着一个问题走进图书馆。你不会把整馆的书从头到尾背下来,而是:拿你的问题去对每本书的索引,对得越准的书,翻开看得越仔细;对不上的,扫一眼就放下。
注意力机制把这件事拆成三个角色:
- Query(查询):你的问题——「我现在需要什么样的信息?」
- Key(索引):每本书的索引卡片——「我这本书是关于什么的?」
- Value(内容):书的正文——真正要被取走的信息。
每个 Query 和所有 Key 算一个匹配度,匹配度经过归一化变成一组和为 1 的比例,然后按这个比例把所有 Value 加权混合起来——匹配度越高的书,被「翻开」的比例越大。因为每本书都以某个比例被翻开(而不是只取一本),它被称为软查询:整个过程光滑可微,可以用第 5、6 章的梯度方法直接训练。
注意力就是「带着问题查资料」:Query 去碰 Key,碰出权重,再按权重把 Value 加权端走。
9.3 写成数学:缩放点积注意力
把直觉翻译成符号。Query 和 Key 的匹配度用点积衡量(第 1 章老朋友:两个向量越同向,点积越大),所有词一起算就是矩阵乘法 QKT;除以 √dk 缩放,过 softmax 变成和为 1 的权重,最后乘上 V:
Attention(Q, K, V) = softmax( QKT ⁄ √dk ) · V其中 dk 是 Key 向量的维度。为什么要除以 √dk?维度越高,点积的结果天然越大;分数一大,softmax 就会被推到接近 0 或 1 的饱和区——那里梯度几乎为 0,第 5 章的反传就「无梯可传」,网络学不动。除以 √dk 相当于把分数的尺度稳住,让 softmax 始终工作在灵敏的中段。
softmax 饱和的样子很像第 2 章 sigmoid 的两端:输入极端时输出几乎不动,导数趋近于零。深度学习中很多「莫名其妙的小设计」,都是在跟梯度消失搏斗。
公式的每一步都不需要代码就能亲手验证——本章末尾的「QKV 小算盘」演示会把它压缩到 3 个词、2 维向量的最小规模,让你逐个数值拨一遍。
9.4 自注意力:让词互相打量,顺便消歧
如果 Q、K、V 三个角色全部由同一句话里的词扮演,就叫自注意力(Self-Attention):每个词都拿自己的 Query 去问全句所有词(包括自己)「你和我有多相关」,然后把答案按相关度混合成自己的新表示。每个词的新表示里,都揉进了整句话的上下文。
这恰好是自然语言最需要的本领——消歧。代词「它」本身毫无意义,意思全靠上下文指派。下面两句只差一个字,「它」该看谁,答案完全不同:
演示 1 · 「它」指谁?
点击词语同一个「它」,上下文变了,注意力就变了——这就是消歧。试试切换句子,再看「累 / 宽」「因为」等词的注意力分布。
注意权重矩阵不是人工查表查出来的(这里是为了演示而预设的)。真实模型里,Q、K、V 都由词向量乘以可学习矩阵得到,这些矩阵在训练中自动学会「代词应该去匹配被指代的名词」这类规律。
光看别人算好的不过瘾。下面这个小算盘把 9.3 的公式压缩到最小规模:3 个词、每个向量只有 2 维,从点积到 softmax 再到加权求和,每一步的数值都摆在你面前。
演示 2 · QKV 小算盘
拖滑块第 1 步 · 匹配分数 = Q·K ⁄ √2
第 2 步 · softmax → 注意力权重(每行和为 1)
第 3 步 · 输出 = 权重 × V 的加权和
第 1 章的加权求和又回来了——只是这次权重本身也是算出来的。示例预设里,「它」的 Query 和「动物」的 Key 最对得上,所以「它」的输出里近七成来自「动物」的 Value。
9.5 多头:多双眼睛同时看
一句话里的关系不止一种:「它」和「动物」是指代关系,「过」和「马路」是动宾关系,「太」和「累」是程度修饰。让一组 Q、K、V 同时抓住所有关系,未免太强人所难。
多头注意力(Multi-Head Attention)的办法简单粗暴:复制好几套独立的 Q、K、V 投影矩阵,让每套(每个「头」)在自己的小维度空间里各算各的注意力,最后把各头的结果拼接起来。就像多双眼睛同时看同一句话——一双盯语法结构,一双盯指代,一双盯语义搭配,互不干扰。
还有一个容易忽略的细节:注意力本身只看「匹配不匹配」,完全不看顺序——把句子打乱,算出的权重一模一样。所以 Transformer 会给每个词向量额外注入一份位置编码,把「第几个位置」的信息写进向量里,否则「它追动物」和「动物追它」在模型眼里没有区别。
9.6 一块 Transformer 拼图
把零件装起来:词先变成嵌入向量并加上位置编码;进多头自注意力,让词与词交换信息;过一层前馈网络(就是第 3 章的多层感知机)做非线性变换;每个子层外面都包着残差连接和层归一化,让几十层堆叠也能稳定训练。这样的一「块」重复堆叠若干层,就是 Transformer 的本体。
回头看,这条路其实环环相扣:第 1 章的神经元学会了加权投票;第 2 章的激活函数给了它非线性的表达力;第 3 章把神经元叠成深层网络;第 4 章用损失函数定义「错多少」;第 5 章的反向传播算出每个权重的责任;第 6 章的梯度下降负责改进;第 7 章学会不过拟合,才算真正学会;第 8 章的卷积教会机器看图像;这一章的注意力教会机器读序列。从 z = w·x + b 到 softmax(QKT ⁄ √dk)·V,本质上都是同一件事:可微的加权求和,加上用梯度调出来的权重。恭喜你,已经走完了深度学习的核心主线!