跳到主要内容

注意力 — 可微分的数据库查询

这一章讲五件事: 注意力的确切定义(数据库类比); 打分函数为什么用「除以 √d 的点积」; Bahdanau 注意力怎么砸开 seq2seq 的瓶颈。

多头注意力就是多组打分并行、各学一种范围的依赖。

自注意力就是 Q/K/V 全部来自同一序列; 以及它丢掉的「顺序」怎么补回来(位置编码)。 读完这一章,Transformer 的全部零件你就都有了——第 13 章只是组装。

1. 顶层全景:一个查询,一堆键值对,一次加权平均

先看数据库。一张表:{(Zhang, Aston), (Li, Mu), (Smola, Alex), …}, 姓是键(key),名是值(value)。查询 q="Li",返回 "Mu"1。 这个日常操作里有三个深思的性质:

  • 查询的写法与库的大小无关——库有 6 条还是 600 万条,「查 Li」这句话不用变;
  • 同一个查询,库不同答案不同;
  • 不需要压缩数据库,多大都能查。

注意力机制就是把这件事做成可微分的2:

Attention(q, D) = Σᵢ α(q, kᵢ) · vᵢ

查询 q 与每个键 kᵢ 算一个匹配度 α(注意力权重),
拿权重对所有值 vᵢ 做加权平均,结果就是输出。

几个特例帮你定位它3:只有一个权重是 1、其余是 0 ——退化成传统数据库查询; 所有权重相等 ——退化成平均池化; 权重非负且和为 1(凸组合)——深度学习里的标准形态。 怎么保证非负和为 1?拿任意打分函数 a(q,k),过一遍 softmax 就行—— 可导、梯度不消失,这两个性质让它能直接进训练循环4

书里还有一段「史前史」值得知道:1964 年的 Nadaraya-Watson 核回归 (用高斯核之类的手工相似度,对新点附近的旧样本加权平均) 就是手工版的注意力——不用训练、数据多了还一致收敛5。 它的意义是反面的:手工打分是有极限的,更好的策略是把 「什么样的查询和键算匹配」也学出来——这就是后面一切的起点。

2. 打分函数:为什么是「除以 √d 的点积」

打分函数 a(q, k) 是注意力的引擎。两个主力:

缩放点击注意力(scaled dot-product):a(q,k) = qᵀk/√d。 来源有个干净的推导:高斯核 −½‖q−k‖² 展开是 qᵀk − ½‖k‖² − ½‖q‖²; 归一化会消掉只含 q 的项,层归一化(layer norm,把单个样本的所有特征拉成零均值、单位方差的做法,见第 09 章)下 ‖k‖² 近似常数——于是只剩点积。 但点积有个数值毛病:q、k 各分量独立、零均值、单位方差时, qᵀk 的方差等于维度 d——d 一大,点积巨大,softmax 被推到饱和区,梯度消失。 除以 √d 把方差拉回 1,与维度无关6

加性注意力(additive):a(q,k) = w_vᵀ·tanh(W_q q + W_k k)—— 查询和键维度不同时用,等价于「拼接后过一个单隐层小 MLP」。 这是 Bahdanau 当年用的打分。

两个工程件顺带记住7: masked softmax——批量里句子长短不一,补齐的占位符不该参与注意力, 做法是把占位处的打分设成 −10⁶,softmax 后权重≈0 (宁可浪费一点计算,也比写条件分支快——GPU 的形状); 批量矩阵乘(BMM)——整批查询、键、值一次算完: softmax(QKᵀ/√d)V。

3. Bahdanau 注意力:砸开定长瓶颈

回到第 11 章那堵墙:编码器-解码器里, 全部源句信息装在定长向量 c 里,它是编码器和解码器之间唯一的传话人。 句子一长就塞不下——作者说,seq2seq 把这个状态当成了 源句的「充分统计量」,短句合理,长句必死8

2014 年 Bahdanau 等人的解法: 解码器每生成一个词,就回头查一遍源句9:

解码到第 t' 步时:
query = 解码器上一步的隐状态 s_{t'-1}
keys/values = 编码器在所有时间步的隐状态 h_1,…,h_T
c_{t'} = Σ_t α(s_{t'-1}, h_t) · h_t ← 这一步专属的上下文

上下文向量 c 不再固定:每一步解码,都用自己的 query 重新从源句各位置「加权取阅」一次。 翻「它」的时候,权重自然聚到源句里对应的名词上—— 可视化注意力权重,能直接看到逐词的对齐10。 瓶颈由此打开:信息不再压缩进一个向量,而是「随用随查」。 作者给的评价是:这个看似温和的想法, 可争论地是过去十年深度学习最有影响力的想法—— 它直接催生了 Transformer11

4. 多头注意力:一组查询看不够,就 h 组并行

同一段输入,有人想看「主谓关系」,有人想看「指代关系」—— 一种匹配度装不下多种「相关」。 多头注意力的做法:把 q、k、v 各自用 h 组独立学习的线性投影 投到 h 个不同的表示子空间,每个子空间独立做一次注意力(一头), h 个输出拼接后再过一次线性变换12:

