为什么提 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。