news 2026/9/8 17:01:20

训练1000轮损失不降?反向传播手算一遍就懂了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
训练1000轮损失不降?反向传播手算一遍就懂了

训练1000轮损失不降?反向传播手算一遍就懂了

【免费下载链接】nndl邱锡鹏《神经网络与深度学习》第二版与通识版:电子书、章节目录、学习资源与勘误。项目地址: https://gitcode.com/GitHub_Trending/nn/nndl

训练跑了 1000 轮,损失却纹丝不动,模型一点没学——十有八九,问题出在反向传播(backpropagation)上:梯度要么算错,要么层层传递后归零。这篇写给深度学习新手,也适合回头补基础的工程师:不依赖框架,从"参数到底怎么更新"倒着推,把每一步在算什么讲清楚。读完你能解决:

  • 看懂反向传播传递的到底是什么:误差项 error term 如何从输出层一路回到输入层
  • 会手动推导误差项公式,不再只会背结论
  • 能用一个最小的 2-2-1 网络,亲手算出完整梯度
  • 分清手写循环、向量化、自动微分三条实现路线各自适合什么场景

🧠 先建立直觉:反向传播像流水线追责

把一次前向传播(forward pass)想成一条工厂流水线:原料进(输入层)、中间加工(隐藏层)、成品出厂(输出层)。现在成品检验不合格,质检员不会把整条线推倒重来,而是拿着"这批差了多少"沿流水线往回问——最后一道工序担几成责?它又把几成"甩锅"给上一道?每个环节被追到的责任记下来,最后才知道谁该改多少、改多狠。

这个"被追到的责任",就是误差项;质检"往回问"的动作,就是反向传播。落到数学上:我们要让损失 L 最小,参数的更新方向由梯度(gradient)∂L/∂w 决定,而反向传播正是用链式法则(chain rule)把这个梯度从输出层往输入层一层层累乘出来。它优化的是"每一步都在往损失更小的地方走"这件事本身:

图:损失要最小化,反向传播给出的梯度就是下山方向;上图对比了几种优化器沿下降方向的轨迹。

直觉有了,接下来别急着记公式——我们倒过来,从"参数该怎么更新"这个终点往回推。

🔁 倒着推导误差项:从参数更新量反推

终点很明确:我们最终要的是每个参数的更新量

Δw = -η · ∂L/∂w # η 是学习率 learning rate

所以要算 ∂L/∂w。为什么中途要引入"误差项" δ 这个量?因为权重梯度恰好等于 δ 与上一层激活的外积,只要先拿到 δ,∂L/∂W 一步就出来——δ 是把"重复出现的乘积"提前打包好的中间结果。

为什么需要输出层的 δ?它把"损失对最后一层输入的敏感程度"一次算清,供后面逐层复用:

δ^(L) = (a^(L) - Y) ⊙ σ'(z^(L))

为什么需要往回传的 δ?因为前一层对损失的贡献 = 后一层传回的责任 × 连接权重 × 本地激活导数,这条递推就是反向传播的"追责规则":

δ^(l) = (W^(l+1)ᵀ δ^(l+1)) ⊙ σ'(z^(l))

为什么拿到 δ 就够?有了它,权重和偏置的梯度直接落地,不需要再对损失求一次复杂偏导:

∂L/∂W^(l) = δ^(l) (a^(l-1))ᵀ ∂L/∂b^(l) = δ^(l)

三行公式闭环了。下面用一个能手算的小网络验证它真的对得上。

✏️ 手算走一遍反向传播:最小2-2-1网络

固定参数,输入X=[1,0],标签Y=1,激活全用 sigmoid,损失用均方误差。参数取W¹=[[0.5,1.0],[1.0,0.5]]b¹=[1.0,-1.0]W²=[0.5,-0.5]b²=0。按"检查项 → 数值 → 来源"过一遍:

检查项数值来源说明
隐藏层输入 z¹[1.5, 0.0]W¹X+b¹,前向第一层
隐藏层输出 a¹[0.8176, 0.5]σ(z¹)
输出层 z² / a²0.1588 / 0.5396W²a¹+b²再 σ
损失 L0.106½(Y-a²)²
输出层 δ²-0.1144(a²-Y)·σ'(z²),σ'(z²)=0.2484
隐藏层 σ'(z¹)[0.1491, 0.25]a¹(1-a¹)
隐藏层 δ¹[-0.0085, 0.0143](W²ᵀδ²)⊙σ'(z¹)
∂L/∂W² / ∂L/∂b²[-0.0935,-0.0572] / -0.1144δ²a¹ᵀ/δ²
∂L/∂W¹ / ∂L/∂b¹[[-0.0085,0],[0.0143,0]] / [-0.0085,0.0143]δ¹Xᵀ/δ¹

