前馈神经网络一次只看一个输入,没有"时间"的概念。但语言、语音、股价都是序列——当前时刻的含义依赖之前发生了什么。循环神经网络(RNN)的核心想法很简单:
给网络加一个"记忆":把上一时刻的隐状态传给下一时刻。
具体来说,Elman RNN 在每个时间步 t 做两件事:
ht=tanh(Wxh⋅xt+Whh⋅ht−1+bh)
yt=Why⋅ht
ht 是隐状态——网络的"记忆"。它同时接收当前输入 xt 和前一步的记忆 ht−1,用 tanh 压到 (−1,1) 之间。yt 是当前时刻的输出。
把一个 RNN 沿时间轴"铺平",就得到一个很深的前馈网络——每个时间步是一层,所有层共享同一组权重 Wxh、Whh。这种视角叫 unrolling,它让我们能用熟悉的反向传播来训练 RNN。
既然展开后就是一个深度网络,训练方式自然是反向传播。对 RNN 而言,这叫 BPTT(Backpropagation Through Time):从最后一个时间步的损失出发,沿时间轴一路乘回去。
损失对隐状态的梯度需要逐步回传:
∂ht∂L=∂hT∂Lk=t+1∏T∂hk−1∂hk
关键在这个连乘。每一步的局部导数是:
∂hk−1∂hk=diag(1−hk2)⋅Whh
其中 diag(1−hk2) 是 tanh 的导数(最大值为 1,通常远小于 1)。
问题来了:这个连乘要乘 T−t 次。
- 如果 ∥Whh∥ 的谱范数 < 1,连乘指数衰减 → 梯度消失。早期时间步的信号传不到后面,网络"忘了"远处的输入。
- 如果 ∥Whh∥ 的谱范数 > 1,连乘指数增长 → 梯度爆炸。参数更新一步跳出几百倍,训练直接崩溃。
梯度爆炸可以用梯度裁剪(gradient clipping)粗暴解决——超过阈值就缩放。但梯度消失没有这么简单的补丁。它意味着:
简单 RNN 无法学习长距离依赖。 实际上超过 10–20 步,梯度就已经接近零了。
这就是 LSTM 被发明的原因。
LSTM(Long Short-Term Memory) 的核心思想是:给记忆一条"高速公路"——细胞状态 Ct。信息可以在这条路上几乎无损地流过多个时间步,不被反复乘以权重矩阵。
为了控制什么信息进入、保留、输出,LSTM 引入三道门(gate),每道门的输出都在 [0,1] 之间(sigmoid),然后和信号做逐元素乘法:
ft=σ(Wf⋅[ht−1,xt]+bf)
ft 接近 0 表示"清除这段记忆",接近 1 表示"完整保留"。当话题切换时,遗忘门会关闭。
it=σ(Wi⋅[ht−1,xt]+bi)
C~t=tanh(Wc⋅[ht−1,xt]+bc)
输入门决定"写多少",候选记忆是"写什么内容"。两者逐元素相乘后加到细胞状态上。
Ct=ft⊙Ct−1+it⊙C~t
这就是那条"高速公路":旧记忆乘以遗忘门(保留多少),加上新信息乘以输入门(写入多少)。梯度沿 C 回传时,只需乘以 ft——只要遗忘门接近 1,梯度几乎无损地流过。
ot=σ(Wo⋅[ht−1,xt]+bo)
ht=ot⊙tanh(Ct)
细胞状态是完整的记忆,但不是所有记忆都需要在当前时刻暴露。输出门控制隐状态 ht 呈现记忆的哪个部分。
关键在细胞状态的更新公式 Ct=ft⊙Ct−1+…。对 Ct−1 求导只得到 ft——一个接近 1 的标量。这意味着梯度可以沿细胞状态线性流过任意长度,不像简单 RNN 那样指数衰减。
用一个比喻:简单 RNN 的记忆是在纸上反复涂写——每一步都把整张纸重新画一遍,旧内容很快模糊。LSTM 的细胞状态是一块白板,只有拿到"遗忘门钥匙"才能擦,拿到"输入门钥匙"才能写。
点击 Step 开始
机器学习很有趣
注意第 5 步 "很":话题切换时遗忘门关闭 (f≈0.3),清除旧记忆并写入新信息
LSTM 门控可视化 — 模拟值展示门控如何控制信息流
GRU(Gated Recurrent Unit) 是 Cho 等人在 2014 年提出的简化方案。它把遗忘门和输入门合并为一个更新门 zt,同时去掉了独立的细胞状态:
zt=σ(Wz⋅[ht−1,xt])
rt=σ(Wr⋅[ht−1,xt])
h~t=tanh(W⋅[rt⊙ht−1,xt])
ht=(1−zt)⊙ht−1+zt⊙h~t
设计哲学:zt 同时控制"忘多少旧的"和"写多少新的"——忘掉的部分正好被新信息填上,两者互补。重置门 rt 决定计算候选值时参考多少旧隐状态。
GRU 参数更少、训练更快,在中等长度序列上表现与 LSTM 相当。但在需要非常精细的记忆控制(如代码生成、长文档)时,LSTM 仍有优势。