头 i:head_i = Attention(W_i^q q, W_i^k k, W_i^v v)
输出:W_o · [head_1; …; head_h]

成本上有个常用的约定:每个头的维度设成总维度的 1/h(p_q = p_o/h), 这样 h 个头的总成本和一个单头大体相当13。 效果是:不同的头可以各看各的—— 有的关注短程搭配,有的关注长程指代, 「相关」这个词从单数变成了复数。

5. 自注意力与位置编码:丢掉循环之后,补回顺序

自注意力(self-attention):查询、键、值全部来自同一个序列—— 每个词以自己为 query,全体词为 key/value, 算出的新表示里掺进了全句的信息14。 它对比 CNN、RNN 的三项指标,书里有一张关键的对照表15:

架构计算复杂度顺序操作(不可并行)最长路径(任意两位置)
CNN(核 k)O(knd²)O(1)O(n/k)
RNNO(nd²)O(n)O(n)
自注意力O(n²d)O(1)O(1)

读法:RNN 必须逐词串行,且信息从第 1 词传到第 n 词要穿 n 步; 自注意力任何两个词一步直达(最长路径 O(1)),还能全并行—— 长程依赖好学了,GPU 也喂得饱。 代价写在第一列:对序列长度平方的复杂度,长序列吃不消—— 这是注意力唯一的阿喀琉斯之踵,后面所有高效注意力变体都在治它。

还有一个自注意力自己丢掉的性质:它完全不认顺序—— 把输入打乱,输出只是跟着打乱,集合运算。 顺序信息必须显式补回。Transformer 原案的位置编码16:

p_{i,2j} = sin(i / 10000^{2j/d})
p_{i,2j+1} = cos(i / 10000^{2j/d})

不同维度是正弦/余弦的不同频率——像二进制数的各个位: 低位变化快(高频),高位变化慢(低频),但用连续值表示,比二进制省空间17。 它还有一个关键的代数性质:任意固定偏移 δ, 位置 i+δ 的编码是位置 i 的编码的一个线性投影(旋转矩阵,与 i 无关)—— 所以模型很容易从它学出「相对位置」(往前/往后几个词)。

6. 作者的判断与证据

书里给了证据的: √d 的方差推导;Bahdanau 注意力的公式与对齐可视化; 三架构对比表;位置编码的线性投影性质(2×2 旋转矩阵推导)。

作者的立场: 「Nadaraya-Watson 一节可跳过,但它演示了手工打分的极限」—— 教学路径的选择;「注意力权重的可视化有解释力,但只是直觉」—— 作者特意提醒,大权重=「模型在选相关部分」是一种解读,不是机制保证18

判断(我们的,不是书里的): 注意力是本书「约束换效率」与「通用换规模」 两条路线的交汇点:CNN 用强结构偏见换样本高效(第 08 章), 注意力几乎不带偏见——连顺序都要现补——换取「什么都查得到」的通用性, 账单就是 O(n²)。选架构时先数你的数据量和结构先验: 先验强且数据少,选卷积;先验弱且数据多,选注意力。 如果错,会错在: 这个二分是经验地图不是定理; 视觉 Transformer(第 13 章)正是「数据够多时注意力也能吃掉卷积的地盘」的实例, 而混合架构(卷积干+注意力)证明两者也能共存。

7. 边界与局限

  • O(n²) 复杂度:长序列(数万词)直接不可行,稀疏/线性注意力等变体原书只给了指引;
  • 注意力权重≠解释:可视化好看,但「看了哪」不等于「为什么」;
  • 位置编码补的是顺序的「可学性」,不保证模型一定用好它;
  • 加性注意力已基本是历史(维度不匹配的场合),点积是现役主流。

8. 可带走的

  1. 注意力 = 可微分的数据库查询:Σα(q,kᵢ)vᵢ,softmax 归一化,全程可导;
  2. 标准形态是凸组合;独热=数据库查询,均匀=平均池化;
  3. 缩放点击:a=qᵀk/√d——不除 √d,大维度下 softmax 饱和、梯度消失;
  4. Bahdanau:解码每步重算上下文,信息随用随查,不再靠一个向量传话;
  5. 多头:h 组独立投影,h 种「相关」,成本与单头相当;
  6. 自注意力:全并行、最长路径 O(1),代价 O(n²);
  7. 自注意力不认顺序;sin/cos 位置编码,「固定偏移=线性投影」使相对位置易学。

9. 原文地图

