怎么记住任意长的历史?
本课一问:怎么记住任意长的历史? 「小明 把 苹果 给了 ___」——要猜出下一个词,得记得 4 个词之前的「小明」。上一课的 bigram 只看前 1 个词。
这一课先不碰:输入一句、输出另一句的翻译结构(L3);注意力(L3、L4);LSTM 各个门的完整公式(只讲梯度走哪条路)。
从已有出发
贯穿例句「小明 把 苹果 给了 小王」:要在最后一格猜出「小王」,得记得 4 个词以前的「小明」。上一课的 bigram 只看得到「给了」。
上一课的计数模型输出的是同一个东西——下一个词的概率(流水线最右端),失败在两处:没见过的组合概率为 0;窗口只有前 1 个词。第一处要靠词向量解决(C1);这一课处理第二处。
这条流水线的「解码层」里今天放的是注意力;这一课讲的 RNN 不在其中——但它的一个想法在 2025-2026 年又回到了锚点模型的 64 层里的 48 层(岔路 B1)。
先自己设计:窗口不够,那就加大窗口?
最直接的想法:bigram 只看前 1 个词,那就看前 n−1 个词。
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
| 窗口 | 计数表格子数 Vn(锚点 V = 248,320,现算) |
|---|---|
| 看前 1 个词(n = 2) | 6.17×10¹⁰ |
| 看前 2 个词(n = 3) | 1.53×10¹⁶ |
| 看前 4 个词(n = 5) | 9.44×10²⁶ |
即使把计数换成上一课预告的词向量(C1 的 NPLM),输入仍是「前 n−1 个词的向量拼起来」,窗口照样是写死的。
不存表格。只维护一个固定长度的向量 h(隐藏状态),每读一个词就用「旧状态 + 新词」算出新状态:
ht = tanh(W · ht−1 + U · xt)
状态的长度与前文长短无关,读 5 个词和读 5,000 个词,h 都是同样多的数;原理上,第 1 个词的信息可以一路传到第 5,000 步。用它来做语言模型:在每一步用 ht 预测下一个词。Mikolov et al. 2010 的 RNN 语言模型,几个 RNN 混合后的困惑度比当时最好的回退 n-gram 低约 50% 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条摘要原话:混合多个 RNN 语言模型,困惑度相对最先进的回退语言模型下降约 50%。只在其语音识别语料上。 出处Mikolov et al. 2010 · INTERSPEECH ↗需联网 。
改进:能传下去,不等于学得会
先把 RNN 的一步看清楚:
训练用反向传播(沿时间展开,叫 BPTT):第 T 步的 loss 对第 T−n 步状态的梯度,是中间每一步的「局部导数」连乘。取最简单的标量 RNN(状态只有 1 个数,权重是一个数 w)看得最清楚:
这就是 梯度消失 / 爆炸:Hochreiter 1991 年的学位论文最早分析了它,Bengio, Simard & Frasconi 1994 把它写成「用梯度下降学长期依赖是困难的」 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条连乘的指数行为是可证明的;论文另有实验展示简单任务上随依赖长度增加学习失败。 出处Bengio, Simard, Frasconi 1994 · IEEE TNN 5(2) ↗需联网 。
常见误解:「RNN 能记住任意长的历史。」 它能表示:状态一路传下去,理论上第 1 个词可以影响第 100 步。但它学不会用:第 100 步的 loss 传回第 1 步时,只剩 2.66×10⁻⁵ 倍(w = 0.9 时;把 tanh′ 算进去更小)。梯度小到这个程度,早期的词对参数更新几乎没有贡献。
常见误解:「w > 1 梯度就一定爆炸。」 只在状态停留在 tanh 的线性区时才会。状态一旦被推到 ±1 附近,tanh′ 很小,w·tanh′ 反而小于 1——下面实验台里把 w 设成 1.1、再调大输入强度 u 就能看到真实曲线往下走。
改进一:LSTM(1997)。 Hochreiter & Schmidhuber 给状态加了一条加法通路(细胞状态 c):ct = ct−1 + (门控后的新内容)。梯度沿这条路往回传时,每步乘的系数是 1,不再被迫乘 w·tanh′——原文把它叫作「恒定误差传送带」,并报告能跨越 1,000 步以上的时间间隔 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条「恒定误差流」让梯度不衰减是有理论动机的设计;「能跨越 1,000 步以上」是其人工合成任务上的实验结论。 出处Hochreiter & Schmidhuber 1997 · 摘要 ↗需联网 。
但原版的系数恒为 1,状态只能累加、不会清空。 今天说的 LSTM 里「每步乘遗忘门 f」是 Gers, Schmidhuber & Cummins 2000 加的,让网络自己学会什么时候忘 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条《Learning to Forget》:原版 LSTM 在连续输入流上状态会无限增长,遗忘门让它能自我重置;实验在其连续预测任务上。 出处Gers et al. 2000 · Neural Computation 12(10) ↗需联网 。于是细胞通路上的梯度又变回连乘:fn。f 是由数据算出来的、可学习,训练可以把需要记住的地方的 f 学到接近 1——但 f = 0.99 时 100 步剩 0.366,f = 0.9 时就和普通 RNN 一样了。
改进二:梯度裁剪。 爆炸那一侧,Pascanu, Mikolov & Bengio 2012 提出按梯度范数裁剪:范数超过阈值就等比例缩小 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条从动力系统角度分析爆炸的成因,提出范数裁剪并做了实验验证;它不解决消失。 出处Pascanu et al. 2012 · arXiv 1211.5063 ↗需联网 。今天训练 LLM 仍然默认开着它(C5 细讲)。
常见误解:「LSTM 解决了长依赖。」 它把强制的 w·tanh′ 换成了可学习的门 f,大大缓解了消失,但梯度仍然是连乘;而且下面两个问题它一个都没动。
还剩两个问题,RNN 家族都解决不了:
- 必须逐步串行。 要算 ht 必须先算完 ht−1,一个 4,000 词的序列在训练时也要一步一步走 4,000 步,没法沿序列并行。串行步数、最长路径与每层计算量的真实计数,见 C3 的岔路课「为什么不用 RNN?」,L4 会看到 Transformer 怎样把它变成 1 步。
- 所有信息都挤在一个固定长度的状态里。 读一句话时还好;要把一整句翻译成另一句时,整句的意思都得压进这一个向量——下一课的问题。
RNN 的历史角色。 从 2010 年的 RNN 语言模型到 2017 年之前,循环网络是神经网络处理语言的主干:语言模型、字符级生成、2014 年的 seq2seq 翻译,以及 2015 年第一次「先用语言模型预训练、再微调」的尝试(Dai & Le 用的就是 LSTM,L5 会讲)都建在它上面。今天纯 RNN 已经退出 LLM 的主干,但「一个固定大小的状态」这个想法,在 2024-2026 年以线性注意力的形式回来了——锚点模型的 64 层里有 48 层就是这种层,见岔路 B1。
极小真数字:拖动 w,看梯度一步步消失
打开 LSTM 细胞通路:把「乘 w·tanh′」换成「乘遗忘门 f」
试三件事: ① 保持 w = 0.9、T = 100:左卡是 0.9100 = 2.66×10−5,中卡是真实前向算出的连乘——更小,因为 tanh′ 的平均值小于 1。点「逐步回传」,看颜色从右往左一格格变淡。 ② 把输入强度 u 拖到 0、w 设成 1.1:状态一直是 0,tanh′ 恒为 1,两条线重合,100 步后放大到 13,781 倍——这是爆炸。再把 u 慢慢拖大,看真实曲线掉头往下:状态进了饱和区。 ③ 展开下面的 LSTM 细胞通路:f = 1(1997 原版)是一条水平线;f = 0.99 时 100 步剩 0.366;f = 0.9 时和 RNN 的 0.9100 重合——还是连乘。
🔍 为什么叫「沿时间反向传播」
把 RNN 按时间展开,它就是一个 T 层深、每层共享同一组权重的前馈网络;对它做普通的反向传播,就叫 BPTT(backpropagation through time)。「梯度连乘」和深层前馈网络里梯度逐层相乘是同一件事,只是 RNN 的层数等于序列长度,而且每层用的是同一个 W,连乘的是同一个矩阵——这让指数行为更加极端。证据三问
| 问 | 本课的回答(以 LSTM 为例) |
|---|---|
| ① 它解决什么问题? | 普通 RNN 的梯度沿时间被 w·tanh′ 连乘,100 步后只剩 2.66×10⁻⁵ 或更少,长距离依赖学不会 |
| ② 数学上为什么可能有效? | 细胞通路是加法,每步乘的系数变成可学的门,能接近 1 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条恒定误差通道是设计动机,不是最优性证明。 出处Hochreiter & Schmidhuber 1997 ↗需联网 |
| ③ 实验上为什么被选中? | 在长间隔合成任务、后来的语言与翻译任务上明显好于普通 RNN;没有最优证明,2017 年以后在语言上被注意力取代(L4) 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条能跨越 1,000 步以上是其合成任务上的结果。 出处Hochreiter & Schmidhuber 1997 ↗需联网 |
本课每条结论的证据等级:
| 结论 | 证据等级 | 依据 |
|---|---|---|
| 梯度沿时间是局部导数的连乘 | 可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条链式法则直接展开。 出处待补 | BPTT 推导 |
| 真实连乘 ≤ ∣w∣n(标量) | 可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条tanh′(z) = 1 − tanh²(z) ≤ 1。 出处待补 | 导数上界 |
| 连乘导致长依赖难学 | 可证明 + 实验 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条指数行为可证;「学不会」由其实验展示。 出处Bengio et al. 1994 ↗需联网 | Hochreiter 1991;Bengio et al. 1994 |
| RNN 语言模型优于回退 n-gram | 实验验证 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条多个 RNN 混合,困惑度降约 50%,其语料上。 出处Mikolov et al. 2010 ↗需联网 | Mikolov et al. 2010 |
| LSTM 缓解消失 | 理论动机 + 实验 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条加法通路让系数为 1 是设计动机;能跨 1,000 步是合成任务上的实验。 出处Hochreiter & Schmidhuber 1997 ↗需联网 | LSTM 1997;遗忘门 Gers 2000 |
| 范数裁剪能控制爆炸 | 理论动机 + 实验 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条有动力系统分析,效果由实验验证。 出处Pascanu et al. 2012 ↗需联网 | Pascanu et al. 2012 |
一句话
RNN 用一个固定大小的状态记住任意长的历史;但梯度每往回一步都要乘一次,0.9 乘 100 次只剩 2.66×10⁻⁵。
先停在这里:记住 0.9100 = 2.66×10−5 这一个数,进 L3。
再深一层:岔路 B1 · 固定状态为什么又回来了(建议读完 L4 再去),或展开上面「沿时间反向传播」的 Dig。
下一个缺口
语言模型只需要「读到哪、猜到哪」。可要是任务是读完一整句法语、再写出一整句英语呢?编码器 RNN 读完整句,手里只剩最后那一个状态;解码器只能从这一个向量里把整句话的意思还原出来。长句会怎样? → L3 · 输入一句、输出一句,长句为什么丢
你可能会问
这一课还没有真实提问记录。先列几个最常见的:
- 固定大小的状态,2026 年为什么又回来了? → 岔路 B1 · 为什么 2026 年「固定状态」又回来了(会用到 L3、L4 的注意力,建议读完 L4 再去)。
- 既然 RNN 不能并行,它到底慢多少? → C3 岔路 为什么不用 RNN? 用锚点模型的维度现算串行步数与每层计算量。
- 梯度裁剪的阈值怎么定? → C5 的「一个超大梯度把模型甩飞」一课。