跳转到内容
← 返回算法
深度学习计算机科学 · 深度学习 · 序列建模22 分钟阅读

循环神经网络

Recurrent Neural Networks

1986 年,大卫·鲁姆哈特(David Rumelhart)、杰弗里·欣顿(Geoffrey Hinton)和罗纳德·威廉姆斯(Ronald Williams)在提出反向传播算法的同一篇论文中,也提出了将其应用于循环网络的设想。循环神经网络(Recurrent Neural Network, RNN)随后成为处理语言…

循环神经网络RNNLSTM序列建模自然语言处理

1986 年,大卫·鲁姆哈特(David Rumelhart)、杰弗里·欣顿(Geoffrey Hinton)和罗纳德·威廉姆斯(Ronald Williams)在提出反向传播算法的同一篇论文中,也提出了将其应用于循环网络的设想。循环神经网络(Recurrent Neural Network, RNN)随后成为处理语言、音频、时间序列的主要工具,直到 2017 年 Transformer 出现。

RNN 的核心思想:网络有"记忆",当前的输出不仅取决于当前输入,还取决于对过去信息的压缩表示(隐状态)。

破除误解:RNN 的"记忆"是有限的

RNN 理论上能记住任意长的历史,但实际上由于梯度消失(Vanishing Gradient)问题,标准 RNN 的有效记忆长度非常短(通常不超过 10–20 个时间步)。LSTM 的发明就是为了解决这个问题,但即便是 LSTM,在序列长度超过几百时也面临困难。这是 Transformer 取代 RNN 的直接原因:注意力机制允许任意两个位置之间直接交互,不受序列长度限制。

但"记不住"只是表层症状。本文后面会用一张表说明,真正致命的那一条是训练时不能并行——而这一点在 2024 年被重新审视后,反而成了循环架构复归的起点。

标准 RNN

RNN 的基本单元:在时间步 $t$,接受输入 xtx_t 和上一时间步的隐状态 ht1h_{t-1},输出新的隐状态 hth_t

ht=tanh(Whht1+Wxxt+b)h_t = \tanh(W_h h_{t-1} + W_x x_t + b)

y^t=Wyht+by\hat{y}_t = W_y h_t + b_y

其中 Wh,Wx,Wy,b,byW_h, W_x, W_y, b, b_y 是在所有时间步共享的参数。这种权重共享使 RNN 能处理任意长度的序列,参数数量不随序列长度增加。

展开的 RNN:将 RNN 在时间轴上展开,等价于一个非常深的前馈网络,每层共享权重。用随时间反向传播(Backpropagation Through Time, BPTT)计算梯度。

梯度消失的本质:BPTT 中,对 $t=0$ 的梯度包含矩阵乘积 k=1TWh(k)\prod_{k=1}^{T} W_h^{(k)}。若 WhW_h 的最大奇异值 $< 1$,长距离梯度指数衰减;若 $> 1$,梯度指数爆炸(用梯度裁剪 Gradient Clipping 应对)。

手算梯度消失:一个标量循环权重

"梯度指数衰减"这句话太抽象。把 RNN 简化到极致——隐状态是标量,激活函数暂取恒等映射,ht=wht1+xth_t = w \cdot h_{t-1} + x_t——梯度就只剩一项:

hTh0=wT\frac{\partial h_T}{\partial h_0} = w^T

一个指数函数而已。把几个 $w$ 值和几个序列长度列成表,问题的形状立刻看得见:

$w$$T=10$$T=20$$T=50$$T=100$
0.59.8×1049.8\times10^{-4}9.5×1079.5\times10^{-7}8.9×10168.9\times10^{-16}7.9×10317.9\times10^{-31}
0.90.3490.1225.2×1035.2\times10^{-3}2.7×1052.7\times10^{-5}
1.01111
1.12.596.731171.4×1041.4\times10^{4}
2.010241.0×1061.0\times10^{6}1.1×10151.1\times10^{15}1.3×10301.3\times10^{30}