主题原书章原文位置
数据库类比Queries, Keys, and Valuestext/69-queries-keys-and-values.txt:11(搜「Zhang」)
注意力定义与特例Queries, Keys, and Valuestext/69-queries-keys-and-values.txt:26(搜「convex combination」) · text/69-queries-keys-and-values.txt:27(搜「traditional database query」)
softmax 归一化Queries, Keys, and Valuestext/69-queries-keys-and-values.txt:34(搜「exponentiation」)
Nadaraya-Watson 与手工极限Attention Pooling by Similaritytext/70-attention-pooling-by-similarity.txt:19(搜「requires no training」) · text/70-attention-pooling-by-similarity.txt:229(搜「hand-crafted attention」)
√d 方差论证Attention Scoring Functionstext/71-attention-scoring-functions.txt:62(搜「variance of $d$」)
masked softmaxAttention Scoring Functionstext/71-attention-scoring-functions.txt:92(搜「large negative number」)
充分统计量、瓶颈Bahdanau Attentiontext/72-the-bahdanau-attention-mechanism.txt:17(搜「sufficient statistic」) · text/72-the-bahdanau-attention-mechanism.txt:22(搜「not be enough」)
最有影响力的想法Bahdanau Attentiontext/72-the-bahdanau-attention-mechanism.txt:33(搜「most influential ideas」)
多头、子空间、1/hMulti-Head Attentiontext/73-multi-head-attention.txt:14(搜「representation subspaces」) · text/73-multi-head-attention.txt:112(搜「p_o / h」)
三架构对比Self-Attention and Positional Encodingtext/74-self-attention-and-positional-encoding.txt:170(搜「maximum path length」) · text/74-self-attention-and-positional-encoding.txt:209(搜「quadratic computational complexity」)
位置编码、二进制类比、线性投影Self-Attention and Positional Encodingtext/74-self-attention-and-positional-encoding.txt:253(搜「10000」) · text/74-self-attention-and-positional-encoding.txt:467(搜「linear projection」)

Footnotes

  1. 出处:「Queries, Keys, and Values」第 11 段(text/69-queries-keys-and-values.txt:11,搜「Zhang」)。

  2. 出处:「Queries, Keys, and Values」第 23 段(text/69-queries-keys-and-values.txt:23,搜「attention pooling」)。

  3. 出处:「Queries, Keys, and Values」第 26 段(text/69-queries-keys-and-values.txt:26,搜「convex combination」)、第 27 段(text/69-queries-keys-and-values.txt:27,搜「traditional database query」)与第 28 段(text/69-queries-keys-and-values.txt:28,搜「average pooling」)。

  4. 出处:「Queries, Keys, and Values」第 34 段(text/69-queries-keys-and-values.txt:34,搜「exponentiation」)。

  5. 出处:「Attention Pooling by Similarity」第 19 段(text/70-attention-pooling-by-similarity.txt:19,搜「requires no training」)与第 229 段(text/70-attention-pooling-by-similarity.txt:229,搜「hand-crafted attention」)。

  6. 出处:「Attention Scoring Functions」第 62 段(text/71-attention-scoring-functions.txt:62,搜「variance of $d$」)。

  7. 出处:「Attention Scoring Functions」第 92 段(text/71-attention-scoring-functions.txt:92,搜「large negative number」)。

  8. 出处:「The Bahdanau Attention Mechanism」第 17 段(text/72-the-bahdanau-attention-mechanism.txt:17,搜「sufficient statistic」)。

  9. 出处:「The Bahdanau Attention Mechanism」第 31 段(text/72-the-bahdanau-attention-mechanism.txt:31,搜「aligns (or attends)」)。更早的单向对齐尝试:Graves 2013 手写生成。

  10. 出处:「The Bahdanau Attention Mechanism」第 33 段(text/72-the-bahdanau-attention-mechanism.txt:33,搜「most influential ideas」)与可视化节。

  11. 出处:「The Bahdanau Attention Mechanism」第 33 段(text/72-the-bahdanau-attention-mechanism.txt:33,搜「most influential ideas」)。

  12. 出处:「Multi-Head Attention」第 14 段(text/73-multi-head-attention.txt:14,搜「representation subspaces」)。

  13. 出处:「Multi-Head Attention」第 112 段(text/73-multi-head-attention.txt:112,搜「p_o / h」)。

  14. 出处:「Self-Attention and Positional Encoding」第 6 段(text/74-self-attention-and-positional-encoding.txt:6,搜「self-attention」)。

  15. 出处:「Self-Attention and Positional Encoding」第 149 段(text/74-self-attention-and-positional-encoding.txt:149,搜「maximum path lengths」)、第 204 段(text/74-self-attention-and-positional-encoding.txt:204,搜「maximum path length is also」)与第 209 段(text/74-self-attention-and-positional-encoding.txt:209,搜「quadratic computational complexity」)。

  16. 出处:「Self-Attention and Positional Encoding」第 253 段(text/74-self-attention-and-positional-encoding.txt:253,搜「10000」)。

  17. 出处:「Self-Attention and Positional Encoding」第 408 段(text/74-self-attention-and-positional-encoding.txt:408,搜「binary representations」)。

  18. 出处:「Queries, Keys, and Values」第 75 段(text/69-queries-keys-and-values.txt:75,搜「just that」)。