LSTM 与 GRU

上一节你已经看到 RNN 会“边读边记”。
这一节要解决一个更现实的问题:
如果普通 RNN 记不住太久,怎么办?
LSTM 和 GRU 就是为了解决这个“会读,但容易忘”的问题。
学习目标
- 理解普通 RNN 为什么容易忘掉远处信息
- 直觉理解门控机制在做什么
- 掌握 LSTM 的 cell state 和三种门
- 掌握 GRU 的更新门与重置门
- 看懂 PyTorch 中
nn.LSTM和nn.GRU的输入输出 - 理解什么时候更适合用 LSTM,什么时候 GRU 已经够用
历史背景:为什么后来一定会走到 LSTM?
这一节最关键的历史节点是:
| 年份 | 节点 | 关键作者 | 它最重要地解决了什么 |
|---|---|---|---|
| 1994 | Learning Long-Term Dependencies is Difficult | Bengio, Simard, Frasconi | 系统揭示了普通 RNN 在长依赖训练里的梯度消失问题 |
| 1997 | LSTM | Hochreiter, Schmidhuber | 用门控记忆机制缓解长期依赖和梯度问题 |
对新人来说,最值得先记的是:
LSTM 不是“RNN 再复杂一点”,而是为了解决普通 RNN 很难稳稳记住长距离信息这个核心问题。
所以这节课真正的主线不是:
- 记住几个门的名字
而是:
- 理解这些门为什么会被发明出来
为什么当年很多人会把 LSTM 看成一次“正面救场”?
因为在那之前,RNN 这条路并不是没人喜欢。
恰恰相反,它看起来非常诱人:
- 文本是序列
- 语音是序列
- 时间序列还是序列
按直觉,RNN 好像天然就该成为这类任务的主力。
但真正训练起来后,大家又不断撞到同一堵墙:
- 早期信息留不住
- 梯度往回传时越来越弱
- 序列一长,模型就开始“会读但会忘”
所以 LSTM 当年让人兴奋的地方,不只是“门控很聪明”,
而是它第一次非常明确地在说:
不是 RNN 方向错了,而是它需要一种更认真管理记忆的结构。
为什么“梯度消失”会让很多人对 RNN 主线开始焦虑?
因为在纸面上,RNN 看起来几乎什么序列都能处理:
- 文本
- 语音
- 时间序列
但一到真正训练长序列时,大家会发现:
- 越早的信息越难留下来
- 梯度一路传回去时会越来越弱
这就像你一开始以为自己能一路把长故事复述清楚,
但讲到后面,最前面的细节已经开始变得模糊。
所以 LSTM 当年真正让人眼前一亮的地方,不是“多了几道门”,
而是它像在告诉大家:
既然普通 RNN 靠自然传递记不住,那就给记忆本身加管理机制。
这就是为什么后来很多 人会把 LSTM 看成:
- 不是小修小补
- 而是一次真正针对长依赖问题的正面回应
一、为什么普通 RNN 不够?
1.1 一个经典问题:长距离依赖
看这句话:
“我小时候在上海住过很多年,所以虽然现在搬走了,但我最熟悉的城市还是上海。”
如果模型在最后读到“上海”时,要知道前面说的是哪座城市,它就必须把很久之前的信息一路记下来。
普通 RNN 理论上可以做到,但实践里经常会遇到:
- 越往后,早期信息越容易被冲淡
- 训练时梯度容易消失
- 序列一长,记忆就不稳
1.2 一个直觉类比
普通 RNN 很像你在纸条上不断改写一小段摘要:
- 每来一句新话,就把旧摘要改一下
问题是:
- 摘要空间太小
- 旧信息容易被覆盖
所以后面就出现了一个更聪明的思路:
不要只靠一个“会变的摘 要”,而要让模型学会“哪些该忘、哪些该留、哪些该输出”。
这就是门控机制。
二、LSTM 的核心直觉:给记忆加上“门”
2.1 LSTM 到底多了什么?
LSTM 在普通 RNN 基础上,最关键的增强是:
- 多了一条更稳定的记忆通道:
cell state - 多了几道门,控制信息流
可以先把它理解成:
普通 RNN 像只有一个小本子,LSTM 则像一套更精细的记忆管理系统。
2.2 LSTM 的三道门
| 门 | 作用 |
|---|---|
| Forget Gate | 决定旧记忆保留多少 |
| Input Gate | 决定新信息写入多少 |
| Output Gate | 决定当前输出多少给外部 |
这三道门不是人工规则,而是模型自己学出来的。