反向传播
上一节我们讲了梯度下降,知道模型要通过求偏导数(计算坡度)来更新参数。但在一个包含成千上万、甚至数十亿参数的复杂神经网络中,我们要怎么高效地计算出每一个参数的偏导数呢?
这就要归功于深度学习的基石算法:反向传播(Backpropagation)。
什么是反向传播?
用一句话概括:反向传播是一种高效计算梯度的算法。它的核心数学基础是微积分中的链式法则(Chain Rule)。
为了直观理解,我们可以把它想象成一场精密的**“甩锅”大会**(或者叫责任分配)。
直观比喻:工厂流水线
假设有一个多层级的工厂流水线(神经网络),从工人 A 传给工人 B,再传给工人 C,最后生产出一件产品(预测输出)。 质检员(损失函数)拿过产品一看,发现有瑕疵(产生了误差 / Loss)。
这个时候,质检员需要追责:
- 最后一层(C):质检员首先把产品退给最后的装配工 C,说:“产品出了这么大问题,你得负多少责任?” C 检查了自己的工序,计算出自己的责任(偏导数)。
- 倒数第二层(B):C 接着对上一道工序的 B 说:“我装配没问题,是你传给我的零件本来就有毛病,你要分担这部分责任。” B 于是根据 C 传回来的反馈,结合自己的操作,计算出自己的责任。
- 更靠前的层(A):B 又用同样的逻辑去找 A“甩锅”。
就这样,误差的反馈信息从输出端(产品)开始,一层一层反向传递到了输入端。 在传递的过程中,每个人(每个参数)都清楚地算出了自己对最终误差应该承担多少责任(也就是偏导数
知道责任大小后,每个人就根据自己的责任去改进工艺(这就是梯度下降更新参数的过程)。
数学本质:链式法则
在数学上,神经网络可以看作是一个巨大的复合函数。例如一个三层的网络可以表示为
当我们想求最终损失
反向传播的高效之处就在于,它复用了计算过程。我们在算后面层的偏导数时,把中间结果存下来,前面层在计算时直接拿来乘就可以了,从而避免了海量的重复计算。
算法视角:动态规划的体现
如果你熟悉计算机科学中的算法设计,你会发现反向传播本质上就是动态规划(Dynamic Programming)在求解链式法则时的一种应用。
在朴素地计算整个网络的偏导数时,我们会遇到大量的重叠子问题(Overlapping Subproblems)。如果不加优化,很多相同的导数项会被重复计算无数次,导致计算复杂度呈指数级爆炸。
反向传播通过从后往前计算,并把每一层算出来的“局部梯度”用一张表(在深度学习框架中通常是计算图节点上的属性)存起来(记忆化 / Memoization)。当更前面的层需要这些数据时,直接查表相乘即可。正是这种利用动态规划思想的“空间换时间”策略,才让训练深层神经网络在计算上成为了可能。
总结:前向与反向
在有监督学习中,一次完整的训练迭代包含两个步骤:
- 前向传播(Forward Propagation):数据从输入层顺着网络往前走,经过层层计算,最终得到预测结果,并用损失函数计算出误差。
- 反向传播(Backward Propagation):误差从输出端往回传,利用链式法则逐层计算出每个参数对误差的偏导数(梯度)。
有了反向传播算出的梯度,我们就可以愉快地使用梯度下降去更新参数了。两者结合,构成了神经网络能够“学习”的基石。