L03: Backpropagation and Neural Networks

Week 2 · Tue Jan 13 2026 08:00:00 GMT+0800 (中国标准时间)

进度: 0/22 (0%)
下载 PDF
/ 0
100%
正在加载 PDF...

L03: Backpropagation and Neural Networks

Slides

中英交替版(推荐)

L03 双语 (PDF)

英文原版

L03 EN (PDF)

中文翻译版

L03 ZH (PDF)

核心知识点

1. 词向量评估回顾(Recap from L02)

Slide 1 Slide 2 Slide 3 Slide 4 Slide 5 Slide 6 Slide 7 Slide 8 Slide 9 Slide 10 Slide 11
  • 内在评估 vs 外在评估
    • 内在:特定子任务上评估(快速,但与真实任务关联不明确)
    • 外在:在真实任务上评估(耗时,但直接反映效果)
  • 词类比(Word Analogies):d=argmaxi(xbxa+xc)Txixbxa+xcd = \arg\max_i \frac{(x_b - x_a + x_c)^T x_i}{\|x_b - x_a + x_c\|}
  • 词相似度:WordSim353 数据集,GloVe 在多个基准上表现优异
  • GloVe 可视化:性别、皇室等语义关系在向量空间中呈现平行结构

📐 词类比公式完整推导

变量定义

  • xax_a = 词 aa 的词向量(如 “man”)
  • xbx_b = 词 bb 的词向量(如 “woman”)
  • xcx_c = 词 cc 的词向量(如 “king”)
  • dd = 目标词(如 “queen”)的向量索引
  • \|\cdot\| = L2 范数(向量的欧几里得长度)

推导过程

第 1 步:语义关系 = 向量差。“man → woman” 这个关系可以用 xbxax_b - x_a 表示。训练良好的词向量满足 xbxaxdxcx_b - x_a \approx x_d - x_c,即”性别关系”在向量空间中是一个稳定的偏移方向。

第 2 步:目标向量估计。将关系迁移到 xcx_c,估计 dd 的向量应当接近:

x^d=xbxa+xc\hat{x}_d = x_b - x_a + x_c

第 3 步:在词汇表中搜索最近邻。直接用欧几里得距离不够稳定(向量长度不一致),改用余弦相似度

cos(x^d,xi)=x^dTxix^dxi\cos(\hat{x}_d, x_i) = \frac{\hat{x}_d^T x_i}{\|\hat{x}_d\| \cdot \|x_i\|}

第 4 步:当所有 xix_i 均已归一化(xi=1\|x_i\| = 1)时,分母中 xi\|x_i\| 可省略:

d=argmaxi(xbxa+xc)Txixbxa+xcd = \arg\max_i \frac{(x_b - x_a + x_c)^T x_i}{\|x_b - x_a + x_c\|}

即对查询向量归一化后,直接做点积排名即可。

直觉:词向量空间是”语义坐标系”。不同词对之间的关系对应方向,语义相似 = 方向相同。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定(2维简化版):

向量
man (xax_a)[1.0, 0.0][1.0,\ 0.0]
woman (xbx_b)[0.0, 1.0][0.0,\ 1.0]
king (xcx_c)[0.9, 0.2][0.9,\ 0.2]
queen (待找)[?, ?][?,\ ?]

计算

  1. 计算偏移向量:x^d=xbxa+xc=[0,1][1,0]+[0.9,0.2]=[0.1, 1.2]\hat{x}_d = x_b - x_a + x_c = [0,1] - [1,0] + [0.9,0.2] = [-0.1,\ 1.2]
  2. 归一化:x^d=0.01+1.44=1.451.204\|\hat{x}_d\| = \sqrt{0.01 + 1.44} = \sqrt{1.45} \approx 1.204,归一化后 [0.083, 0.997]\approx [-0.083,\ 0.997]
  3. 若词汇表中 queen 的向量为 [0.05,0.99][0.05, 0.99](已归一化),则点积 0.083×0.05+0.997×0.990.983\approx -0.083 \times 0.05 + 0.997 \times 0.99 \approx 0.983,得分最高

结果:queen 得分最接近查询向量,被正确检索出。

💡 为什么这样做?

词向量空间的核心假设是:语义关系 = 方向向量。“性别关系”、“国家-首都关系”、“时态关系”等都对应向量空间中特定的方向。词类比本质上是:沿着已知关系的方向,在新的起点出发,找落脚点