这张表最该注意的是中间那一行有多窄$w = 1.0$ 是唯一稳定的取值;偏到 0.9,100 步的梯度就只剩 10510^{-5};偏到 1.1,它涨到 10410^{4}。而 $w$ 本身是靠梯度下降学出来的参数,没有任何机制把它钉在 1 附近。这不是"训练技巧不够好",是这一族函数的结构性质。

两侧的失败方式完全不同,这一点比公式更值得记住:

  • 消失一侧是静默失败。fp16 的机器精度约 9.8×1049.8\times10^{-4}。把 2.7×1052.7\times10^{-5} 这个长程梯度加到一个 $O(1)$ 的近程梯度上,结果一位都不会变——长程贡献在求和那一步就被吞掉了。损失照样平稳下降(近处的梯度还在),没有报错,没有 NaN,只有一个"看起来在训练、但学不到长程结构"的模型。
  • 爆炸一侧是喧闹失败$w = 2$$T = 50$ 时梯度是 101510^{15} 量级,一步更新就把参数打飞,损失立刻变 NaN。喧闹反倒是好事——能被检测、能被处理,梯度裁剪就够用。所以工程上爆炸早已是个已解决的问题,消失才是那个逼出 LSTM 的真麻烦

矩阵情形只是把 $w$ 换成 WhW_h 的最大奇异值,结论照旧。真实 RNN 还多乘一个 tanh\tanh 的导数,它上界为 1、在饱和区远小于 1,所以有效乘数是 wtanh|w| \cdot \tanh'——这意味着即便 $w$ 略大于 1,梯度仍可能消失,两个方向的危险可以同时存在于同一个网络里。

LSTM:长短期记忆网络

1997 年,塞普·霍克赖特(Sepp Hochreiter)和于尔根·施密德胡贝尔(Jürgen Schmidhuber)发表了 LSTM(Long Short-Term Memory),引入了门控机制(Gating Mechanism)细胞状态(Cell State)

LSTM 的核心是三个门:

遗忘门(决定丢弃哪些旧记忆): ft=σ(Wf[ht1,xt]+bf)f_t = \sigma(W_f [h_{t-1}, x_t] + b_f)

输入门(决定记录哪些新信息): it=σ(Wi[ht1,xt]+bi)i_t = \sigma(W_i [h_{t-1}, x_t] + b_i) C~t=tanh(WC[ht1,xt]+bC)\tilde{C}_t = \tanh(W_C [h_{t-1}, x_t] + b_C)

细胞状态更新Ct=ftCt1+itC~tC_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t

输出门ot=σ(Wo[ht1,xt]+bo)o_t = \sigma(W_o [h_{t-1}, x_t] + b_o) ht=ottanh(Ct)h_t = o_t \odot \tanh(C_t)

细胞状态 CtC_t 是"记忆高速公路"——信息可以通过它几乎无损地在时间轴上传播,梯度也能沿此路径回传,有效缓解了梯度消失问题。

GRU(Gated Recurrent Unit,Cho et al., 2014):LSTM 的简化版,将遗忘门和输入门合并为一个"更新门",参数更少,在许多任务上表现与 LSTM 相当。

门控在具体数值下做了什么

"记忆高速公路"这个说法把细胞状态的更新式 Ct=ftCt1+itC~tC_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t 带过去了。路修得有多宽,其实是能算出来的:忽略新写入,把 ftf_t 当成常数 $f$$T$ 步之后的残留量就是 fTf^T。定义记忆半衰期 T1/2=ln0.5/lnfT_{1/2} = \ln 0.5 / \ln f

遗忘门输出 $f$所需预激活值 σ1(f)\sigma^{-1}(f)半衰期(步)100 步后残留
0.501.07.9×10317.9\times10^{-31}
0.92.206.62.7×1052.7\times10^{-5}
0.952.9413.50.0059
0.994.60690.366
0.9996.916930.905

这张表最该注意的是第二列。想让一条信息活过 100 步,遗忘门必须输出 0.99,对应的预激活值是 ln(0.99/0.01)=4.60\ln(0.99/0.01) = 4.60——一个相当大的数。而门的预激活默认从 0 附近随机初始化开始(σ(0)=0.5\sigma(0) = 0.5,半衰期 1 步),网络得靠梯度把它一路推到 4.6 以上。可是要学会"这条记忆该保住",前提是长程梯度能传回来;而长程梯度能传回来,前提是门已经开着。这是个自举困境。

