损失怎样一路传回第一层:用计算图拆开反向传播 | xkmchenmu Blog

损失怎样一路传回第一层:用计算图拆开反向传播

神经网络先把输入变成预测,再把预测误差沿依赖关系逆向分配给每个参数。本文用单隐藏层网络和 L2 项建立计算图,解释局部导数、梯度汇合、矩阵形状、显存占用与数值梯度检查。

自动求导让训练代码只需调用一次 backward,但这并不意味着反向传播可以被当成魔法。模型能否学习,取决于每个运算是否在前向中产生正确数值,也取决于损失对这些数值的影响能否按链式法则回到参数。最有效的理解方式不是背一组偏导公式,而是画出计算图:节点保存张量,边表示运算依赖,正向沿依赖产生结果,反向按相反拓扑顺序累积梯度。

用形状为正向传播做第一轮审计

设一批输入 X 的形状为批大小乘特征数,第一层权重 W1 把特征映射到隐藏维度,偏置 b1 在批维广播。线性结果 Z 经过逐元素激活得到 H,第二层权重 W2 再产生输出 O,最后由 O 与标签 Y 计算数据损失 L。若加入 L2 正则,权重平方和形成另一条分支 S,目标 J 等于 L 与 S 的和。每个中间量的形状都应在纸面上先对齐。

损失怎样一路传回第一层:用计算图拆开反向传播 - 损失责任回传图

前向传播回答“当前参数给出什么预测”,反向传播回答“若想让目标下降,每个中间量和参数应朝哪个方向变化”。优化器才负责实际修改参数。

保存 Z、H 等中间激活并非多余。ReLU 的反向需要知道哪些位置在前向为正,矩阵乘法的参数梯度需要输入值,归一化层还可能使用批次统计。框架会按算子规则决定保留哪些张量,因此训练显存通常明显高于只做推理。

计算图中的分叉意味着梯度要汇合

同一个权重既影响数据损失,又出现在正则项中,目标对它的总梯度等于两条路径贡献之和。残差连接、参数共享和一个张量被多次使用时也是如此。反向传播不是在分叉处任选一条路线,而是把所有下游影响相加。若自定义算子遗漏某一分支,数值仍可能看起来正常,参数却会沿错误方向更新。

  1. 从标量目标 J 开始,其对自身的导数为一。
  2. 经过加法节点时,把上游梯度原样送到各输入分支。
  3. 经过矩阵乘法时,用转置关系得到输入梯度与权重梯度。
  4. 经过逐元素激活时,把上游梯度乘局部导数掩码。
  5. 某节点收到多条回传路径时,先累加再继续传播。

链式法则的高效之处在于复用

若直接为每个参数重新展开从它到损失的所有路径,会重复大量计算。反向模式自动微分从一个标量目标出发,按逆拓扑顺序传播向量—雅可比积;每个节点只需把已经汇总的上游梯度转换为其输入梯度。它不必显式构造尺寸巨大的完整雅可比矩阵,因此特别适合“输入参数很多、输出损失很少”的神经网络训练。

计算节点 前向关系 反向关注点
线性层 输入乘权重并加偏置 转置方向、批次求和与广播
激活函数 逐元素非线性 不可导点约定和饱和区域
损失函数 预测与标签比较 归约是求和还是平均
L2 正则 权重平方和乘系数 系数因子及是否包含偏置
共享节点 同一张量服务多处 所有路径贡献必须相加

矩阵形状是排错最快的约束

假设输出梯度与 O 同形,W2 的梯度应与 W2 同形,H 的梯度应与 H 同形;继续乘激活导数后,Z 的梯度仍与 Z 同形;W1 与 b1 的梯度也必须回到各自参数形状。偏置在前向沿批次广播,反向就要沿对应批次维求和。写自定义层时逐项断言这些形状,能在训练开始前发现大量转置和广播错误。

  • 记录损失是对批次求和还是求平均,这会直接缩放全部梯度。
  • 检查标签与预测的广播是否无意产生额外维度。
  • 为共享参数确认梯度缓冲区采用累加而非覆盖。
  • 梯度异常时同时打印激活范围、梯度范数和非有限值位置。

L2 项与优化器权重衰减需要分清

把 L2 正则显式写入目标,反向时会给权重增加与当前值成比例的导数。某些优化器提供 weight decay 参数,它在不同更新规则中的语义未必与“损失加平方和”完全等价,特别是在自适应优化算法中。实验应说明采用哪种方式、系数如何定义、偏置和归一化参数是否排除。否则,看似相同的超参数可能产生不同训练轨迹。

反向得到梯度后,框架通常把它放进参数的 grad 缓冲区。下一批开始前应按框架语义清零或置空;若故意进行梯度累积,则先对多个微批累加,再按有效样本数缩放并执行一次优化器更新。意外忘记清零会让历史批次持续参与,而过早清零则会让预期的累积消失。

训练显存来自“以后还要用”

前向阶段保存的激活、随机掩码与归一化统计,要一直留到相应反向算子执行。模型越深、序列越长、批次越大,这部分越可观。梯度检查点选择丢弃某些激活,反向时重新计算,以额外算力换显存;混合精度减少部分张量字节数,却需要关注溢出、下溢和损失缩放。释放计算图前再次 backward,或无意保留对历史图的引用,也会造成显存不断增长。

推理模式没有参数梯度需求,通常可以关闭梯度记录并减少保存。若部署代码仍构建训练图,不仅浪费内存,还可能让批归一化和 Dropout 处于错误语义。正向数值相近并不能替代明确模式切换。

数值差分是自定义反向的独立裁判

选择很小的双精度输入,固定随机性,对某个参数加上和减去微小扰动,用两次损失差除以两倍扰动近似导数,再与解析反向比较相对误差。步长过大产生截断误差,过小则受浮点舍入影响;ReLU 的零点等不可导位置也会让结果不稳定,应选择远离边界的测试值。

梯度检查只适合小规模单元测试,不能替代完整训练评估。可以分别测试线性层、激活、正则分支和共享节点,再构造一个微型网络,确认单步更新后损失按预期变化。若数值梯度通过但训练仍发散,继续检查学习率、数据尺度、初始化和损失归约。

自动求导可信的前提是图本身正确

框架能够准确地对“已经执行的运算”求导,却不知道标签错位、损失定义不合业务目标或某个张量被意外截断计算图。理解正向形状、局部导数、分支累加和缓冲区生命周期,才能判断自动结果是否对应想要的模型。反向传播的本质,是把一个全局误差拆成沿依赖关系传播的局部责任;当每条路径都可画、每个形状都可核对、每个自定义梯度都经独立检查时,训练循环才真正从黑盒变成可审计过程。

(0)
打赏 支付宝扫一扫 支付宝扫一扫

发表回复

登录后才能评论