Backpropagation/zh
| Article | |
|---|---|
| Topic area | Deep Learning |
| Difficulty | Intermediate |
| Prerequisites | Gradient Descent, Neural Networks |
反向传播(Backpropagation)(误差反向传播的缩写)是一种高效计算损失函数相对于神经网络中每个权重的梯度的算法。它与梯度下降等优化方法相结合,构成了现代深度学习模型的标准训练过程。
链式法则
反向传播本质上是微积分中链式法则(Chain Rule)的应用。如果变量 $ z $ 依赖于 $ y $,而 $ y $ 又依赖于 $ x $,则:
- $ \frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \cdot \frac{\partial y}{\partial x} $
在神经网络中,损失 $ L $ 依赖于输出,输出依赖于最后一个隐藏层的激活值,激活值又依赖于前一层的激活值,以此类推直到输入。链式法则允许我们将梯度分解为局部导数的乘积,每一层对应一个。
前向传播
在前向传播过程中,输入数据逐层通过网络传播。对于全连接层 $ l $:
- $ \mathbf{z}^{(l)} = \mathbf{W}^{(l)} \mathbf{a}^{(l-1)} + \mathbf{b}^{(l)} $
- $ \mathbf{a}^{(l)} = g^{(l)}(\mathbf{z}^{(l)}) $
其中 $ \mathbf{a}^{(l-1)} $ 是前一层的激活值($ \mathbf{a}^{(0)} = \mathbf{x} $),$ \mathbf{W}^{(l)} $ 和 $ \mathbf{b}^{(l)} $ 是权重和偏置,$ g^{(l)} $ 是激活函数。前向传播存储所有中间值 $ \mathbf{z}^{(l)} $ 和 $ \mathbf{a}^{(l)} $,因为它们在反向传播过程中需要使用。
反向传播过程
反向传播从损失开始向输入方向计算梯度。定义第 $ l $ 层的误差信号为:
- $ \boldsymbol{\delta}^{(l)} = \frac{\partial L}{\partial \mathbf{z}^{(l)}} $
对于输出层(第 $ L_{\text{out}} $ 层):
- $ \boldsymbol{\delta}^{(L_{\text{out}})} = \frac{\partial L}{\partial \mathbf{a}^{(L_{\text{out}})}} \odot g'^{(L_{\text{out}})}(\mathbf{z}^{(L_{\text{out}})}) $
对于每个更早的层,误差向后传播:
- $ \boldsymbol{\delta}^{(l)} = \bigl(\mathbf{W}^{(l+1)}\bigr)^\top \boldsymbol{\delta}^{(l+1)} \odot g'^{(l)}(\mathbf{z}^{(l)}) $
其中 $ \odot $ 表示逐元素乘法。一旦知道误差信号,参数梯度为:
- $ \frac{\partial L}{\partial \mathbf{W}^{(l)}} = \boldsymbol{\delta}^{(l)} \bigl(\mathbf{a}^{(l-1)}\bigr)^\top, \qquad \frac{\partial L}{\partial \mathbf{b}^{(l)}} = \boldsymbol{\delta}^{(l)} $
计算图
现代深度学习框架(PyTorch、TensorFlow、JAX)通过构建计算图(Computational Graph)来实现反向传播——这是一个有向无环图,其中每个节点表示一个运算,每条边传递一个张量。前向传播构建计算图;反向传播按逆拓扑排序遍历它,在每个节点应用链式法则。
这种抽象使得对任意运算组合进行微分成为可能,而不仅限于标准层类型。存在两种实现策略:
- 静态图 — 在执行前一次性定义图(早期的TensorFlow)。允许激进的编译器优化,但灵活性较低。
- 动态图 — 在每次前向传播时重建图(PyTorch、TensorFlow Eager模式)。更便于调试和处理依赖数据的控制流模型。
自动微分
反向传播是反向模式自动微分(Reverse-mode Automatic Differentiation)(AD)的特例。与数值微分(近似的)或符号微分(可能产生冗长的表达式)不同,自动微分通过系统地对基本运算应用链式法则来计算精确导数。
反向模式自动微分可以在单次反向传播中计算标量输出相对于所有输入的梯度,这使其非常适合神经网络——损失是标量,但参数数量达到数百万。
反向传播的计算成本通常是前向传播的2-3倍,因为它必须评估局部雅可比矩阵(Jacobian)并将其与传入的误差信号相乘。
梯度消失与梯度爆炸
当网络层数很多时,梯度是许多局部导数的乘积。如果这些因子持续小于1,梯度会指数级地趋向于零——即梯度消失(Vanishing Gradient)问题。如果它们持续大于1,梯度会指数级增长——即梯度爆炸(Exploding Gradient)问题。
| 问题 | 症状 | 常见缓解措施 |
|---|---|---|
| 梯度消失 | 早期层学习极其缓慢 | ReLU激活函数、残差连接、批量归一化、精心初始化 |
| 梯度爆炸 | 损失发散或产生NaN值 | 梯度裁剪、权重正则化、降低学习率 |
在引入ReLU激活函数、残差连接(ResNet)和归一化技术之前,这些问题是训练深度网络的主要障碍。
实践注意事项
- 内存 — 前向传播必须存储所有中间激活值以供反向传播使用。对于非常深的网络,这可能是不可承受的;梯度检查点(Gradient Checkpointing)通过在反向传播时重新计算激活值来以计算换取内存。
- 数值稳定性 — 使用log-sum-exp技巧和融合的softmax-交叉熵实现可以避免上溢和下溢。
- 高阶梯度 — 对反向传播本身再求导可以得到二阶信息(海森向量积),这对自然梯度下降和元学习(Meta-learning)等方法很有用。
- 混合精度(Mixed Precision) — 在半精度下执行前向传播,同时保持权重的全精度主副本,可以在现代GPU上加速训练。
历史发展
反向传播背后的关键思想由多位研究者独立发展。Seppo Linnainmaa于1970年描述了反向模式自动微分。Paul Werbos在1974年的博士论文中将其应用于神经网络。该算法在Rumelhart、Hinton和Williams于1986年发表的有影响力的论文之后获得了广泛采用,该论文展示了它在多层网络上的有效性。
参见
- Gradient Descent
- Stochastic Gradient Descent
- Neural Networks
- Loss Functions
- Convolutional Neural Networks
- Recurrent Neural Networks
参考文献
- Rumelhart, D. E., Hinton, G. E. and Williams, R. J. (1986). "Learning representations by back-propagating errors". Nature, 323, 533–536.
- Linnainmaa, S. (1970). "The representation of the cumulative rounding error of an algorithm as a Taylor expansion of the local rounding errors". Master's thesis, University of Helsinki.
- Werbos, P. J. (1974). "Beyond Regression: New Tools for Prediction and Analysis in the Behavioral Sciences". PhD thesis, Harvard University.
- Baydin, A. G. et al. (2018). "Automatic Differentiation in Machine Learning: a Survey". JMLR, 18(153), 1–43.
- Goodfellow, I., Bengio, Y. and Courville, A. (2016). Deep Learning, Chapter 6. MIT Press.