这正是把遗忘门偏置初始化为 1 或 2 这条实践建议的来历(Jozefowicz 等人 2015 年那次大规模架构比较把它列为关键设置:加上它之后,LSTM 就与所有被考察的变体——包括 GRU——打成平手)。σ(1)=0.731\sigma(1) = 0.731σ(2)=0.881\sigma(2) = 0.881,半衰期分别只有 2.2 步和 5.5 步,听起来仍然很短。但关键不在这个初值本身够不够长,而在于它把门推离了 σ\sigma 的中点,给梯度一个非零的起点继续往上推。初始化的作用是打破自举困境,不是直接给出答案。

由此可以说清 LSTM 相对标准 RNN 的真正改进在哪里:标准 RNN 的乘数 WhW_h所有时间步共享的一个固定参数,一旦它的谱半径不合适,整条序列一起完蛋;LSTM 的乘数 ftf_t逐时间步、逐维度按当前输入算出来的,可以在读到一个句号时把一部分维度的 $f$ 关到 0.1、同时把另一部分维度稳稳保持在 0.99。同一个网络里可以并存半衰期 1 步和半衰期 700 步的通道。门控的含义不是"缓解了梯度消失",而是把衰减率从一个全局超参变成了一个逐步可控的变量

序列到序列(Seq2Seq)架构

2014 年,苏茨克维尔(Sutskever)等人提出 Seq2Seq 架构,彻底改变了机器翻译:

编码器 RNN:输入序列 → 上下文向量 c
解码器 RNN:上下文向量 c → 输出序列
```

编码器将可变长度的输入序列压缩为固定长度的上下文向量;解码器将其"翻译"为输出序列。这个框架被用于机器翻译、文本摘要、对话系统等几乎所有序列到序列任务。

注意力机制(Attention,Bahdanau et al., 2015):发现固定长度的上下文向量是瓶颈,允许解码器在每一步"注意"编码器的不同输出位置,大幅提升了长序列翻译质量。这成为 Transformer 的前身。

主要应用领域

任务典型架构
语言模型(文本生成)单向 LSTM
机器翻译Seq2Seq + Attention
语音识别双向 LSTM + CTC 损失
情感分析双向 LSTM
时间序列预测LSTM / GRU
音乐生成LSTM(如 Magenta)

双向 RNN 与训练技巧

双向 RNN(BiRNN):标准 RNN 只能看到过去的信息。对于非实时任务(如情感分析、阅读理解),整个序列都已知,可以同时训练两个 RNN——一个从左到右,一个从右到左——将两个方向的隐状态拼接,让每个位置都能看到"前后文":

ht=RNN(xt,ht1),ht=RNN(xt,ht+1)\overrightarrow{h}_t = \text{RNN}(x_t, \overrightarrow{h}_{t-1}), \quad \overleftarrow{h}_t = \text{RNN}(x_t, \overleftarrow{h}_{t+1}) ht=[ht;ht]h_t = [\overrightarrow{h}_t; \overleftarrow{h}_t]

双向 LSTM 在序列标注(命名实体识别、词性标注)上是深度学习时代的标准模型,BERT 在本质上也可以看作全双向的"软注意力 LSTM"。

梯度裁剪(Gradient Clipping):RNN 训练中梯度爆炸可以通过限制梯度范数来应对——当 L>threshold\|\nabla L\| > \text{threshold},将梯度等比缩小到阈值:

ggthresholdgg \leftarrow g \cdot \frac{\text{threshold}}{\|g\|}

这是训练 RNN 的标准技巧,由 Pascanu 等人(2013)系统化研究。

训练现场:教师强制、曝光偏差与截断 BPTT

教师强制(Teacher Forcing):训练一个生成式 RNN 时,第 $t$ 步的输入用什么?可以用模型自己在第 $t-1$ 步的预测,也可以用真实的第 $t-1$ 个词。几乎所有实现都选后者——因为这样每一步的输入都是干净的,整条序列的损失可以一次算完,训练又快又稳。

代价是训练与推理的输入分布不一致:训练时模型只见过正确的前缀,推理时它必须在自己生成的、可能已经出错的前缀上继续往下走。一旦第 3 个词错了,第 4 步的输入就落进训练中从未出现过的区域,误差会自我放大。这个现象叫曝光偏差(Exposure Bias)

Bengio 等人在 NeurIPS 2015 提出的计划采样(Scheduled Sampling)是最直接的修补:训练时以概率 ϵ\epsilon 用真实词、以 1ϵ1-\epsilon 用模型自己的预测,ϵ\epsilon 随训练步数从 1 逐渐退火下去,让模型在训练后期就开始适应自己的输出。这类方法确实有用,但采样这一步打断了梯度路径,引入了新的偏差;曝光偏差至今没有既干净又通用的解法。今天的大语言模型仍然是纯教师强制预训练,靠后续的对齐阶段间接缓解。

截断 BPTT(Truncated BPTT):文档级序列可能有上万个 token,把整条展开做反向传播既存不下也不必要——上面那张 wTw^T 表已经说明,超过若干十步的梯度贡献本就趋于零。工程做法是把序列切成固定长度的窗口,隐状态跨窗口向前传递(保留信息),但梯度在窗口边界截断(不再回传)。窗口长度是一个明确的权衡:太短学不到跨窗口依赖,太长则显存与单步时间线性上升。语言模型上的常见取值是几十步的量级。

GNMT:LSTM 工程的顶点。谷歌 2016 年的神经机器翻译系统把这套东西推到了极限——8 层编码器(第 1 层双向、其余 7 层单向)加 8 层解码器,层间带残差连接,每层放在一块独立 GPU 上做模型并行,梯度按 L2 范数裁剪到 5.0;论文报告训练单个语言对用了 96 块 NVIDIA K80 GPU、约一周时间。把这套配置和一年后 Transformer 论文里"8 块 P100、12 小时"的基础模型摆在一起,2017 年那次架构切换为什么不可逆就很清楚了:不是 LSTM 效果不行,而是它的串行结构让每一分算力都用得更贵

代价与争议

Transformer 的挑战:在大多数 NLP 任务上,Transformer 已经全面超越 RNN/LSTM,因为它支持完全并行训练、能建模任意长距离依赖。RNN 是序列性的,不易并行化,训练速度远慢于 Transformer。

仍有价值的场景:在低延迟在线推理(RNN 逐步处理新输入,无需重新计算所有历史)和资源受限设备(参数量少于 Transformer)上,RNN 仍有优势。2024 年后,Mamba(基于选择性状态空间模型)等新架构试图结合 RNN 的推理效率与 Transformer 的表达能力。

理论理解不完整:为什么 LSTM 的门控机制如此有效?为什么某些任务用 LSTM 而非 Transformer 更好?这些问题没有完整的理论解释。

2024 年的复归浪潮:把 RNN 判为历史的说法,在 2024 年被系统性地挑战了三次。Mamba(Gu & Dao,COLM 2024)用选择性状态空间把循环改写成可并行扫描的形式;xLSTM(Beck、Hochreiter 等人,NeurIPS 2024)由 LSTM 原作者之一领衔,用 sLSTM 与 mLSTM 两种模块把门控 RNN 重新推到十亿参数规模;Feng 等人那篇标题就是质问的《Were RNNs All We Needed?》(2024)走得最远——他们把 LSTM 与 GRU 里所有依赖前一时刻隐状态的门全部去掉,得到的 minLSTM / minGRU 可以用并行前缀扫描一次算完整条序列,在长度 512 的序列上训练比原版快约 175 倍,测试损失与 Mamba、Transformer 相当。

这条线索指向一个相当清楚的技术判断:RNN 当年的致命伤不是"记不住",而是"训练时不能并行"。而不能并行的根源是门控依赖经过非线性变换的前一隐状态——一旦把这个依赖去掉、改成只依赖当前输入,循环就退化为线性递推,可以用并行前缀扫描在 O(logT)O(\log T) 的深度上算完。序列建模领域绕了七年,回头发现问题出在一个具体的结构选择上,而不是"循环"这个想法本身。

跨域连接

  • 线性代数:梯度消失与爆炸整件事可以归约成一句话:反复乘同一个矩阵会发生什么。答案由最大奇异值决定,稳定区间窄到只有一个点。这与马尔可夫链收敛到平稳分布、幂法收敛到主特征向量是同一件数学,只是这里我们不希望它收敛。
  • 信号处理:一旦去掉门对前一隐状态的非线性依赖,循环就退化成线性递推,可以用并行前缀扫描一次算完。这正是近年状态空间模型复归的技术要点:不是循环这个想法错了,而是那一处非线性依赖挡住了并行,训练成本因此高出一个层级。
  • 动态规划:随时间反向传播本质上是在时间轴上做一次反向的动态规划,每一步复用后一步的结果。截断就是给这个递推人为设一个边界条件:窗口内梯度照传,窗口外直接归零,而隐状态仍向前传递——正确性被牺牲,因为超过若干十步的贡献本就趋于零。
  • 记忆系统:细胞状态常被类比成工作记忆的持续激活,这一类比只能到功能层面。门控做的是把衰减率从一个全局超参变成逐步逐维可调的变量,而生物记忆还涉及巩固、重编码与提取时的重构,这些在门控里没有对应物。
  • 注意力与 Transformer:注意力让任意两个位置直接交互,看起来解决的是"记不住",实际更致命的是并行性。循环的每一步都要等上一步算完,同样的算力被摊薄——架构切换的直接理由是单位算力的产出,而不是效果上限。

参考文献

  • Hochreiter, S. & Schmidhuber, J. Long Short-Term Memory. Neural Computation 9(8), 1735–1780 (1997).
  • Sutskever, I., Vinyals, O. & Le, Q. V. Sequence to Sequence Learning with Neural Networks. NeurIPS 2014. arXiv:1409.3215.
  • Bahdanau, D., Cho, K. & Bengio, Y. Neural Machine Translation by Jointly Learning to Align and Translate. ICLR 2015. arXiv:1409.0473.
  • Cho, K. et al. Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation. EMNLP 2014. arXiv:1406.1078.
  • Pascanu, R., Mikolov, T. & Bengio, Y. On the Difficulty of Training Recurrent Neural Networks. ICML 2013. arXiv:1211.5063.(梯度爆炸/消失的系统分析与梯度裁剪)
  • Jozefowicz, R., Zaremba, W. & Sutskever, I. An Empirical Exploration of Recurrent Network Architectures. ICML 2015.(遗忘门偏置初始化为 1 的来源)
  • Bengio, S., Vinyals, O., Jaitly, N. & Shazeer, N. Scheduled Sampling for Sequence Prediction with Recurrent Neural Networks. NeurIPS 2015. arXiv:1506.03099.
  • Wu, Y. et al. Google's Neural Machine Translation System: Bridging the Gap between Human and Machine Translation. arXiv:1609.08144 (2016).(8+8 层架构、梯度裁剪 5.0、96 块 K80 的训练规模)
  • Gu, A. & Dao, T. Mamba: Linear-Time Sequence Modeling with Selective State Spaces. COLM 2024. arXiv:2312.00752.
  • Beck, M. et al. xLSTM: Extended Long Short-Term Memory. NeurIPS 2024. arXiv:2405.04517.
  • Feng, L. et al. Were RNNs All We Needed? arXiv:2410.01201 (2024).(minLSTM / minGRU 与 175 倍训练加速)

延伸阅读

  • Karpathy, A. The Unreasonable Effectiveness of Recurrent Neural Networks. 2015.(char-RNN 的经典科普,附可运行代码)
  • Olah, C. Understanding LSTM Networks. 2015.(门控结构的图解,与本文"门控在具体数值下做了什么"一节互补)
  • Goodfellow, I., Bengio, Y. & Courville, A. Deep Learning. MIT Press, 2016.(第 10 章系统讲序列建模与 BPTT)