注意 δ¹ 第二项是正的:因为第二维权重为负,"甩锅"回传后符号被翻转,再乘上激活导数。手算一遍,链式法则的符号与量级就都踏实了。

算对了,落到代码上无非是把这些外积写成矩阵乘法。

⚙️ 工程落地:手写、向量化与自动微分怎么选

路线代码量速度调试透明度适合谁
手写循环最高,每步可打印学习原理、定位错误
向量化(NumPy)高,矩阵维度可控生产前的原型、教学
自动微分(PyTorch)最快黑盒,靠梯度检验兜底实际训练大模型

核心逻辑其实就几行,前向存下中间量,反向按上面公式回填:

import numpy as np sig = lambda z: 1/(1+np.exp(-z)) z1 = W1@x + b1; a1 = sig(z1) # 前向 z2 = W2@a1 + b2; a2 = sig(z2) # 前向 d2 = (a2 - y) * a2*(1-a2) # 输出层误差项 dW2 = np.outer(d2, a1); db2 = d2 d1 = (W2*d2) * a1*(1-a1) # 隐藏层误差项(含权重回传) dW1 = np.outer(d1, x); db1 = d1

写完别急着跑,先核对几个高频坑。

❓ 反向传播高频疑问:梯度消失与数值核对

问:为什么必须从后往前算,不能各层独立求梯度?答:链式法则是连乘关系,后一层的 δ 是前一层求 ∂L/∂W 的输入。先算输出层并复用这个中间量,能把重复的乘积只算一次;逐参数暴力求导会把它算成千上万遍。

问:换交叉熵损失,输出层公式会变吗?答:会简化。MSE+sigmoid 时 δ² 带一个 σ' 因子;改用交叉熵+sigmoid,对数损失求导产生的 1/σ' 会把 σ' 抵消掉,δ² 直接退化成(a²-Y),少乘一项、数值也更稳。

问:手算和框架的梯度对不上,先查哪?答:先做数值梯度检验,对每个 w 用(f(w+ε)-f(w-ε))/2ε逼近,和反向值比对,相对误差 <1e-5 才算对。常见坑:漏加偏置、激活导数写错、batch 维度没乘进去。

问:梯度消失到底消失的是什么?答:消失的是"传给更浅层的信号"。σ' 最大 0.25,多层连乘因子小于 1,δ 越往前越小,浅层权重梯度趋近 0,等于没更新。ReLU、残差连接、BN 都是为了让这条连乘别一路衰减。

自测题:把上面例子的输出层激活换成 ReLU(此处 z²=0.1588>0,σ'=1),δ² 会变成多少?手算核对一下。想继续:仓库的 可视化资源 汇总了各章动图,优化算法对比 专门看损失面上的优化器轨迹;要动手写代码,案例与实践 第 4 章有可运行的 notebook,教材章节目录 可定位第 4 章前馈神经网络。

【免费下载链接】nndl邱锡鹏《神经网络与深度学习》第二版与通识版:电子书、章节目录、学习资源与勘误。项目地址: https://gitcode.com/GitHub_Trending/nn/nndl

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 17:00:02

three js 13 光照和阴影

文章目录1 灯光的类型2 材质3 如何场景有影子3 平行光4 聚光灯5 点光源1 灯光的类型 平行光 点光 面光 无阴影 射灯 2 材质 以下材质会接受光照 MeshStandardMaterial 标准PBR材质&#xff0c;主要用这个 MeshPhysicalMaterial 高级物理材质 没用 MeshLambertMaterial 兰伯…

作者头像 李华
网站建设 2026/9/8 16:54:57

冻融循环与氯离子侵蚀耦合下的混凝土耐久性数值模拟

这几年在北方沿海、盐渍土地区跑项目&#xff0c;混凝土耐久性病害里最让人头疼的组合就是冻融循环和氯离子侵蚀同时出现。单独做冻融试验或单测氯离子扩散&#xff0c;结果往往偏乐观&#xff0c;现场却早早出现顺筋裂缝和表层剥落。原因在于这两个过程根本就不是简单叠加&…

作者头像 李华
网站建设 2026/9/8 16:53:35

Windows消息机制详解:从硬件事件到窗口过程的完整链路

刚把Windows系统的启动流程和进程调度捋清楚没多久&#xff0c;我又一头扎进了消息机制。这个知识点我老早就想整理成笔记&#xff0c;但一直觉得它既抽象又琐碎&#xff1a;网上能找到的资料要么停留在“给你一段WinMain抄一下”&#xff0c;要么就直接上MFC/消息循环源码&…

作者头像 李华