17-3 反向传播与模型训练
📌 一、 课程导入(5 分钟)
主题:神经网络如何学习?
第 17-1 课学习了逻辑回归的梯度下降——单个神经元参数的更新方法。
第 17-2 课学习了神经网络的结构——多层的、包含隐藏层的复杂模型。
新的问题:对于一个包含隐藏层的多层网络,如何计算每一层参数的梯度?
核心洞察:反向传播(Backpropagation)本质上只是链式法则(Chain Rule)的工程化应用。与其说是一个“新算法”,不如说是一种高效计算多层复合函数梯度的策略。
本课路径:
- 👨🏫 教师活动:回顾逻辑回归的梯度公式;点明多层网络的梯度计算需求;展示本课的结构图。
- 🧑🎓 学生活动:回忆逻辑回归的梯度推导过程;思考“如果是两层网络,梯度如何从输出传到输入”。
从已知的单层梯度过渡到多层梯度计算,建立“反向传播本质是链式法则”这一核心认知,避免将反向传播视为某种“黑魔法”。
📖 二、 解决问题过程(一):计算图与链式法则(20 分钟)
2.1 计算图(Computational Graph)
计算图是一种将数学表达式表示为有向图的方法,节点表示操作或变量,边表示数据流向。
示例:计算 \( e = (a + b) \times (b + 1) \)
flowchart LR
a["a"] --> add1["+"] --> mul["×"] --> e["e"]
b["b"] --> add1
b --> add2["+"] --> mul
c["1"] --> add2
前向传播:从输入到输出,计算每个节点的值。
2.2 链式法则回顾
对于复合函数 \( y = f(g(x)) \):
\[ \frac{dy}{dx} = \frac{dy}{dg} \cdot \frac{dg}{dx} \]对于多元复合函数:
\[ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial z} \cdot \frac{\partial z}{\partial w} \]2.3 计算图上的反向传播
反向传播的流程是从输出节点出发,沿反方向逐层计算梯度。
对于表达式 \( e = (a + b) \times (b + 1) \),假设最终损失 \( L = e \):
-
前向计算各节点值(设 \( a = 2, b = 3 \))
- \( c = a + b = 5 \)
- \( d = b + 1 = 4 \)
- \( e = c \times d = 20 \)
-
反向传播梯度:
- \( \frac{\partial L}{\partial e} = 1 \)
- \( \frac{\partial L}{\partial c} = \frac{\partial L}{\partial e} \cdot \frac{\partial e}{\partial c} = 1 \times d = 4 \)
- \( \frac{\partial L}{\partial d} = \frac{\partial L}{\partial e} \cdot \frac{\partial e}{\partial d} = 1 \times c = 5 \)
- \( \frac{\partial L}{\partial b} = \frac{\partial L}{\partial c} \cdot \frac{\partial c}{\partial b} + \frac{\partial L}{\partial d} \cdot \frac{\partial d}{\partial b} = 4 \times 1 + 5 \times 1 = 9 \)
- \( \frac{\partial L}{\partial a} = \frac{\partial L}{\partial c} \cdot \frac{\partial c}{\partial a} = 4 \times 1 = 4 \)
关键观察:梯度在反向传播过程中是累加的(当节点有多个下游路径时),且每个节点只需要接收来自“上方”的梯度,乘以本地导数后传给“下方”。
2.4 神经网络的计算图视角
神经网络就是一个巨大的计算图:
flowchart LR
x["x"] --> W1["W¹"] --> z1["z¹"] --> f1["f¹"] --> a1["a¹"]
b1["b¹"] --> z1
a1 --> W2["W²"] --> z2["z²"] --> f2["f²"] --> a2["ŷ"]
b2["b²"] --> z2
a2 --> L["损失"] --> J["J"]
反向传播就是沿着此图的反向路径,从 \( J \) 开始逐层计算所有参数(\( W^{[1]}, b^{[1]}, W^{[2]}, b^{[2]} \))的梯度。
- 👨🏫 教师活动:在黑板上绘制简单表达式的计算图;逐节点演示前向计算与反向传播过程;过渡到神经网络的计算图表示。
- 🧑🎓 学生活动:在笔记本上跟随教师绘制计算图并完成梯度计算;理解“梯度是反向传播的”。
通过简单的标量计算图建立反向传播的直觉理解,再推广到神经网络的张量计算,避免直接进入矩阵推导造成的认知跳跃。
📖 三、 解决问题过程(二):单隐藏层网络的梯度推导(35 分钟)
3.1 网络结构与符号定义
考虑一个单隐藏层神经网络:
- 输入层:\( n_0 \) 个特征
- 隐藏层:\( n_1 \) 个神经元,激活函数为 ReLU
- 输出层:\( n_2 \) 个神经元(根据任务决定)
前向传播:
\[ z^{[1]} = W^{[1]} x + b^{[1]}, \quad a^{[1]} = \text{ReLU}(z^{[1]}) \]\[ z^{[2]} = W^{[2]} a^{[1]} + b^{[2]}, \quad \hat{y} = f^{[2]}(z^{[2]}) \]3.2 反向传播的统一框架
反向传播的核心是计算损失 \( J \) 对每一层线性输出 \( z^{[l]} \) 的偏导数 \( \delta^{[l]} = \frac{\partial J}{\partial z^{[l]}} \)。
一旦有了 \( \delta^{[l]} \),参数梯度可直接计算:
\[ \frac{\partial J}{\partial W^{[l]}} = \delta^{[l]} (a^{[l-1]})^T \]\[ \frac{\partial J}{\partial b^{[l]}} = \delta^{[l]} \]关键公式(误差反向传播):
\[ \delta^{[l]} = (W^{[l+1]})^T \delta^{[l+1]} \odot f'^{[l]}(z^{[l]}) \]其中 \( \odot \) 表示逐元素相乘(Hadamard 乘积)。
3.3 场景一:回归任务(MSE + 线性输出)
配置:
- 输出层激活:\( f^{[2]}(z) = z \)(线性)
- 损失函数:\( J = \frac{1}{2m} \sum_{i=1}^{m} (\hat{y}^{(i)} - y^{(i)})^2 \)
单样本梯度:
\[ \delta^{[2]} = \frac{\partial J}{\partial z^{[2]}} = \hat{y} - y \]\[ \frac{\partial J}{\partial W^{[2]}} = \delta^{[2]} (a^{[1]})^T \]\[ \frac{\partial J}{\partial b^{[2]}} = \delta^{[2]} \]隐藏层误差(ReLU 的导数为 0/1):
\[ \delta^{[1]} = (W^{[2]})^T \delta^{[2]} \odot \mathbf{1}_{z^{[1]} > 0} \]其中 \( \mathbf{1}_{z^{[1]} > 0} \) 表示 ReLU 的导数(输入大于 0 时为 1,否则为 0)。
隐藏层参数梯度:
\[ \frac{\partial J}{\partial W^{[1]}} = \delta^{[1]} x^T \]\[ \frac{\partial J}{\partial b^{[1]}} = \delta^{[1]} \]3.4 场景二:二分类任务(交叉熵 + Sigmoid)
配置:
- 输出层激活:\( f^{[2]}(z) = \sigma(z) = \frac{1}{1+e^{-z}} \)
- 损失函数:\( J = -\frac{1}{m} \sum_{i=1}^{m} [y^{(i)} \log \hat{y}^{(i)} + (1-y^{(i)}) \log (1-\hat{y}^{(i)})] \)
单样本梯度:
\[ \delta^{[2]} = \frac{\partial J}{\partial z^{[2]}} = \hat{y} - y \]关键性质:交叉熵损失 + Sigmoid 激活的组合,使得输出层的误差表达式与回归任务完全相同(均为 \( \hat{y} - y \))。
💡 设计巧妙之处:无论输出层是线性+Sigmoid还是线性+MSE,只要损失函数与激活函数匹配,\( \delta^{[2]} \) 的形式统一为 \( \hat{y} - y \)。这正是逻辑回归和线性回归梯度表达式一致的根本原因。
隐藏层误差(与回归相同):
\[ \delta^{[1]} = (W^{[2]})^T \delta^{[2]} \odot \mathbf{1}_{z^{[1]} > 0} \]3.5 批量形式
对于包含 \( m \) 个样本的批次,将向量扩展为矩阵:
| 变量 | 单样本维度 | 批量维度 |
|---|---|---|
| \( X \) | \( n_0 \times 1 \) | \( n_0 \times m \) |
| \( z^{[1]} \) | \( n_1 \times 1 \) | \( n_1 \times m \) |
| \( a^{[1]} \) | \( n_1 \times 1 \) | \( n_1 \times m \) |
| \( z^{[2]} \) | \( n_2 \times 1 \) | \( n_2 \times m \) |
| \( \hat{y} \) | \( n_2 \times 1 \) | \( n_2 \times m \) |
批量参数梯度(以回归为例):
\[ \frac{\partial J}{\partial W^{[2]}} = \frac{1}{m} (\hat{Y} - Y) (A^{[1]})^T \]\[ \frac{\partial J}{\partial b^{[2]}} = \frac{1}{m} \sum_{i=1}^{m} (\hat{y}^{(i)} - y^{(i)}) \]\[ \frac{\partial J}{\partial W^{[1]}} = \frac{1}{m} \delta^{[1]} X^T \]\[ \frac{\partial J}{\partial b^{[1]}} = \frac{1}{m} \sum_{i=1}^{m} \delta^{[1](i)} \]3.6 权重初始化的重要性
梯度消失与梯度爆炸:
若权重初始化过大,深层网络的输出趋向饱和区,梯度消失;若初始化过小,梯度逐层衰减。
常用的初始化策略:
| 初始化方法 | 公式 | 适用激活函数 |
|---|---|---|
| Xavier/Glorot | \( W \sim \mathcal{N}(0, \frac{2}{n_{in} + n_{out}}) \) | Sigmoid, Tanh |
| He | \( W \sim \mathcal{N}(0, \frac{2}{n_{in}}) \) | ReLU |
- 👨🏫 教师活动:在黑板上逐步推导输出层和隐藏层的误差反向传播公式;对比回归和二分类场景下的 \( \delta^{[2]} \);演示批量矩阵形式的梯度计算。
- 🧑🎓 学生活动:跟随教师完成公式推导,特别关注维度匹配;理解 \( \delta^{[l]} \) 的递推关系;记录权重初始化策略。
反向传播是本课程数学强度最高的内容。通过分场景(回归/分类)、分层(输出/隐藏)、分形式(单样本/批量)的渐进式推导,确保学生理解每一步的来源,而非死记公式。
✍️ 四、 解决问题过程(三):完整训练循环的实现(20 分钟)
4.1 单隐藏层神经网络完整实现
4.2 在二分类数据集上训练
- 👨🏫 教师活动:逐段讲解代码中前向传播、反向传播、参数更新与训练循环的对应关系;运行训练过程并展示损失曲线;强调梯度形状与维度匹配的调试技巧。
- 🧑🎓 学生活动:在 Jupyter 中运行完整的训练代码;调整学习率、隐藏层大小、迭代次数等超参数,观察对训练过程的影响。
将抽象的数学推导转化为可运行的代码,建立“推导 → 实现 → 验证”的完整闭环。通过实际操作理解超参数对训练过程的具体影响。
✍️ 五、 课堂练习与巩固(10 分钟)
📝 六、 课堂小结(5 分钟)
flowchart TB
root["17-3 反向传播与模型训练"]
subgraph C1["📐 计算图与链式法则"]
direction TB
A1["表达式 → 有向图"]
A2["前向: 计算节点值"]
A3["反向: 从输出逐层求导"]
A4["核心: 链式法则"]
end
subgraph C2["📉 反向传播公式"]
direction TB
B1["δ[l] = (W[l+1])ᵀ δ[l+1] ⊙ f' (z[l])"]
B2["∂J/∂W[l] = δ[l] (a[l-1])ᵀ"]
B3["∂J/∂b[l] = δ[l]"]
B4["回归: δ[2] = ŷ - y"]
B5["分类: δ[2] = ŷ - y (相同形式)"]
end
subgraph C3["⚠️ 训练关键技术"]
direction TB
C1["权重初始化: Xavier / He"]
C2["学习率选择: 太大震荡/太小收敛慢"]
C3["监控损失曲线诊断训练状态"]
end
subgraph C4["💻 代码实现"]
direction TB
D1["前向: 缓存中间变量"]
D2["反向: 计算梯度"]
D3["更新: 梯度下降"]
D4["循环: epoch 迭代"]
end
root --> C1
root --> C2
root --> C3
root --> C4
style root fill:#4b6cb7,stroke:#253b6e,color:#fff,stroke-width:2px
style C1 fill:#e3f2fd,stroke:#2196f3
style C2 fill:#fff3e0,stroke:#ff9800
style C3 fill:#e8f5e9,stroke:#4caf50
style C4 fill:#f3e5f5,stroke:#9c27b0
✏️ 随堂检测与互动练习
📮 七、 课后作业与拓展
📋 八、 板书设计
🔤 本课用到的单词
| 单词 | 发音(美式) | 解释 |
|---|---|---|
| Backpropagation | /ˈbækˌprɑːpəˈɡeɪʃən/ | 反向传播,通过链式法则从输出向输入逐层计算梯度的算法 |
| Chain Rule | /tʃeɪn ruːl/ | 链式法则,复合函数求导的基本法则,反向传播的数学基础 |
| Computational Graph | /ˌkɑːmpjuˈteɪʃənl ɡræf/ | 计算图,表示数学运算流程的有向图 |
| Error Signal | /ˈerər ˈsɪɡnəl/ | 误差信号,即 \( \delta^{[l]} = \partial J/\partial z^{[l]} \) |
| Gradient Flow | /ˈɡreɪdiənt floʊ/ | 梯度流动,梯度在网络中反向传播的过程 |
| Vanishing Gradient | /ˈvænɪʃɪŋ ˈɡreɪdiənt/ | 梯度消失,深层网络中误差信号逐层衰减到零 |
| Exploding Gradient | /ɪkˈsploʊdɪŋ ˈɡreɪdiənt/ | 梯度爆炸,误差信号逐层增长到极大值 |
| Weight Initialization | /weɪt ˌɪnɪʃəlaɪˈzeɪʃən/ | 权重初始化,训练开始前为参数赋初值的策略 |
| Xavier Initialization | /ˈzeɪviər ˌɪnɪʃəlaɪˈzeɪʃən/ | Xavier/Glorot 初始化,适用于 Sigmoid/Tanh 的初始化方案 |
| He Initialization | /hiː ˌɪnɪʃəlaɪˈzeɪʃən/ | He/Kaiming 初始化,适用于 ReLU 的初始化方案 |
| Learning Rate | /ˈlɜːrnɪŋ reɪt/ | 学习率,梯度下降中控制参数更新步长的超参数 |
| Convergence | /kənˈvɜːrdʒəns/ | 收敛,训练过程中损失函数趋于稳定的状态 |
| Epoch | /ˈiːpɑːk/ | 轮次,训练过程中完整遍历一次全部训练数据 |
| Batch | /bætʃ/ | 批次,训练时同时处理的一小部分样本集合 |
| Gradient Descent | /ˈɡreɪdiənt dɪˈsent/ | 梯度下降,沿负梯度方向更新参数的优化算法 |