跳到主要内容

这一章解决一个问题:题目不是一个向量,而是有先后顺序的一串,长度还不固定。 解法只加了一样东西——一条从上一时刻通向下一时刻的回路;这一章的全部交易就是: 用这条回路换来记忆,代价是误差必须沿着时间链一步步往回走。

循环网络:给网络加一点记忆

1. 这一章讲什么

三件事: 前馈网络处理序列到底缺什么(不留历史、吃定长输入); 三种补记忆的办法为什么收敛到循环连接; 以及循环网络怎么用(四种应用模式)、怎么训(误差沿时间回传)。

它在全书链条里的位置: 第 13、14 章的结构先验管的是空间数据; 序列是另一类先验:有先后、长度可变。这一章把记忆机制立起来, 第 16 章立刻面对它的病根(间隔一拉长梯度就没命),再由门控接住。

需要第 10、11 章。

2. 顶层全景

输入 x1 x2 x3 ……
│ │ │
▼ ▼ ▼
h₀ ──▶ [h1] ─ [h2] ─ [h3] ── … 每个时刻:hₜ = f(hₜ₋₁, xₜ)
│ │ │ 全程共用同一组 U、W、b
▼ ▼ ▼
输出 y1 y2 y3

训练 = 把上图沿时间拉直 → 一个很深的前馈网
→ 第 11 章的反向传播照做,只是各时刻的梯度要全部加起来

一句话链条: 序列的两个麻烦(变长、依赖历史)→ 三条补记忆的路里, 循环连接是唯一不预选窗口的 → 展开后就是共享参数的深层前馈网 → 反向传播照旧,但误差要沿时间往回传——这既是能力来源, 也是下一章所有麻烦的来源。

3. 前馈网络处理不了序列

两个具体缺口。 其一,前馈网络是一种静态网络,不具备短期记忆能力1: 输入一进来就走完前向,内部不留任何「之前看到过什么」。 给它一句话,只能把整句摊平成定长的输入向量——长了截断、短了补零, 而且顺序信息在这一步就被抹掉了。

其二,任务本身要求带历史地看:文本、语音、一般时间序列都是长度可变的数据2, 当前的答案往往取决于前面出现过的内容。「它」指的是谁、这句话是不是反问, 单看这两个字根本答不了。

所以问题变成:怎么让网络记住最近发生的事。

4. 三种加记忆的办法

书里排了三条路,按记忆方式的差异排列2:

  • 延时神经网络(TDNN):给神经元配延时器,存最近 K 个时刻的活性值,K 预先定死。短板:只看固定窗口

  • 自回归(拿自己的历史预测自己)模型(AR)/ NARX:用输出自己(和外部输入)的历史预测自己,延时器记最近 K 步。短板:窗口大小是超参数

  • 循环神经网络(英文叫 RNN):带自反馈的神经元,hₜ = f(hₜ₋₁,xₜ),能处理任意长度的时序数据3。本章主角

延时的想法并不陌生——书的边注点破了它: 对序列输入来说,TDNN 就相当于卷积(在一维信号上滑窗加权求和)4。 但两条「延时器」路线有同一个天花板:K 定几步就只能看几步

循环连接是第三条路,也是唯一不给窗口设上限的3: 记忆不再是一格一格的死窗口,而是一个可以被反复改写的容器。

5. 简单循环网络:一条更新公式

最小可行版本叫简单循环网络(SRN)[Elman, 1990]。核心概念只有两个。

隐状态:每个时刻网里的那份「到目前为止看到了什么」。 这个词借自动力系统——数学上用一个函数描述系统状态如何随时间变化的那套理论; hₜ 在文献中也直接叫状态或隐状态5

更新公式:zₜ = U·hₜ₋₁ + W·xₜ + b,hₜ = f(zₜ)6。 拆开读:新记忆 = 上一时刻的记忆经 U 加权 + 当前输入经 W 加权,再过一道非线性 f (Logistic 或 Tanh)。U 是状态-状态权重(D×D),W 是状态-输入权重(D×M), f 通常取 Logistic 或 Tanh 函数6所有记忆都浓缩在这两个矩阵怎么转里面。

注意一件小事但分量很重:U 和 W 在每个时刻都是同一组—— 没有任何一处为「时刻 5」单独配参数。

6. 按时间展开:它其实是一个深层网络

