调试夜班:为什么我的网络不学习?
上周在训练一个三层的全连接网络做图像分类,损失函数从 2.3 降到 2.1 就卡住了,连续跑了 20 个 epoch 纹丝不动。打开 TensorFlow 的梯度监控,发现第一层的权重梯度全是 0.0001 量级,而最后一层还在 0.1 左右。那一刻才意识到,反向传播不是“自动求导库帮你算好了”这么简单,而是需要你理解误差是如何从输出层一层层倒流回输入层的。如果中间某层的梯度被激活函数压得太小,整个网络就会像被掐住脖子的水管,上游再怎么努力,下游也收不到信号。
梯度消失的现场证据
我们把那晚的权重变化曲线、梯度热力图和激活值分布同步到白板,沿着“输出误差 → 反向传播 → 权重更新”画成一条数据流。结果发现:sigmoid 激活函数在饱和区梯度接近 0,每经过一层就衰减 0.25 倍,三层下来梯度只剩原来的 1.5%,第一层权重几乎不动。反向传播不是魔法,而是链式法则的工程实现,任何一个环节设计不当,都会让误差信号在传播途中消失或爆炸。
心智模型:把反向传播想成误差的逆向旅行
前向传播是送信,反向传播是回执
想象你在一个多层邮局系统里送信:前向传播时,你把原始数据从第一层邮局送到最后一层,每经过一层邮局,工作人员都会对信件做一次处理(加权求和、激活函数),最终在最后一层得到预测结果。反向传播则是把“预测错了多少”这个误差信息,从最后一层邮局一层层往回传,告诉每一层邮局的工作人员:“你刚才的处理方式需要调整,调整幅度就是误差对你的影响程度。”
这个“影响程度”就是梯度。梯度大的权重,说明它对最终误差贡献大,需要大幅调整;梯度小的权重,说明它影响小,可以微调。反向传播的本质,就是通过链式法则,把最终误差分解到每个权重上,让每个参数都知道自己该往哪个方向、移动多少距离。
image_group

链式法则:误差传播的数学桥梁
反向传播的核心是链式法则。假设网络有 L 层,第 l 层的输出是 a(l)a^{(l)}a(l),权重是 W(l)W^{(l)}W(l),偏置是 b(l)b^{(l)}b(l)。对于损失函数 LLL,我们想知道 ∂L∂W(l)\frac{\partial L}{\partial W^{(l)}}∂W(l)∂L。
链式法则告诉我们:
∂L∂W(l)=∂L∂a(L)⋅∂a(L)∂a(L−1)⋅…⋅∂a(l+1)∂W(l)\frac{\partial L}{\partial W^{(l)}} = \frac{\partial L}{\partial a^{(L)}} \cdot \frac{\partial a^{(L)}}{\partial a^{(L-1)}} \cdot \ldots \cdot \frac{\partial a^{(l+1)}}{\partial W^{(l)}}∂W(l)∂L=∂a(L)∂L⋅∂a(L−1)∂a(L)⋅…⋅∂W(l)∂a(l+1)
这个公式看起来复杂,但直观理解就是:最终误差对第 l 层权重的影响,等于“误差对最后一层输出的影响”乘以“最后一层对倒数第二层的影响”乘以……一直乘到“第 l+1 层对第 l 层权重的影响”。每一层的梯度,都是后面所有层梯度的累积乘积。
激活函数的梯度陷阱
这里就出现了梯度消失和梯度爆炸的根源。如果每一层的梯度都小于 1(比如 sigmoid 在饱和区的梯度是 0.25),多层相乘后梯度会指数衰减;如果每一层的梯度都大于 1,多层相乘后梯度会指数爆炸。ReLU 激活函数之所以流行,就是因为它在前向传播时梯度恒为 1(在激活区),避免了梯度消失,但要注意 dying ReLU 问题。
image_group

最小可复现实验:手动实现反向传播
环境与依赖
- Python 3.8+
- NumPy 1.20+
- 可选:Matplotlib(用于可视化)
python3 -m venv backprop-lab && cd backprop-lab
source bin/activate # Windows: backprop-lab\Scripts\activate
pip install

最低0.47元/天 解锁文章
673

被折叠的 条评论
为什么被折叠?



