
一、计算图与链式法则回顾前向传播把输入变成输出而反向传播Backpropagation回答的问题是每个参数对最终损失的影响有多大答案就是梯度它决定了参数更新方向。反向传播的本质是在计算图上应用链式法则。假设一个最简链路即z f(x)y g(z)损失L h(y)。根据链式法则关键点在于从输出向输入逐层回传我们总是先拿到更靠后的梯度\frac{\partial L}{\partial y}再乘以本地的\frac{\partial y}{\partial z}得到更靠前的梯度。这种局部梯度相乘、全局从后往前的模式就是反向传播可并行、可复用缓存前向中间值的原因。二、全连接层梯度推导以一个全连接层 Sigmoid 激活为例记\mathbf{z} W\mathbf{a} \mathbf{b}, \qquad \mathbf{h} \sigma(\mathbf{z})假设我们已经从后续层拿到了反向传播传来的误差。推导本层参数梯度1. 对偏置\mathbf{b}最直观因为每个分量都加了同一个。2. 对权重W外积形式其中\frac{\partial L}{\partial \mathbf{z}} \frac{\partial L}{\partial \mathbf{h}} \odot \sigma(\mathbf{z})。3. 传给前一层的误差这个正是下一层更靠前反向传播所需要的输入梯度如此循环直到输入层。一句话口诀权重梯度 输出误差外积输入激活偏置梯度 输出误差按位乘传向前层 权重转置乘输出误差。三、数值梯度校验代码实现手推的解析梯度对不对永远要用数值梯度做交叉验证这是自己写训练循环时最该养成的习惯。数值梯度用中心差分近似校验代码import numpy as np def numerical_grad_check(): D 4 rng np.random.default_rng(0) W1 rng.standard_normal((D, D)) * 0.5 b1 rng.standard_normal(D) * 0.5 W2 rng.standard_normal((D, D)) * 0.5 b2 rng.standard_normal(D) * 0.5 x rng.standard_normal(D) t rng.standard_normal(D) def forward(x): a1 1.0 / (1.0 np.exp(-(W1 x b1))) return W2 a1 b2 def loss(x): y forward(x) return 0.5 * np.sum((y - t) ** 2) # 解析梯度手推反向传播 a1 1.0 / (1.0 np.exp(-(W1 x b1))) y W2 a1 b2 dy (y - t) dW2 np.outer(dy, a1) db2 dy da1 W2.T dy dz1 da1 * a1 * (1 - a1) dW1 np.outer(dz1, x) db1 dz1 # 数值梯度中心差分 eps 1e-5 params {W1: W1, b1: b1, W2: W2, b2: b2} analytic {W1: dW1, b1: db1, W2: dW2, b2: db2} max_err 0.0 for name, p in params.items(): g np.zeros_like(p) it np.nditer(p, flags[multi_index]) while not it.finished: idx it.multi_index old p[idx] p[idx] old eps; lp loss(x) p[idx] old - eps; lm loss(x) p[idx] old g[idx] (lp - lm) / (2 * eps) it.iternext() max_err max(max_err, np.abs(g - analytic[name]).max()) print(总体最大误差 , max_err, -, PASS if max_err 1e-4 else FAIL)实测结果参数数值梯度与解析梯度最大绝对误差W13.80e-11b12.23e-11W22.06e-11b21.59e-11总体3.80e-11 → PASS误差在 1e-11 量级完全由中心差分的截断误差决定说明我们的解析梯度推导是正确的。工程经验只在训练初期、小网络上跑一次梯度校验。线上训练若每次都跑数值梯度成本会高几个数量级。四、深层网络梯度消失实测链式法则的隐患在于梯度是连乘的。一旦每一层的局部梯度都略小于 1乘上十几层后就会指数级趋近于 0——这就是梯度消失Vanishing Gradient。我们用一个 10 层全连接网络每层 16 维Xavier 初始化实测不同激活函数的首层梯度 / 末层梯度比值激活函数首层(L1)梯度范数末层(L10)梯度范数L1/L10 比值结论Sigmoid4.09e-061.64e002.50e-06严重消失差约 40 万倍Tanh2.48e002.46e001.01e00基本持平ReLU4.70e-021.57e-023.00e00不衰减甚至略增解读Sigmoid 的导数最大值仅 0.2510 层连乘后\approx 0.25^{10} \approx 1e-6首层几乎收不到误差信号自然训不动。ReLU 在正区的导数恒为 1梯度得以跨层保持。这正是现代网络普遍采用 ReLU 族激活的根本原因。完整实验脚本含逐层梯度范数打印import numpy as np def sigmoid(z): return 1.0 / (1.0 np.exp(-z)) def sigmoid_grad(z): s sigmoid(z); return s * (1 - s) def tanh_grad(z): return 1 - np.tanh(z) ** 2 def relu(z): return np.maximum(0, z) def relu_grad(z): return (z 0).astype(float) ACT {Sigmoid: (sigmoid, sigmoid_grad), Tanh: (np.tanh, tanh_grad), ReLU: (relu, relu_grad)} D, L 16, 10 rng np.random.default_rng(0) Ws [rng.standard_normal((D, D)) / np.sqrt(D) for _ in range(L)] bs [np.zeros(D) for _ in range(L)] x, t rng.standard_normal(D), rng.standard_normal(D) for name, (f, g) in ACT.items(): acts, pre [x], [] a x for l in range(L): z Ws[l] a bs[l]; a f(z) pre.append(z); acts.append(a) dy (acts[-1] - t) delta, norms dy, [] for l in range(L - 1, -1, -1): da Ws[l].T delta dz da * g(pre[l]) norms.append(np.linalg.norm(np.outer(dz, acts[l]))) delta dz print(name, L1/L10 , norms[-1] / norms[0])五、ReLU 族与 BatchNorm 缓解方案梯度消失不是绝症工程上有成熟解法1. ReLU 族激活ReLU正区导数恒 1直接缓解消失但负区死神经元。LeakyReLU / PReLU给负区一个小的非零斜率复活死神经元。GELU / Swish平滑、对优化更友好Transformer 时代的主流选择。2. Batch Normalization批归一化BN 在每层激活前把该 batch 的输入标准化为均值 0、方差 1它平滑了损失曲面、减小了内部协变量偏移使得各层梯度尺度更稳定允许更大的学习率间接缓解梯度问题。3. 残差连接ResNet更彻底的解决方案是跳过连乘。残差块反向时梯度多了一条恒等捷径包含1项即使\mathcal{F}的梯度很小信号也能直接回传。这让训练上百层的网络成为可能详见本专栏第 3 篇《CNN 架构演进》。六、总结本文从计算图与链式法则出发完整推导了全连接层的参数梯度并用中心差分把解析梯度验证到 1e-11 误差量级随后用一个 10 层网络的实测量化了 Sigmoid 梯度消失的严重程度首层梯度仅为末层的 2.5e-6并对比了 ReLU 的梯度保持能力。最后给出了 ReLU 族、BatchNorm、残差连接三类缓解手段。核心收获反向传播 在计算图上从后往前链式乘局部梯度数值梯度校验是自定义网络的安全带误差应 1e-4梯度消失源于链式法则的连乘Sigmoid 尤甚ReLU BN 残差是现代深网稳定训练的三件套。参考资料Rumelhart, D., Hinton, G., Williams, R. (1986).Learning Representations by Back-propagating Errors.Nature.Ioffe, S., Szegedy, C. (2015).Batch Normalization: Accelerating Deep Network Training.ICML.He, K., et al. (2016).Deep Residual Learning for Image Recognition.CVPR.Glorot, X., Bengio, Y. (2010).Understanding the Difficulty of Training Deep Feedforward Neural Networks.AISTATS.往期回顾第 1 篇神经网络基础——从感知机到多层网络的数学原理互动与关注觉得有收获就点赞 / 收藏 / 关注吧下一篇我们将进入计算机视觉聊聊《卷积神经网络架构演进——从 LeNet 到 ResNet》。本篇出自专栏《深学之路从感知机到智能体》—— 从感知机到大模型智能体的完整深度学习连载。每篇附可运行代码与原创实验收藏专栏不迷路。