这是理解本章剩下的全部钥匙。 把循环网络沿时间轴摊开——每经过一个时刻算「一层」——得到的就是一个 在时间维度上共享参数的深层前馈网络7:层数等于序列长度 T, 所有「层」共用同一组 U、W、b。

这个视角一口气回答两件事:

  • 为什么能处理变长输入? 层数跟着输入走,长句多层、短句少层,结构本身不变;
  • 怎么训练? 第 11 章的反向传播拿来就用——账目在第 8 节算。

顺带一句理论定位。书里给了两条表达能力定理: 足够多 Sigmoid 型隐藏神经元的完全连接循环网络,能以任意精度近似一大类非线性动力系统8; 甚至能模拟所有图灵机(图灵完备)9但书里立刻画线:理论表达能力属补充阅读,和可学习性、计算效率、泛化能力不是同一层面的问题 ——这两条定理都不保证我们训得出来,这一点正是下一章的全部主题。

7. 四种用法:输出接在哪、损失算在哪

序列任务看着五花八门,归纳起来只有四类10,区别全在输入输出的形状:

  • 序列分类(多对一):取末时刻 h_T 当整句表示(或全时刻平均),交给分类器11——文本分类

  • 序列标注(多对多,等长对齐):每个 hₜ 各过一个分类器,逐位出标签——词性(名词/动词这类)标注

  • 自回归序列建模:一条序列逐步预测下一符号,hₜ 读出下一个符号,再把预测喂回输入——语言模型(NTP)

  • 条件序列生成:一条序列先压入编码器(负责读取并压缩的一方)读到末状态。

  • 再由解码器(负责生成的一方)自回归展开(<EOS> 收尾)——机器翻译

第四种值得多说一句。编码器-解码器:一个 RNN 把输入序列读到末状态, 另一个 RNN 从那里开始逐个生成输出符号12。 书里给这种结构标了一个日后极重要的批评: 这类模型要把整个输入序列压缩为一个或少数几个状态向量, 输入很长时容易形成信息瓶颈;这一局限促成了注意力机制, 让解码器能在生成过程中动态访问编码器不同位置的信息13 ——第 20 章的伏笔在这里埋下。

自回归模式的训练与生成不是同一件事。 以语言模型为例: 训练时常见做法是把真实序列整体右移一位当输入,让模型在每个位置预测下一个真实符号—— 这叫教师强制,好处是所有位置的损失可以并行计算,早期错误也不会污染后面的训练信号14但生成时没有真实历史可喂,模型只能拿自己上一步的预测当下一步的输入, 一步错了,后面就在错误历史上继续展开。 这种训练条件与生成条件的不一致叫暴露偏差15。 (第 21 章 Transformer 的「从前缀到采样」走的是同一条数据流(数据怎么一步步流过模型),这个问题原样跟过去。)

8. BPTT:误差怎么沿时间往回传

思路一句话:展开之后就是深层前馈网,第 11 章的反向传播照做16。 设损失为各时刻损失之和 ℒ = Σ ℒₜ,那么整个序列对参数的梯度, 就是各时刻损失的偏导数之和17——一组参数被一整段时间共同使用, 它的梯度就得把全时间的贡献收齐。

要算这份总账,需要一个新角色:

δ_{t,k} ≜ ∂ℒ_t/∂z_k —— t 时刻的损失,对 k 时刻净输入的导数

沿时间往回推:δ_{t,k} = diag(f′(z_k))·Uᵀ · δ_{t,k+1}

直观地说:误差信号从时刻 t 沿时间反向传播到时刻 k, 每经过一步都乘以 diag(f′(zₖ))·Uᵀ——Uᵀ 来自前向公式对 h 的转置关系, diag(f′) 是激活函数在那一时刻的逐元素斜率18。 把这个递推展开到底再代回参数梯度,就得到双求和的形式: ∂ℒ/∂U = Σₜ Σₖ δ_{t,k}·hᵀₖ₋₁(t 从 1 到 T,k 从 1 到 t)19

主走查:三个时刻,正向传一遍,误差送回去两步

设定: 隐状态只取 1 维(D=1,U、W 都是单个数);输入 x = [1, 0, 1]; U=0.5、W=1、b=0;f=tanh;h₀=0。 损失只在最后时刻产生:L₃ = ½(h₃−y₃)²,y₃=0——目标值是我们为演示定的, 原书没给这些数字;以下数值全部按公式实算,保留四位。

