RNN、LSTM 与 GRU 总览
三类循环网络共享时间参数,但状态结构和长依赖能力不同。
学习目标
- 同输入维度与隐藏维度的参数账本
- batch_first 会改变 h_n 的维度顺序吗?
- 说明:同 hidden size 不是同参数预算;双向模型也不能用于依赖未来不可见信息的部署场景。
为什么需要这个概念
普通 RNN 用单一非线性状态更新,GRU 用两个主要门和单状态,LSTM 用多门及 h、c 双状态。三者都在时间维共享参数。
学习前需要掌握
背景与问题
RNN、LSTM、GRU 都能逐步处理序列,差异主要在状态与门控机制。选型需要结合上下文长度、在线延迟和验证结果,而不是只记一个优劣排名。
概念定义
普通 RNN 用单一非线性状态更新,GRU 用两个主要门和单状态,LSTM 用多门及 h、c 双状态。三者都在时间维共享参数。
直观理解
三种方法都维护笔记,区别在于笔记的结构和擦写控制,而不是只有某一种才具有历史依赖。
核心原理
普通 RNN 计算最简,但长路径梯度容易衰减或放大;LSTM 通过细胞状态加法路径控制记忆;GRU 把旧状态与候选直接混合。门控增加参数,可能改善长期依赖,却同时增加运算与调参成本。
对 batch_first 输入 ,单向 output 为 。h_n 为 ,LSTM 还返回同类形状的 c_n。双向网络的输出末维是 2H,但它需要未来上下文,不适合直接用于严格在线因果预测。
比较时应控制数据划分和训练预算,并记录参数量、耗时及任务指标。同 hidden size 的模型参数量不相同,不能把这种比较误说成完全等容量比较。
数学表达
核心公式
普通 RNN 用单一非线性状态更新,GRU 用两个主要门和单状态,LSTM 用多门及 h、c 双状态。三者都在时间维共享参数。
变量含义
Nbatch sizeD/H特征或隐藏维度
计算步骤
- 1普通 RNN 参数为 4×3+4×4+2×4=36。
- 2GRU 有三组门相关变换,共 108。
- 3LSTM 有四组,共 144。
代码对应位置
示例 1同输入维度与隐藏维度的参数账本的最小验证:使用完整构造输入核对同输入维度与隐藏维度的参数账本,输出只表示本例计算。
变量解释
| 变量 | 含义 |
|---|---|
N | batch size |
D/H | 特征或隐藏维度 |
完整数值示例
同输入维度与隐藏维度的参数账本
已知条件
- input_size=3,hidden_size=4,单层单向,有偏置
- 输入 shape 为 (2,5,3)
计算步骤
- 普通 RNN 参数为 4×3+4×4+2×4=36。
- GRU 有三组门相关变换,共 108。
- LSTM 有四组,共 144。
计算结果
三者 output 都为 (2,5,4),参数量分别为 36、108、144。
处理前后对比
- 同 hidden size 不是同参数预算;双向模型也不能用于依赖未来不可见信息的部署场景。
同输入维度与隐藏维度的参数账本
PyTorch 为输入和隐藏线性变换分别设置偏置,因此有 2H 个偏置,而非只算 H。门数的差异直接乘到这套账本上。
相同输出 shape 便于替换模块,却不意味着优化行为相同。若需要公平资源比较,可以进一步调整 H 使参数或推理延迟接近,再用同样验证协议比较。
计算与实现步骤
- 普通 RNN 参数为 4×3+4×4+2×4=36。
- GRU 有三组门相关变换,共 108。
- LSTM 有四组,共 144。
代码实现
示例 1
同输入维度与隐藏维度的参数账本的最小验证
example_01.py用途:使用完整构造输入核对同输入维度与隐藏维度的参数账本,输出只表示本例计算。
import torch
from torch import nn
x = torch.zeros(2, 5, 3)
for cls in [nn.RNN, nn.GRU, nn.LSTM]:
model = cls(3, 4, batch_first=True)
out, state = model(x)
params = sum(p.numel() for p in model.parameters())
print(f"{cls.__name__}: output={tuple(out.shape)} parameters={params}")代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用完整构造输入核对同输入维度与隐藏维度的参数账本,输出只表示本例计算。
model- 组合预处理和估计器的模型对象。
Step 1 · 1–8 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torch
from torch import nn
x = torch.zeros(2, 5, 3)
for cls in [nn.RNN, nn.GRU, nn.LSTM]:
model = cls(3, 4, batch_first=True)
out, state = model(x)
params = sum(p.numel() for p in model.parameters())
print(f"{cls.__name__}: output={tuple(out.shape)} parameters={params}")预期输出或运行结果
RNN: output=(2, 5, 4) parameters=36 GRU: output=(2, 5, 4) parameters=108 LSTM: output=(2, 5, 4) parameters=144
常见错误 · 4 条
- 双向用于在线预测
- h_n 维度错
- 跨样本复用状态
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 建立循环模型对照实验
- 检查多层与双向状态形状
常见错误
- 双向用于在线预测
- h_n 维度错
- 跨样本复用状态
常见问题
batch_first 会改变 h_n 的维度顺序吗?
不会,它只改变输入和 output 的 batch/time 排列;h_n 的首轴仍组合层数与方向。
这个示例能说明什么边界?
同 hidden size 不是同参数预算;双向模型也不能用于依赖未来不可见信息的部署场景。
推荐学习资料
MIT Introduction to Deep Learning
以密集讲座和实验介绍神经网络、序列模型、生成模型和深度学习应用。
MIT 6.S191 Team · MIT