类比日常:你知道”北京在中国的东部”这个方向,再加上”法国”,就能猜到”巴黎在法国的中部偏北”——同样的逻辑。

⚠️ 常见误区

  1. 误区:直接用欧几里得距离找最近邻更直观 → 正确:词向量的模长不统一,高频词向量往往更长;余弦相似度对方向更敏感,与训练目标更一致
  2. 误区:分子分母的 xbxa+xc\|x_b - x_a + x_c\| 可以省略 → 正确:当比较不同查询时需要归一化;若只是对同一查询排名,分子的归一化不影响 argmax\arg\max 结果,但规范写法应保留
  3. 误区:词类比评估 = 词相似度评估 → 正确:两者测量不同维度,类比测结构关系,相似度测语义距离

2. 深度学习分类:命名实体识别(NER)

Slide 12 Slide 13 Slide 14 Slide 15 Slide 16 Slide 17 Slide 18 Slide 19 Slide 20 Slide 21
  • 任务:在文本中找到并分类命名实体(PER/LOC/ORG/DATE 等)
  • 方法:窗口分类(Window Classification)
    • 将中心词及其上下文窗口内的词向量拼接为输入 xwindowR5dx_{window} \in \mathbb{R}^{5d}
    • 用二分类或多分类逻辑回归/神经网络判断
  • 示例:判断 “Paris” 是否为 LOCATION
    • x=[xmuseums,xin,xParis,xare,xamazing]Tx = [x_{museums}, x_{in}, x_{Paris}, x_{are}, x_{amazing}]^T

📐 窗口分类输入构造与决策函数推导

