RNN 与 LSTM
RNN:循环神经网络
Section titled “RNN:循环神经网络”RNN 的核心思想:序列中每个位置的输出不仅依赖当前输入,还依赖之前的状态。
flowchart LR subgraph 展开的 RNN h0[">h₀"] --> h1["h₁ = tanh(Wₕh₀ + Wₓx₁)"] h1 --> h2["h₂ = tanh(Wₕh₁ + Wₓx₂)"] h2 --> h3["h₃ = ..."] end x1[x₁] --> h1 x2[x₂] --> h2和 在所有时间步共享,这是 RNN 能处理变长序列的关键。
基础 RNN 实现
Section titled “基础 RNN 实现”import torchimport torch.nn as nn
rnn = nn.RNN(input_size=128, hidden_size=256, num_layers=1, batch_first=True)x = torch.randn(2, 10, 128) # (batch=2, seq_len=10, features=128)output, hidden = rnn(x)print(f"输出: {output.shape}, 最终隐状态: {hidden.shape}")# 输出: (2, 10, 256), 最终隐状态: (1, 2, 256)RNN 的致命问题
Section titled “RNN 的致命问题”反向传播时,梯度经过 反复相乘:
- 如果 的特征值 < 1 → 梯度消失,早期时间步无法学习
- 如果 的特征值 > 1 → 梯度爆炸,参数变为 NaN
# 梯度裁剪是防止爆炸的常用手段torch.nn.utils.clip_grad_norm_(rnn.parameters(), max_norm=1.0)LSTM:长短期记忆
Section titled “LSTM:长短期记忆”LSTM 通过门控机制解决梯度消失问题。它维护一个细胞状态 ,信息可以不受阻碍地流过:
flowchart TD subgraph LSTM 单元 A[遗忘门 f_t] --> D[细胞状态 c_t] B[输入门 i_t] --> D C[输出门 o_t] --> E[隐状态 h_t] D -->|tanh| E end| 门 | 公式 | 作用 |
|---|---|---|
| 遗忘门 | 决定丢弃哪些旧信息 | |
| 输入门 | 决定存储哪些新信息 | |
| 候选值 | 新候选信息 | |
| 更新 | 更新细胞状态 | |
| 输出门 | 决定输出什么 | |
| 隐状态 | 最终输出 |
lstm = nn.LSTM(input_size=128, hidden_size=256, num_layers=1, batch_first=True)
x = torch.randn(2, 10, 128)output, (hidden, cell) = lstm(x)print(f"输出: {output.shape}") # (2, 10, 256)print(f"隐状态: {hidden.shape}") # (1, 2, 256)print(f"细胞状态: {cell.shape}") # (1, 2, 256)双向 LSTM
Section titled “双向 LSTM”同时从前向和后向处理序列,捕获上下文:
bilstm = nn.LSTM(128, 256, bidirectional=True, batch_first=True)output, _ = bilstm(x)print(f"双向输出: {output.shape}") # (2, 10, 512) — 256×2RNN vs LSTM vs Transformer
Section titled “RNN vs LSTM vs Transformer”| 特性 | RNN | LSTM | Transformer |
|---|---|---|---|
| 并行计算 | ❌ | ❌ | ✅ |
| 长距离依赖 | ❌ | ✅ | ✅ (O(1)) |
| 训练速度 | 慢 | 慢 | 快 |
| 推理速度 | 快 | 中 | 中(可用 KV Cache) |
- 时间序列预测(股价、天气)
- 语音识别(CTC 损失)
- 文本生成(字符级 RNN)
- 机器翻译(Seq2Seq + Attention)
- CNN — 图像处理架构
- Transformer — 取代 RNN 的现代架构