计算图与反向传播是深度学习的核心引擎,它决定了模型如何从数据中学习。很多人调用model.backward()时,可能并不清楚梯度是如何从输出层一步步“流”回输入层的。这篇文章将彻底拆解这个过程,让你不仅理解原理,还能在代码层面亲手验证每一步的梯度计算。
我们将从一个带 L2 正则化的单隐藏层感知机入手,通过数学推导和代码实现,完整展示前向传播、计算图构建、反向传播的梯度计算全过程。重点是理解链式法则在计算图中的具体应用,以及中间变量如何被高效复用。无论你是想深入理解 PyTorch/TensorFlow 的自动微分机制,还是为面试准备,这篇文章都能提供清晰的路径。
1. 核心概念速览
在深入细节之前,我们先快速把握几个关键点:
| 概念 | 核心解释 | 在训练中的作用 |
|---|---|---|
| 前向传播 | 按网络结构顺序计算并存储每一层的输出(中间变量)。 | 得到模型预测值,并生成用于反向传播的计算图。 |
| 计算图 | 一种有向无环图,节点代表变量(输入、参数、中间结果),边代表运算。 | 清晰地定义了变量间的依赖关系,是反向传播的路线图。 |
| 反向传播 | 依据计算图,从最终损失开始,按链式法则反向计算所有参数的梯度。 | 为优化器(如SGD、Adam)提供更新模型参数的依据(梯度)。 |
| 梯度 | 损失函数相对于某个参数的变化率,是一个向量或矩阵。 | 指明了参数调整的方向和幅度,是模型学习的“指南针”。 |
| 链式法则 | 计算复合函数导数的核心数学工具。 | 使得梯度可以沿着计算图从输出层“传播”回输入层。 |
核心关系:前向传播构建计算图,反向传播利用计算图和链式法则计算梯度。整个过程是现代深度学习框架(如PyTorch的Autograd)自动微分功能的基础。
2. 为什么需要反向传播?一个简单例子
假设我们有一个极其简单的网络:y = w * x + b,并采用均方误差损失L = (y_pred - y_true)^2。 我们的目标是求损失L对参数w和b的梯度∂L/∂w和∂L/∂b。
手动计算并不难:
∂L/∂y_pred = 2*(y_pred - y_true)∂y_pred/∂w = x∂L/∂w = (∂L/∂y_pred) * (∂y_pred/∂w) = 2*(y_pred - y_true) * x- 同理,
∂L/∂b = (∂L/∂y_pred) * (∂y_pred/∂b) = 2*(y_pred - y_true) * 1
当网络变成10层、100层,有数百万个参数时,手动计算梯度变得不可能。反向传播算法通过系统性地应用链式法则,自动化了这个过程。它最大的优势是避免了重复计算:在前向传播中存储的中间结果,可以在反向传播中被复用,从而极大地提高了计算效率。
3. 实战模型:带L2正则化的单隐藏层感知机
我们将以一个具体的、稍复杂的模型为例,把理论落