为什么提 RNN/LSTM
它们已经被 Transformer 全面取代——但理解它们能更好理解 Transformer。还有些场景(资源受限的边缘设备、超长序列)仍在用 LSTM。
RNN:循环神经网络
每一步把"当前输入 + 上一步隐藏状态"变成"新隐藏状态":
h_t = tanh(W_h · h_{t-1} + W_x · x_t + b)
y_t = W_y · h_t
import torch.nn as nn
rnn = nn.RNN(input_size=10, hidden_size=32, batch_first=True)
x = torch.randn(4, 20, 10) # batch=4, seq_len=20, dim=10
out, h = rnn(x)
print(out.shape) # (4, 20, 32) 每步隐藏状态
print(h.shape) # (1, 4, 32) 最后一步
RNN 的致命问题:梯度消失
序列一长,反向传播时梯度连乘——要么爆炸要么消失。RNN 实际只能处理几十步。
LSTM:用门解决长依赖
LSTM 引入三个门(gate)来控制信息流:
- 遗忘门(forget gate):要忘掉多少旧记忆
- 输入门(input gate):要记住多少新输入
- 输出门(output gate):从记忆里读多少出去
lstm = nn.LSTM(input_size=10, hidden_size=32, batch_first=True, num_layers=2)
x = torch.randn(4, 20, 10)
out, (h, c) = lstm(x)
# h 是隐藏状态,c 是细胞状态("长期记忆")
GRU:LSTM 的简化版
gru = nn.GRU(input_size=10, hidden_size=32, batch_first=True)
参数比 LSTM 少 25%,效果接近——优先选 GRU 而不是 LSTM。
双向 RNN
nn.LSTM(10, 32, batch_first=True, bidirectional=True)
同时跑正向 + 反向——序列任务用得多(命名实体识别、词性标注)。
实战:用 LSTM 做文本分类
class TextClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden, num_classes):
super().__init__()
self.embed = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden, batch_first=True, bidirectional=True)
self.fc = nn.Linear(hidden * 2, num_classes)
def forward(self, x):
e = self.embed(x) # (B, L, D)
out, _ = self.lstm(e) # (B, L, 2H)
last = out[:, -1, :] # 取最后一步的输出
return self.fc(last)
model = TextClassifier(vocab_size=10000, embed_dim=128, hidden=64, num_classes=5)
为什么被 Transformer 替代
- 训练慢:序列必须串行展开(一步一步),不能并行
- 长依赖弱:再 long 的 LSTM 也比不过 attention 直接看任意位置
- 超大模型不好做:LSTM 不像 Transformer 容易堆深
GPT / BERT / Claude 一统江湖之后,LSTM 在 NLP 领域基本绝迹。
还活着的场景
- 时间序列预测(股价、销量、IoT 传感器)
- 边缘设备 / 嵌入式(参数比 Transformer 小很多)
- 在线学习(流数据,逐步更新)
一句话总结
LSTM 是过去式,但学会它你能秒懂 Transformer 在解决什么——下一篇就讲 Transformer。