第一步:正向,逐时刻写净输入与隐状态(zₜ = 0.5·hₜ₋₁ + xₜ):

t=1: z₁ = 0.5×0 + 1 = 1.0000 → h₁ = tanh(1.0000) = 0.7616
t=2: z₂ = 0.5×0.7616 + 0 = 0.3808 → h₂ = tanh(0.3808) = 0.3633
t=3: z₃ = 0.5×0.3633 + 1 = 1.1817 → h₃ = tanh(1.1817) = 0.8282

看清一件事:x₂=0 不代表这一刻无事发生——0.5×h₁ 把第一步的信息带到了第二步。 这就是记忆的运输方式:一路上全是 U 在搬运。

第二步:出口误差。 L₃ = ½×0.8282² ≈ 0.343; δ₃,₃ = (h₃−y₃)×(1−tanh²z₃) = 0.8282×(1−0.6859) = 0.8282×0.3141 ≈ 0.2601

第三步:往回送两步(每步乘 diag(f′)·Uᵀ,一维情形就是一个数 f′×0.5):

δ₃,₂ = (1−0.3633²) × 0.5 × 0.2601 = 0.8679×0.1300 ≈ 0.1128
δ₃,₁ = (1−0.7616²) × 0.5 × 0.1128 = 0.4200×0.0564 ≈ 0.0237

离损失越远,误差缩得越小:0.26 → 0.11 → 0.02。 每一步的缩小率 ≈ f′×0.5,这组数里最大不过 0.43——每一次都是「乘一个小于 1 的数」。 这不是巧合也不是数不好选,这正是下一章长程依赖问题的雏形: 任何一项远端贡献都要被连乘几十次同样的因子。

第四步:参数梯度,全时刻求和(∂ℒ/∂U = Σₖ δ₃,ₖ·hₖ₋₁):

k=3: δ₃,₃ × h₂ = 0.2601 × 0.3633 = 0.0945
k=2: δ₃,₂ × h₁ = 0.1128 × 0.7616 = 0.0859
k=1: δ₃,₁ × h₀ = 0.0237 × 0 = 0
合计 ∂ℒ/∂U ≈ 0.1804

第三项为零不是 bug——h₀=0,时刻 1 对这组参数拿不出任何证据。 同时这也演示了「展开层求和」:U 只有 1 个数,却收到来自三个时刻的三份梯度, 因为展开后的三层共用这一个参数。W 的梯度同理是 Σₖ δ₃,ₖ·xₖ, 同样的三行就能算完。

9. 反方向:RTRL

书并列了另一个算法作对照:**实时循环学习(RTRL)**不从后往前回传误差, 而是在前向计算的同时维护「状态对参数的偏导数」,随时可更20。 取舍清楚:BPTT 计算量小(输出维度通常远低于输入维度), 但要保存整段中间状态,空间开销高;RTRL 形式上适合在线学习或无限序列任务, 但完整版要维护的东西太多,实际多用近似或截断版本21。 主干仍是 BPTT。

10. 作者的判断与证据

书里给了推导的: BPTT 全套——误差项递推、参数梯度的双求和式1819; 四类应用模式及其公式化10;教师强制的收益(并行计算、隔离早期错误) 与暴露偏差的代价写在同一段里1415

书里划了线的: 表达能力两条定理注明属理论补充, 「并不意味着有限规模、可训练的循环神经网络在实际中都能有效求解任意可计算问题」89; RTRL 说明确指出完整版开销高、实际要用近似版本21

书里提前认账的: 编码器-解码器的信息瓶颈——整条输入压成少数几个向量, 长输入必堵;注意力动机在此埋下13

边注里的实物知识: TDNN 对序列输入相当于卷积4, 结构先验跨数据类型通用,这是全书反复出现的模式在序列上的第一次亮相。

11. 边界与局限

本章的循环网络还不敢碰长序列的远处依赖。 机制和训练方法立住了, 但「为什么远处学不动」到下一章才回答;第 8 节里每步都在乘的那个小于 1 的因子, 就是病根的形状。

信息瓶颈在本章内无解。 批评指出了,解药(注意力)在第 20 章13

堆叠与双向两种加深手段本章只点名不展开,它们与门控同属「补救」主题, 第 16 章一并讲。