变量定义

  • dd = 词向量维度(如 d=300d = 300
  • ww = 窗口半径(如 w=2w = 2,则窗口大小为 2w+1=52w+1 = 5
  • xtRdx_t \in \mathbb{R}^d = 位置 tt 的词向量
  • xwindowR(2w+1)dx_{window} \in \mathbb{R}^{(2w+1)d} = 窗口拼接向量
  • WRC×(2w+1)dW \in \mathbb{R}^{C \times (2w+1)d} = 分类权重矩阵(CC 为类别数)

推导过程

第 1 步:拼接(concatenate)操作。对位置 tt,取上下文窗口内所有词向量,按顺序拼接(不是求和、不是平均):

xwindow=[xtwxtw+1xtxt+w]R(2w+1)dx_{window} = \begin{bmatrix} x_{t-w} \\ x_{t-w+1} \\ \vdots \\ x_t \\ \vdots \\ x_{t+w} \end{bmatrix} \in \mathbb{R}^{(2w+1)d}

数学上等价于:xwindow=[xtwT, xtw+1T, , xtT, , xt+wT]Tx_{window} = [x_{t-w}^T,\ x_{t-w+1}^T,\ \ldots,\ x_t^T,\ \ldots,\ x_{t+w}^T]^T

第 2 步:线性分类决策函数:

y^=Wxwindow+bRC\hat{y} = W \cdot x_{window} + b \in \mathbb{R}^C

其中 WRC×(2w+1)dW \in \mathbb{R}^{C \times (2w+1)d},每一行对应一个类别的权重。

第 3 步:对二分类(是/否 LOCATION),输出层用 sigmoid:

p(LOCx)=σ(y^)=11+ey^p(\text{LOC}|x) = \sigma(\hat{y}) = \frac{1}{1 + e^{-\hat{y}}}

形状检查WW(C)×((2w+1)d)(C) \times ((2w+1)d)xwindowx_{window}((2w+1)d)((2w+1)d),乘积是 (C)(C),加偏置 (C)(C),形状一致。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定d=3d = 3,窗口大小 =3= 3w=1w=1),判断中心词是否为 LOCATION

句子:“in Paris are”,中心词 = “Paris”

向量(d=3d=3
“in” (xt1x_{t-1})[0.2,0.1,0.5][0.2, 0.1, 0.5]
“Paris” (xtx_t)[0.8,0.9,0.3][0.8, 0.9, 0.3]
“are” (xt+1x_{t+1})[0.1,0.3,0.2][0.1, 0.3, 0.2]

计算

  1. 拼接:xwindow=[0.2,0.1,0.5, 0.8,0.9,0.3, 0.1,0.3,0.2]TR9x_{window} = [0.2, 0.1, 0.5,\ 0.8, 0.9, 0.3,\ 0.1, 0.3, 0.2]^T \in \mathbb{R}^9
  2. WR1×9W \in \mathbb{R}^{1 \times 9}(二分类)= [0.1,0.2,0.1,0.5,0.4,0.3,0.0,0.1,0.2][0.1, 0.2, -0.1, 0.5, 0.4, 0.3, 0.0, 0.1, 0.2]b=0.1b = 0.1
  3. y^=Wxwindow+b=0.02+0.020.05+0.40+0.36+0.09+0+0.03+0.04+0.1=1.01\hat{y} = W \cdot x_{window} + b = 0.02 + 0.02 - 0.05 + 0.40 + 0.36 + 0.09 + 0 + 0.03 + 0.04 + 0.1 = 1.01
  4. p=σ(1.01)0.733p = \sigma(1.01) \approx 0.733(73.3% 概率是 LOCATION)

💡 为什么这样做?

窗口分类的核心问题是:孤立地看一个词,无法判断它是不是命名实体。“Washington” 可以是人名也可以是地名,但”President Washington visited”和”Washington D.C. is”语境完全不同。

拼接上下文词向量,等于把”这个词周围的语境”打包成一个大向量,让分类器同时看到局部上下文。这是 NLP 中最基础的上下文特征提取思路。

⚠️ 常见误区

  1. 误区:窗口越大越好 → 正确:窗口是超参,太大引入噪声,太小上下文不足;NER 任务通常 w=2w=2 已足够
  2. 误区:拼接 = 求和(或平均) → 正确:拼接保留了位置信息(哪个词在哪个位置),而求和/平均会丢失顺序信息
  3. 误区:每个词的向量是 one-hot → 正确:这里的 xtx_t 已经是词嵌入(低维稠密向量),不是稀疏的 one-hot 编码

3. 神经网络分类器

Slide 22 Slide 23 Slide 24 Slide 25 Slide 26 Slide 27 Slide 28 Slide 29 Slide 30 Slide 31 Slide 32 Slide 33 Slide 34
  • 传统 softmax 分类器:p(yx)=exp(Wyx)c=1Cexp(Wcx)p(y|x) = \frac{\exp(W_y \cdot x)}{\sum_{c=1}^{C} \exp(W_c \cdot x)}
    • 只能给出线性决策边界
  • 神经网络的关键区别:
    • 同时学习权重矩阵 WW分布式表示(词向量 xx
    • 多层网络 + 非线性函数 \to 非线性决策边界
  • NER 二分类网络结构:
    • xR5dx \in \mathbb{R}^{5d}(输入:5 个词的拼接向量)
    • h=f(Wx+b)h = f(Wx + b)(隐藏层 + 非线性激活)
    • s=uThs = u^T h(评分)
    • Jt(θ)=σ(s)=11+esJ_t(\theta) = \sigma(s) = \frac{1}{1 + e^{-s}}(sigmoid 输出概率)

📐 神经网络分类器完整前向传播推导

变量定义

  • xR5dx \in \mathbb{R}^{5d} = 窗口拼接词向量(输入层)
  • W(1)Rm×5dW^{(1)} \in \mathbb{R}^{m \times 5d} = 第一层权重矩阵(mm 为隐藏层维度)
  • b(1)Rmb^{(1)} \in \mathbb{R}^m = 第一层偏置
  • f()f(\cdot) = 逐元素非线性激活函数(如 tanh\tanh
  • hRmh \in \mathbb{R}^m = 隐藏层输出
  • uRmu \in \mathbb{R}^m = 输出权重向量
  • sRs \in \mathbb{R} = 标量评分

推导过程

第 1 步:线性变换。将输入投影到隐藏空间:

z(1)=W(1)x+b(1)Rmz^{(1)} = W^{(1)} x + b^{(1)} \in \mathbb{R}^m

展开矩阵乘法的第 ii 个分量:zi(1)=j=15dWij(1)xj+bi(1)z^{(1)}_i = \sum_{j=1}^{5d} W^{(1)}_{ij} x_j + b^{(1)}_i

第 2 步:逐元素非线性激活:

h=f(z(1))Rm,hi=f(zi(1))h = f(z^{(1)}) \in \mathbb{R}^m, \quad h_i = f(z^{(1)}_i)

第 3 步:输出评分(标量)。用权重向量 uu 做内积:

s=uTh=i=1muihiRs = u^T h = \sum_{i=1}^{m} u_i h_i \in \mathbb{R}

第 4 步:转化为概率(二分类用 sigmoid):

p=σ(s)=11+es(0,1)p = \sigma(s) = \frac{1}{1 + e^{-s}} \in (0, 1)

为什么需要非线性:若去掉 ff,则 s=uT(W(1)x+b(1))=(uTW(1))x+uTb(1)s = u^T (W^{(1)} x + b^{(1)}) = (u^T W^{(1)}) x + u^T b^{(1)},等价于单层线性模型 s=wTx+cs = w^T x + c,无论堆多少层都如此。非线性是神经网络表达能力的根本来源。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定d=2d = 2,窗口大小 3(5d5d \to 此例简化为窗口大小 3,即输入维度 =3d=6= 3d = 6),隐藏层 m=4m = 4,激活函数 tanh\tanh

W(1)=[0.50.20.10.40.30.20.10.30.60.20.10.50.20.40.30.10.60.10.30.10.20.50.40.3]R4×6W^{(1)} = \begin{bmatrix} 0.5 & -0.2 & 0.1 & 0.4 & -0.3 & 0.2 \\ -0.1 & 0.3 & 0.6 & -0.2 & 0.1 & 0.5 \\ 0.2 & 0.4 & -0.3 & 0.1 & 0.6 & -0.1 \\ 0.3 & -0.1 & 0.2 & 0.5 & -0.4 & 0.3 \end{bmatrix} \in \mathbb{R}^{4 \times 6}

x=[0.2,0.1,0.5,0.8,0.9,0.3]T,b(1)=[0,0,0,0]T,u=[1,1,1,1]Tx = [0.2, 0.1, 0.5, 0.8, 0.9, 0.3]^T,\quad b^{(1)} = [0, 0, 0, 0]^T,\quad u = [1, -1, 1, -1]^T

计算

  1. z1(1)=0.5(0.2)0.2(0.1)+0.1(0.5)+0.4(0.8)0.3(0.9)+0.2(0.3)=0.10.02+0.05+0.320.27+0.06=0.24z^{(1)}_1 = 0.5(0.2) - 0.2(0.1) + 0.1(0.5) + 0.4(0.8) - 0.3(0.9) + 0.2(0.3) = 0.1 - 0.02 + 0.05 + 0.32 - 0.27 + 0.06 = 0.24
  2. 类似计算其余分量(略),得 z(1)[0.24,0.61,0.14,0.02]Tz^{(1)} \approx [0.24, 0.61, 0.14, 0.02]^T
  3. 激活:h=tanh(z(1))[0.235,0.545,0.140,0.020]Th = \tanh(z^{(1)}) \approx [0.235, 0.545, 0.140, 0.020]^T
  4. 评分:s=uTh=0.2350.545+0.1400.020=0.190s = u^T h = 0.235 - 0.545 + 0.140 - 0.020 = -0.190
  5. 概率:p=σ(0.190)0.453p = \sigma(-0.190) \approx 0.453(约 45% 概率为正类)

💡 为什么这样做?

神经网络的本质是特征变换器。第一层把原始词向量组合成”更抽象的特征”,激活函数引入非线性,使得决策边界可以弯曲——比线性分类器(只能画直线分割)强大得多。

类比:你想区分猫和狗,仅靠”耳朵长度”(一维)不够,但”耳朵长度 + 毛发颜色组合”(非线性特征)就能做到。神经网络自动学习哪些特征组合有用。

⚠️ 常见误区

  1. 误区s=uThs = u^T h 输出的是概率 → 正确ss 是原始评分(可正可负,无界),经过 sigmoid 才变成 (0,1)(0,1) 区间的概率
  2. 误区:二分类用 sigmoid,多分类也用 sigmoid → 正确:多分类用 softmax(对所有类别归一化),二分类才用 sigmoid(等价于 2 类 softmax)
  3. 误区:偏置 bb 不重要 → 正确:偏置允许决策边界不过原点,大幅提升模型灵活性

4. 非线性激活函数

Slide 35 Slide 36 Slide 37 Slide 38 Slide 39 Slide 40 Slide 41 Slide 42 Slide 43 Slide 44 Slide 45 Slide 46
  • Sigmoid / Logisticf(z)=11+exp(z)f(z) = \frac{1}{1 + \exp(-z)},范围 (0,1)(0, 1)
  • tanhtanh(z)=ezezez+ez\tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}},范围 (1,1)(-1, 1)
    • tanh(z)=2logistic(2z)1\tanh(z) = 2 \cdot \text{logistic}(2z) - 1
  • ReLUReLU(z)=max(z,0)\text{ReLU}(z) = \max(z, 0)
    • 训练快,梯度回传好;但有”死区”(负值区梯度为 0)
  • GELUGELU(x)=xP(Xx)\text{GELU}(x) = x \cdot P(X \le x),近似 xlogistic(1.702x)x \cdot \text{logistic}(1.702x)
    • Transformer 常用
  • SwiGLUSwiGLU(x)=(xV+c)Swishβ(xW+b)\text{SwiGLU}(x) = (xV + c) \otimes \text{Swish}_\beta(xW + b)
    • LLaMA 3、Qwen3 等现代 LLM 使用
  • 非线性的必要性:没有非线性,多层网络退化为单一线性变换 W1W2x=WxW_1 W_2 x = Wx

5. 交叉熵损失(Cross-Entropy Loss)

Slide 47 Slide 48 Slide 49 Slide 50 Slide 51 Slide 52 Slide 53 Slide 54 Slide 55 Slide 56 Slide 57
  • 目标:最大化正确类别 yy 的概率 = 最小化负对数概率
  • 交叉熵:H(p,q)=c=1Cp(c)logq(c)H(p, q) = -\sum_{c=1}^{C} p(c) \log q(c)
  • pp 为 one-hot 时,简化为 logp(yixi)-\log p(y_i | x_i)

📐 交叉熵损失从 MLE 到公式完整推导

变量定义

  • θ\theta = 模型参数
  • ptrue(c)p_{true}(c) = 真实分布(one-hot,正确类别为 1,其余为 0)
  • qθ(cx)q_\theta(c|x) = 模型预测的概率分布(softmax 输出)
  • H(p,q)H(p, q) = 交叉熵(p 和 q 的交叉熵)
  • NN = 训练样本数

推导过程

第 1 步:最大似然估计(MLE)。给定数据集 {(xi,yi)}i=1N\{(x_i, y_i)\}_{i=1}^N,最大化所有样本的联合对数似然:

maxθi=1Nlogpθ(yixi)\max_\theta \sum_{i=1}^N \log p_\theta(y_i | x_i)

第 2 步:等价于最小化负对数似然(NLL):

minθi=1Nlogpθ(yixi)=minθi=1NNLLi\min_\theta -\sum_{i=1}^N \log p_\theta(y_i | x_i) = \min_\theta \sum_{i=1}^N \text{NLL}_i

第 3 步:与交叉熵的联系。交叉熵的定义:

H(ptrue,qθ)=c=1Cptrue(c)logqθ(cx)H(p_{true}, q_\theta) = -\sum_{c=1}^C p_{true}(c) \log q_\theta(c|x)

ptruep_{true} 为 one-hot(ptrue(y)=1p_{true}(y) = 1,其余为 0),所有 cyc \ne y 的项乘以 0 消失:

H(ptrue,qθ)=1logqθ(yx)=logpθ(yx)H(p_{true}, q_\theta) = -1 \cdot \log q_\theta(y|x) = -\log p_\theta(y|x)

因此:最小化交叉熵 = 最大化正确类别的 log 概率 = MLE

第 4 步:整个数据集的平均损失(除以 NN 以便不同大小数据集可比):

J(θ)=1Ni=1Nlogpθ(yixi)=1Ni=1NH(ptrue(i),qθ(xi))J(\theta) = -\frac{1}{N}\sum_{i=1}^N \log p_\theta(y_i | x_i) = \frac{1}{N}\sum_{i=1}^N H(p_{true}^{(i)}, q_\theta(\cdot|x_i))

第 5 步:softmax + cross-entropy 合并简化。若 pθ(cx)=softmax(sc)=escjesjp_\theta(c|x) = \text{softmax}(s_c) = \frac{e^{s_c}}{\sum_j e^{s_j}},则:

logpθ(yx)=sy+logjesj-\log p_\theta(y|x) = -s_y + \log\sum_j e^{s_j}

这正是 PyTorch 的 F.cross_entropy(内部做 log-softmax + NLL)。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定:3 类分类(类别 0/1/2),正确标签为类别 1

变量
one-hot label pp[0,1,0][0, 1, 0]
模型 softmax 输出 qq[0.3,0.5,0.2][0.3, 0.5, 0.2]

计算

  1. 展开:H(p,q)=0log(0.3)1log(0.5)0log(0.2)H(p, q) = -0 \cdot \log(0.3) - 1 \cdot \log(0.5) - 0 \cdot \log(0.2)
  2. 化简:=log(0.5)=log20.693= -\log(0.5) = \log 2 \approx 0.693

对比(若预测更准 q=[0.1,0.8,0.1]q = [0.1, 0.8, 0.1]):H=log(0.8)0.223H = -\log(0.8) \approx 0.223,损失更低。

对比(若预测错误 q=[0.1,0.1,0.8]q = [0.1, 0.1, 0.8]):H=log(0.1)2.303H = -\log(0.1) \approx 2.303,损失很高。

结论:正确类别预测概率越高,交叉熵越低,梯度信号越弱(已经”学好了”)。

💡 为什么用交叉熵而不是 MSE?

信息论视角:交叉熵 H(p,q)H(p,q) 度量的是”用 qq 编码 pp 事件所需的平均比特数”。ppqq 越接近,H(p,q)H(p,q) 越小(趋近于 H(p,p)=H(p,p) = 熵)。最小化交叉熵就是让模型预测分布尽量接近真实分布。

梯度优势:对 softmax 输出用 MSE,梯度中会出现 σ(z)\sigma'(z)(sigmoid 导数),在饱和区几乎为零;而交叉熵的梯度是 y^y\hat{y} - y(预测值减真实值),简洁且无饱和问题。

⚠️ 常见误区

  1. 误区:交叉熵 = 信息熵 → 正确:信息熵 H(p)=plogpH(p) = -\sum p \log p 只取决于真实分布;交叉熵 H(p,q)=plogqH(p,q) = -\sum p \log q 还取决于模型预测;两者相差一个 KL 散度:H(p,q)=H(p)+DKL(pq)H(p,q) = H(p) + D_{KL}(p \| q)
  2. 误区:多标签(multi-label)分类用 softmax + cross-entropy → 正确:多标签(一个样本可属于多个类别)应用 binary cross-entropy(每个标签独立的 sigmoid);softmax 强制概率之和为 1,不适合多标签
  3. 误区log\log 底数是 10 → 正确:机器学习中统一用自然对数(底数 ee),单位是 nats(比特用 log2\log_2,但实践中混用,因为只相差常数倍,不影响优化)

6. 矩阵微积分(Matrix Calculus)

Slide 58 Slide 59 Slide 60 Slide 61 Slide 62 Slide 63 Slide 64 Slide 65 Slide 66 Slide 67 Slide 68 Slide 69
  • 雅可比矩阵(Jacobian):fxRm×n\frac{\partial f}{\partial x} \in \mathbb{R}^{m \times n},其中 (fx)ij=fixj\left(\frac{\partial f}{\partial x}\right)_{ij} = \frac{\partial f_i}{\partial x_j}
  • 链式法则的矩阵形式:sx=hxsh\frac{\partial s}{\partial x} = \frac{\partial h}{\partial x} \cdot \frac{\partial s}{\partial h}
  • 实用规则:
    • x(Wx+b)=W\frac{\partial}{\partial x}(Wx + b) = W
    • xf(z)=diag(f(z))\frac{\partial}{\partial x} f(z) = \text{diag}(f'(z))(逐元素非线性)
    • b(uTh)=uTdiag(f(z))\frac{\partial}{\partial b}(u^T h) = u^T \text{diag}(f'(z))
  • 形状约定(shape convention):梯度形状与参数形状相同(便于 SGD 更新)

7. 反向传播算法(Backpropagation)

Slide 70 Slide 71 Slide 72 Slide 73 Slide 74 Slide 75 Slide 76 Slide 77 Slide 78 Slide 79 Slide 80
  • 核心思想:利用计算图(computation graph)的链式法则从输出到输入逐层传播梯度
  • 前向传播:计算各节点的值
  • 反向传播:从损失出发,逆序传播梯度
    • 每个节点只需知道:局部偏导 ×\times 上游梯度
    • 上游梯度 = Lz\frac{\partial L}{\partial z}(从后面传来的)
    • 局部梯度 = zx\frac{\partial z}{\partial x}(本节点的偏导)
    • 下游梯度 = 上游梯度 ×\times 局部梯度
  • 效率:每条边只遍历一次,时间复杂度 O(n)O(n)nn 为计算图中的节点数)
  • 实现:PyTorch 的 autograd 自动完成

📐 反向传播完整推导:NER 二分类网络

网络定义

z(1)=Wx+b,h=tanh(z(1)),s=uTh,J=logσ(s)(y=1 的二元交叉熵)z^{(1)} = Wx + b, \quad h = \tanh(z^{(1)}), \quad s = u^T h, \quad J = -\log \sigma(s) \quad (y=1 \text{ 的二元交叉熵})

参数:θ={W,b,u,x}\theta = \{W, b, u, x\}(此处也对输入 xx 求梯度,以便更新词向量)


第 1 步Js\frac{\partial J}{\partial s}(损失对评分的梯度)

J=logσ(s)J = -\log \sigma(s)σ(s)=11+es\sigma(s) = \frac{1}{1+e^{-s}}

Js=1σ(s)σ(s)=1σ(s)σ(s)(1σ(s))=σ(s)1\frac{\partial J}{\partial s} = -\frac{1}{\sigma(s)} \cdot \sigma'(s) = -\frac{1}{\sigma(s)} \cdot \sigma(s)(1-\sigma(s)) = \sigma(s) - 1

直觉σ(s)(0,1)\sigma(s) \in (0,1),所以 Js=σ(s)1(1,0)\frac{\partial J}{\partial s} = \sigma(s)-1 \in (-1, 0)——评分越高,梯度越小(越接近 0),因为已经预测得很好了。


第 2 步Ju\frac{\partial J}{\partial u}(损失对输出权重 uu 的梯度)

s=uThs = u^T h,故 su=h\frac{\partial s}{\partial u} = h(列向量),链式法则:

Ju=Jssu=(σ(s)1)hRm\frac{\partial J}{\partial u} = \frac{\partial J}{\partial s} \cdot \frac{\partial s}{\partial u} = (\sigma(s)-1) \cdot h \in \mathbb{R}^m


第 3 步Jz(1)\frac{\partial J}{\partial z^{(1)}}(误差信号 δ\delta,关键中间量)

sh=uT\frac{\partial s}{\partial h} = u^Thz(1)=diag(1h2)\frac{\partial h}{\partial z^{(1)}} = \text{diag}(1 - h^2)(tanh 导数)

设上游梯度(从损失到 hh)为:

Jh=Jssh=(σ(s)1)uTR1×m\frac{\partial J}{\partial h} = \frac{\partial J}{\partial s} \cdot \frac{\partial s}{\partial h} = (\sigma(s)-1) \cdot u^T \in \mathbb{R}^{1 \times m}

传过 tanh(逐元素乘,\odot 表示 Hadamard 积):

δJz(1)=(σ(s)1)u(1h2)Rm\delta \equiv \frac{\partial J}{\partial z^{(1)}} = (\sigma(s)-1) \cdot u \odot (1 - h^2) \in \mathbb{R}^m

(将行向量转为列向量后与 1h21-h^2 逐元素相乘)


第 4 步:各参数梯度

利用 z(1)=Wx+bz^{(1)} = Wx + b 及 §6 的规则:

JW=δxTRm×n(外积,形状与 W 相同)\frac{\partial J}{\partial W} = \delta \cdot x^T \in \mathbb{R}^{m \times n} \quad \text{(外积,形状与 } W \text{ 相同)}

Jb=δRm(形状与 b 相同)\frac{\partial J}{\partial b} = \delta \in \mathbb{R}^m \quad \text{(形状与 } b \text{ 相同)}

Jx=WTδRn(传给词向量,用于联合训练)\frac{\partial J}{\partial x} = W^T \delta \in \mathbb{R}^n \quad \text{(传给词向量,用于联合训练)}


计算图(ASCII 示意)

x ──→ [z=Wx+b] ──→ [h=tanh(z)] ──→ [s=uᵀh] ──→ [J=-log σ(s)]
       ↑W,b              ↑                ↑u
  前向:→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
  反向:←←←←←←←←←←←←←←←←←←←←←←←←←←←
       ∂J/∂W=δxᵀ    ∂J/∂z=δ        ∂J/∂s=σ(s)-1

每个节点只需记录自己的局部导数,不需要知道网络其他部分的结构。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例(完整前向 + 反向)

设定d=2d=2m=2m=2W=I2W = I_2(单位矩阵),b=[0,0]Tb = [0,0]^Tu=[1,1]Tu = [1,1]^Tx=[0.6,0.4]Tx = [0.6, -0.4]^T,标签 y=1y=1

前向传播

步骤计算结果
z(1)=Wx+bz^{(1)} = Wx + b=[0.6,0.4]T= [0.6, -0.4]^T[0.6, 0.4]T[0.6,\ -0.4]^T
h=tanh(z(1))h = \tanh(z^{(1)})[tanh(0.6), tanh(0.4)][\tanh(0.6),\ \tanh(-0.4)][0.537, 0.380]T[0.537,\ -0.380]^T
s=uThs = u^T h1(0.537)+1(0.380)1(0.537) + 1(-0.380)0.1570.157
σ(s)\sigma(s)σ(0.157)\sigma(0.157)0.5390.539
J=logσ(s)J = -\log\sigma(s)log(0.539)-\log(0.539)0.6180.618

反向传播

步骤计算结果
Js=σ(s)1\frac{\partial J}{\partial s} = \sigma(s)-10.53910.539 - 10.461-0.461
Ju=(σ(s)1)h\frac{\partial J}{\partial u} = (\sigma(s)-1) h0.461×[0.537,0.380]T-0.461 \times [0.537, -0.380]^T[0.248, 0.175]T[-0.248,\ 0.175]^T
1h21 - h^2[10.5372, 10.3802][1-0.537^2,\ 1-0.380^2][0.712, 0.856]T[0.712,\ 0.856]^T
δ=(σ(s)1)u(1h2)\delta = (\sigma(s)-1) u \odot (1-h^2)0.461×[1,1]T[0.712,0.856]T-0.461 \times [1,1]^T \odot [0.712, 0.856]^T[0.328, 0.395]T[-0.328,\ -0.395]^T
JW=δxT\frac{\partial J}{\partial W} = \delta x^T[0.328,0.395]T[0.6,0.4][-0.328, -0.395]^T \cdot [0.6, -0.4][0.1970.1310.2370.158]\begin{bmatrix}-0.197 & 0.131 \\ -0.237 & 0.158\end{bmatrix}
Jb=δ\frac{\partial J}{\partial b} = \delta[0.328, 0.395]T[-0.328,\ -0.395]^T
Jx=WTδ\frac{\partial J}{\partial x} = W^T \deltaI[0.328,0.395]TI \cdot [-0.328, -0.395]^T[0.328, 0.395]T[-0.328,\ -0.395]^T

验证JW\frac{\partial J}{\partial W} 形状 2×2=2 \times 2 = WW 的形状 ✓,Jx\frac{\partial J}{\partial x} 形状 2=2 = xx 的形状 ✓

💡 反向传播的本质是什么?

反向传播的天才之处在于重用中间计算结果。如果你手动展开损失对每个参数的偏导数(拆掉所有复合函数),会得到大量重复子表达式。反向传播通过计算图把这些子表达式只计算一次,存起来复用

类比:计算 f(x)=((x+1)2+(x+1)3)×5f(x) = ((x+1)^2 + (x+1)^3) \times 5,先算 u=x+1u = x+1,再算 u2u^2u3u^3,比展开后各自对 xx 求导快得多。

时间复杂度是 O(n)O(n)nn 为参数数量)——每个参数的梯度计算量与前向传播等量级。这是深度学习可扩展到数十亿参数的根本原因。

⚠️ 常见误区

  1. 误区:反向传播 = 梯度下降 → 正确反向传播只负责计算梯度θJ\nabla_\theta J),梯度下降(或 Adam 等优化器)才负责用梯度更新参数θθηJ\theta \leftarrow \theta - \eta \nabla J)。两者是完全不同的操作。
  2. 梯度累加陷阱:若某节点(如词向量)被多个地方引用(同一个词在窗口中出现多次),其梯度必须累加所有路径传来的梯度,而不是取平均或覆盖。PyTorch 的 .grad 属性在多次 backward 时会自动累加(这也是为什么要 optimizer.zero_grad())。
  3. tanh 导数记忆tanh(z)=1tanh2(z)\tanh'(z) = 1 - \tanh^2(z),不要写成 1/cosh2(z)1/\cosh^2(z)(虽然等价,但前者可直接用前向已算出的 h=tanh(z)h = \tanh(z),后者还需重新算 cosh\cosh)。
  4. 误区:只有参数需要梯度 → 正确:NLP 中词向量也是参数,Jx\frac{\partial J}{\partial x} 非零,用于联合训练(fine-tuning embedding)。若想固定词向量,需要显式 requires_grad=False

推荐阅读

关联概念

作业提醒

  • A2 发布(神经网络基础 + 张量求导 + 依赖解析)
  • A1 截止

个人笔记