CS231n(柒)——循环神经网络
$\large\star$ 回顾:前馈网络与序列数据
前六讲的所有网络(线性分类器、MLP、CNN)都是前馈网络:输入→前向传播→输出,固定大小的输入。
但很多视觉任务涉及序列:
| 任务 | 输入 | 输出 |
|---|---|---|
| 图像描述 (Image Captioning) | 图像 | 单词序列 |
| 动作预测 (Action Prediction) | 视频帧序列 | 动作类别 |
| 视频描述 (Video Captioning) | 视频帧序列 | 描述文字 |
| 帧级视频分类 | 视频帧序列 | 每帧的类别 |
$\large\star$ 一、RNN 基础
1.1 核心思想
RNN 有一个内部状态(hidden state),在处理序列时不断更新:
$$\boxed{h_t = f_W(h_{t-1}, x_t)}$$
- ht:当前隐藏状态
- ht − 1:上一时刻的隐藏状态
- xt:当前输入
- fW:参数为 W 的函数(所有时间步共享同一组参数)
1.2 展开的 RNN
1 | h_0 → RNN → h_1 → RNN → h_2 → RNN → h_3 → ... → h_t |
1.3 Vanilla RNN(Elman RNN)
最简单的 RNN——隐藏状态是一个向量 h:
ht = tanh (Whhht − 1 + Wxhxt) yt = Whyht
所有时间步使用相同的 W,因此 RNN 天然具有对称性:无论输入在序列的哪个位置,都以相同方式处理。
1.4 RNN 的计算图模式
| 模式 | 说明 | 示例 |
|---|---|---|
| Many-to-Many | 输入序列→输出序列,每个时间步都有输出 | 帧级视频分类、序列标注 |
| Many-to-One | 输入序列→单个输出 | 情感分类、动作识别 |
| One-to-Many | 单个输入→输出序列 | 图像描述生成 |
$\large\star$ 二、训练 RNN:通过时间的反向传播
2.1 前向与反向
- 前向:沿整个序列计算损失
- 反向:沿整个序列反向传播梯度
2.2 截断的反向传播(Truncated BPTT)
对于长序列,不需要反向传播到最开头:
- 前向时携带隐藏状态一直向前
- 反向时只回传固定步数(如10步)
类似于将长序列切成多个片段分别训练,但隐藏状态在片段间保持连续。
2.3 字符级语言模型示例
词汇表 [h, e, l, o],训练序列 "hello":
训练时:输入 "h" 预测 "e",输入
"e" 预测 "l",以此类推
采样时:从 Softmax 输出中采样一个字符,将其作为下一步的输入(自回归生成)
Andrej Karpathy 的 min-char-rnn.py 仅 112 行 Python 即可实现字符级语言模型!
2.4 嵌入层
One-hot 向量 × 权重矩阵 = 从权重矩阵提取一列(即 embedding)。实践中在输入和 RNN 之间加一个可学习的嵌入层 WE。
$\large\star$ 三、RNN 的梯度问题
3.1 梯度消失与梯度爆炸
从 ht 反向传播到 ht − 1 时,每一步乘以 WhhT:
- 最大奇异值 > 1 → 梯度爆炸
- 最大奇异值 < 1 → 梯度消失(实践中几乎总是如此)
3.2 解决方案
| 问题 | 解决方案 |
|---|---|
| 梯度爆炸 | 梯度裁剪(Gradient Clipping):若梯度范数过大则等比缩放 |
| 梯度消失 | 改变 RNN 架构(如 LSTM) |
$\large\star$ 四、LSTM(长短期记忆网络)
4.1 核心创新
Vanilla RNN 的问题:梯度流经矩阵乘法 WhhT → 梯度消失/爆炸。
LSTM 的解决方案:维护一个独立的细胞状态 ct,梯度通过逐元素乘法(而非矩阵乘法)流动。
4.2 四个门
$$\begin{pmatrix} i \\ f \\ o \\ g \end{pmatrix} = \begin{pmatrix} \sigma \\ \sigma \\ \sigma \\ \tanh \end{pmatrix} W \begin{pmatrix} h_{t-1} \\ x_t \end{pmatrix}$$
| 门 | 含义 | 作用 |
|---|---|---|
| Input Gate (i) | 输入门 | 是否写入细胞状态 |
| Forget Gate (f) | 遗忘门 | 是否擦除细胞状态 |
| Output Gate (o) | 输出门 | 暴露多少细胞状态 |
| Gate Gate (g) | 候选值 | 写入多少内容到细胞状态 |
4.3 细胞状态更新
ct = f ⊙ ct − 1 + i ⊙ g ht = o ⊙ tanh (ct)
4.4 不间断的梯度流
从 ct 到 ct − 1 的反向传播只有逐元素乘法(f),没有矩阵乘法!
c0 → c1 → c2 → ... → ct
💡 这就是 LSTM 的关键:只要 f = 1, i = 0,信息可以被无限期保留。LSTM 不保证梯度永远不消失,但提供了”更容易学到长距离依赖”的途径。
LSTM 的细胞状态梯度流与 ResNet 的残差连接有异曲同工之妙——都是通过恒等路径缓解深层网络的优化问题。
$\large\star$ 五、RNN 的应用
5.1 图像描述(Image Captioning)
CNN 提取图像特征 v → RNN 逐词生成描述
修改 RNN 公式,加入图像信息: h = tanh (Wxh ⋅ x + Whh ⋅ h + Wih ⋅ v)
输入 <START> → 采样 "straw" → 输入
"straw" → 采样 "hat" → … → 采样
<END>
5.2 其他应用
- VQA(视觉问答):图像 + 问题 → RNN → 答案
- Visual Dialog:图像 + 对话历史 → RNN → 回答
- 多层 RNN:将多个 RNN 层叠以增加深度
$\large\star$ 六、RNN 的优劣与现代发展
RNN 优势
- 可处理任意长度输入(无上下文长度限制)
- 理论上第 t 步可以使用很久之前的信息
- 模型大小不随输入长度增加
- 同一权重应用于每一步(对称性)
RNN 劣势
- 循环计算慢(不可并行化)
- 实践中难以访问很久之前的信息(梯度消失)
现代 RNN:状态空间模型(SSM)
如 Mamba、RWKV 等: - 无限上下文长度 - 计算量随序列长度线性增长
$\large\star$ 七、总结
| 概念 | 核心要点 |
|---|---|
| RNN | 维护隐藏状态 ht = fW(ht − 1, xt),所有时间步共享同一组参数 |
| 计算图模式 | Many-to-Many / Many-to-One / One-to-Many |
| BPTT | 沿序列反向传播;长序列用截断 BPTT 只回传固定步数 |
| 梯度问题 | 梯度爆炸用梯度裁剪;梯度消失需更换架构 |
| LSTM | 独立细胞状态 ct + 输入/遗忘/输出门,梯度沿逐元素乘法流动 |
| 应用 | 图像描述、VQA、Visual Dialog、多层 RNN |
| 现代发展 | 状态空间模型(Mamba、RWKV)——长上下文、线性计算量 |
下一讲:CS231n(捌)——注意力与Transformer