12. 可带走的

  1. 前馈网络是静态的:不留历史、吃定长输入,天然不适合时序数据;
  2. 三种加记忆的路子:延时器(TDNN≈对序列做卷积)、自回归(NARX)、循环连接; 前两种都要预选窗口大小,循环连接不用;
  3. 隐状态 + 一条更新公式就是最小循环网络:hₜ = f(U·hₜ₋₁+W·xₜ+b);
  4. 按时间展开 = 时间上共享参数的深层前馈网:变长输入有了统一解释,反向传播直接沿用;
  5. 四种用法按输出形状分:分类取末状态、标注逐位出、自回归逐步预测、条件生成编-解码;
  6. 训练喂真历史(教师强制),生成喂自己的历史——这个错位叫暴露偏差,Transformer 也带着;
  7. BPTT 回传每步都乘 diag(f′)Uᵀ,参数梯度等于全时刻贡献之和;
  8. 编码器把整条输入压成几个向量,长输入必成瓶颈——这是注意力机制的直接动机;
  9. 表达能力定理(通用近似、图灵完备)说的都是「存在」,不保证「训得动」;
  10. RTRL 反其道而行(前向算梯度):在线场景友好,开销太大,实践罕见。

13. 原文地图

主题原书章原文位置
前馈无记忆第6章 循环神经网络text/07-ch06.txt:33(搜「不具备这种记忆能力」)
三种办法与 TDNN/NARX第6章 循环神经网络text/07-ch06.txt:34(搜「三种方法」) · text/07-ch06.txt:44(搜「延时神经网络是在前馈网络」) · text/07-ch06.txt:59(搜「AutoRegressive Model,AR」) · text/07-ch06.txt:69(搜「NARX」)
TDNN≈卷积(边注)第6章 循环神经网络text/07-ch06.txt:44(搜「延时神经网络是在前馈网络」,边注在同段右栏)
循环网络定义第6章 循环神经网络text/07-ch06.txt:81(搜「通过使用带自反馈的」) · text/07-ch06.txt:82(搜「任意长度的时序数据」)
隐状态第6章 循环神经网络text/07-ch06.txt:106(搜「隐状态(Hidden State」)
SRN 更新公式第6章 循环神经网络text/07-ch06.txt:120(搜「Simple Recurrent Network」) · text/07-ch06.txt:125(搜「不仅和当前时刻的输入」) · text/07-ch06.txt:133(搜「状态-状态权重矩阵」)
展开/共享参数第6章 循环神经网络text/07-ch06.txt:108(搜「按时间展开」) · text/07-ch06.txt:140(搜「时间维度上权值共享」)
表达能力两定理第6章 循环神经网络text/07-ch06.txt:167(搜「循环神经网络的通用近似定理」) · text/07-ch06.txt:241(搜「所有的图灵机都可以」)
四种模式总表第6章 循环神经网络text/07-ch06.txt:252(搜「归纳为四类」) · text/07-ch06.txt:271(搜「Sequence Classification」) · text/07-ch06.txt:306(搜「Sequence Labeling」) · text/07-ch06.txt:329(搜「Autoregressive Sequence Modelling」) · text/07-ch06.txt:370(搜「Conditional Sequence Generation」)
序列表示取法第6章 循环神经网络text/07-ch06.txt:276(搜「最终表示(或」) · text/07-ch06.txt:297(搜「所有状态进行平均」)
教师强制/暴露偏差第6章 循环神经网络text/07-ch06.txt:361(搜「Teacher Forcing」) · text/07-ch06.txt:364(搜「Exposure Bias」)
信息瓶颈边注第6章 循环神经网络text/07-ch06.txt:398(搜「压缩为一个或」)
BPTT第6章 循环神经网络text/07-ch06.txt:447(搜「Back-Propagation Through Time」) · text/07-ch06.txt:495(搜「每经过一步都乘以」)
梯度求和第6章 循环神经网络text/07-ch06.txt:436(搜「偏导数之和」) · text/07-ch06.txt:453(搜「展开层」)
RTRL第6章 循环神经网络text/07-ch06.txt:582(搜「两种算法比较」) · text/07-ch06.txt:586(搜「在线学习或无限序列」)

Footnotes

  1. 出处:「第6章 循环神经网络」第 31 至 33 段(text/07-ch06.txt:33,搜「不具备这种记忆能力」)。 原文指出前馈网络是一种静态网络,不具备短期记忆能力。

  2. 出处:「第6章 循环神经网络」第 34 段(text/07-ch06.txt:34,搜「三种方法」)。 三条路分别为延时神经网络、自回归模型及其扩展 NARX、循环神经网络。 2

  3. 出处:「第6章 循环神经网络」第 80 至 82 段(text/07-ch06.txt:82,搜「任意长度的时序数据」)。 2

  4. 出处:「第6章 循环神经网络」第 44 段(text/07-ch06.txt:44,搜「延时神经网络是在前馈网络」)。 同段右侧边注写明:「对于序列输入来讲,延时神经网络就相当于卷积神经网络。」 (边注因排版跨行,无法整句检索。) 2

  5. 出处:「第6章 循环神经网络」第 106 段(text/07-ch06.txt:106,搜「隐状态(Hidden State」)。 动力系统(e.g.,钟摆晃动、台球轨迹)的解释在同段左侧边注。

  6. 出处:「第6章 循环神经网络」第 125 段(text/07-ch06.txt:125,搜「不仅和当前时刻的输入」) 与第 133 段(text/07-ch06.txt:133,搜「状态-状态权重矩阵」)。 更新公式为式(6.5)-(6.7):zₜ=Uhₜ₋₁+Wxₜ+b,hₜ=f(zₜ)。 2

  7. 出处:「第6章 循环神经网络」第 108 段(text/07-ch06.txt:108,搜「按时间展开」) 与第 140 段(text/07-ch06.txt:140,搜「时间维度上权值共享」)。

  8. 出处:「第6章 循环神经网络」第 167 段(text/07-ch06.txt:167,搜「循环神经网络的通用近似定理」), 定理 6.1[Haykin, 2009];本小节边注声明「属于对正文主线的补充阅读」(第 163 段)。 2

  9. 出处:「第6章 循环神经网络」第 241 段(text/07-ch06.txt:241,搜「所有的图灵机都可以」), 定理 6.2[Siegelmann et al., 1991];原文随即提醒这不是说实际可训练的网络都能有效求解任意问题。 2

  10. 出处:「第6章 循环神经网络」第 252 段(text/07-ch06.txt:252,搜「归纳为四类」), 及表 6.1 与各小节(271、306、329、370 段)。 2

  11. 出处:「第6章 循环神经网络」第 276 段(text/07-ch06.txt:276,搜「最终表示(或」) 与第 297 段(text/07-ch06.txt:297,搜「所有状态进行平均」)。

  12. 出处:「第6章 循环神经网络」第 370 段(text/07-ch06.txt:370,搜「Conditional Sequence Generation」)。

  13. 出处:「第6章 循环神经网络」第 398 段(text/07-ch06.txt:398,搜「压缩为一个或」)。 这是原书边注:「这类模型通常要把整个输入序列压缩为一个或少数几个状态向量, 因此当输入很长时容易形成信息瓶颈……参见第 8.2 节。」 2 3

  14. 出处:「第6章 循环神经网络」第 361 段(text/07-ch06.txt:361,搜「Teacher Forcing」)。 2

  15. 出处:「第6章 循环神经网络」第 364 段(text/07-ch06.txt:364,搜「Exposure Bias」)。 2

  16. 出处:「第6章 循环神经网络」第 447 段(text/07-ch06.txt:447,搜「Back-Propagation Through Time」)。

  17. 出处:「第6章 循环神经网络」第 436 段(text/07-ch06.txt:436,搜「偏导数之和」)。

  18. 出处:「第6章 循环神经网络」第 495 段(text/07-ch06.txt:495,搜「每经过一步都乘以」)。 原文:「误差信号从时刻 t 沿时间反向传播到时刻 k,每经过一步都乘以 diag(f′(zₖ))Uᵀ……」 2

  19. 出处:「第6章 循环神经网络」第 512 段(text/07-ch06.txt:512,搜「随时间进行反向传播算法的示例」), 参数梯度双求和为式(6.41)-(6.43)。 2

  20. 出处:「第6章 循环神经网络」第 582 段(text/07-ch06.txt:582,搜「两种算法比较」) 与第 586 段(text/07-ch06.txt:586,搜「在线学习或无限序列」)。

  21. 出处:「第6章 循环神经网络」第 584 段(text/07-ch06.txt:584,搜「计算量会更小」) 与第 587 段(text/07-ch06.txt:587,搜「近似或截断」)。 2