神经网络 / 把一次学习慢下来

看见反向传播

预测错了,多层神经网络是怎样一点点改过来的?

2 层隐藏层 · 1 次学习
把“为什么这样改”看明白

只动一个参数,追踪它的影响。

先试调,再看损失,最后理解梯度。其余 19 个参数固定,每个变化都来自重新计算。

试调区 · 不写入训练

原值 −0.600试调值 −0.600
调小调大
换参数或目标会回到原值;下方提示会跟着实际结果改变。
一个旋钮,影响会往后传受影响的部分 · 灰色保持原值
圆内:本次计算值;Δ:试调导致的输出变化单条连接可有正权重,也可有负权重
预测值

→

损失

→

先试着把参数调大一点

为什么朝这边调?

把同一个旋钮的不同位置画出来

真实损失原值附近的变化趋势○ 原值 ● 试调位置

横轴:这个参数的值;纵轴:损失,越低越好。这是整个网络只沿一个参数方向的切片。

曲线旁边的这个数,就叫梯度

看原位置,损失往哪边变

原位置的梯度

从原值出发:新值 = 原值 − 学习率 × 梯度。这个建议只利用原位置附近的趋势,迈大步后仍要重算损失。

这个梯度怎样算出来?展开看一条真实计算链

把相邻环节“变化会传递多少”乘起来;遇到多条路径,先把贡献相加。

这条链使用的是原位置的数值。试调后如果继续学习,需要在新位置重新算梯度。

左右试调帮助理解方向。反向传播用局部变化关系直接计算全部参数的梯度,无须把每个参数反复试一遍。

想再深入一点:梯度、计算方式与参考资料

单参数试调:始终从同一初始网络出发,只修改选中的一个权重或偏置,保持另外 19 个参数固定。圆下的 Δ 表示节点输出相对原值的实际变化;梯度是原位置的局部变化率,两者含义不同。黑色曲线逐点重新计算损失,绿色虚线是原位置的切线。试调动画每帧重新执行前向计算,不写入训练模型;“从原网络看完整反传”会带入相同输入、目标和学习率,以初始参数重新开始完整训练。单参数试调和同时更新全部参数的结果一般不同。

梯度是什么?当前参数附近,“参数稍微增大,损失会往哪边变、变得多快”。正梯度表示稍微增大参数会增大损失,所以沿负方向更新;负梯度反过来。它不是错误的百分比,也不是因果责任。

为什么要向后传?前层神经元通过后面多条路径影响损失。反向传播沿每条路径按链式法则相乘,再把汇合的贡献相加,复用已算出的结果。图中橙色粒子表示计算依赖的方向,粒子大小不代表梯度大小。

本页怎么算?网络为 2 → 3 → 2 → 1,隐藏层用 Tanh,输出用 Sigmoid(0 到 1 的教学分数,不是准确率)。损失 =(预测 − 目标)² ÷ 2;新参数 = 旧参数 − 学习率 × 梯度。14 个权重与 6 个偏置全部参与更新。图中神经元的梯度指损失对该神经元激活前数值的导数,输入不更新。

动画与计算的关系:每轮先计算完整结果,动画逐步揭示;到第 8 步一次性提交全部参数,到第 9 步展示新参数的前向结果。“重看本轮”只重播已存的同一轮,不会额外训练。修改输入、目标或学习率会清空旧轨迹。页面没有网络推理请求,可离线运行。

适用边界:这里用一个样本慢放学习过程。实际训练会使用许多样本或小批量,损失不保证每步都下降;学习率太大可能越过合适位置。降低训练损失不等于学会泛化。

原理参考:PyTorch 官方教程 · 自动微分与反向传播 ↗

文字版:多层网络与反向传播在做什么

神经网络训练时到底发生了什么?这一页把一次学习慢放:一个 2→3→2→1 的小网络,总共 20 个参数(14 个权重、6 个偏置),拆成前向预测、算损失、逐层回传梯度、同步更新、再预测九步走完。在此之前,还可以先只动一个参数,看它一个人能造成多大影响。

画面上正在发生什么

先看「试调」这一半:选中某一个参数,其余 19 个全部冻结,拖动旋钮时右侧每个节点的数值、最终预测和损失都会重新算一遍。从末端权重开始——它直接连着输出,影响一目了然;换到前一层的权重,你会发现它的影响要经过好几条路径才到达输出,有时两条路径的贡献方向相反、互相抵消。这正是「梯度要逐层回传」的原因。

再看完整的九步:绿色数值向前流动得到预测,橙色梯度向后流动。关键在于每一层的梯度都是「后一层传来的梯度」乘以「本层的局部变化率」——这就是链式法则。所有梯度都算完之后才统一更新,不是算一个改一个。最后重新预测一次,损失比刚才小了一点点。

什么时候它会骗你

  • 一个样本上损失变小,什么也证明不了。这一页为了讲清机制只用了一个教学样本。真实训练是在成千上万个样本上求平均梯度,而且损失下降和泛化能力是两回事。
  • 梯度告诉你方向,不告诉你走多远。梯度只说明「往哪个方向改会让损失下降最快」,而且这个结论只在当前位置的极小邻域内成立。步子迈多大由学习率决定,迈过头可能反而让损失变大。
  • 链条一长,梯度就容易消失或爆炸。每回传一层就要乘一次局部变化率,这些数连乘起来,小于 1 就越乘越小(梯度消失),大于 1 就越乘越大(梯度爆炸)。这是深层网络难训练的根本原因,也是 ReLU、批归一化、残差连接被发明出来的动机。

常见问题

反向传播到底是什么?
它是高效计算「每个参数对损失的偏导数」的算法,本质是链式法则加上一次巧妙的复用:从输出往回走,每层把收到的梯度乘上自己的局部导数再传给前一层。这样算一遍就能得到全部参数的梯度,而不必对每个参数单独求一次。
反向传播和梯度下降是一回事吗?
不是。反向传播负责算出梯度,梯度下降负责用梯度更新参数。前者解决「往哪个方向改」,后者解决「改多少」。两者配合完成一次学习,缺一不可。
为什么所有参数要同时更新?
因为梯度是在当前这一组参数下算出来的。如果算一个改一个,后面参数的梯度就建立在已经被改动过的网络上,和推导的前提不符。标准做法是先把全部梯度算完,再一次性更新。

本页使用单个教学样本,隐藏层 Tanh、输出 Sigmoid、半平方误差,所有数值现场计算;该样本上的损失下降不代表泛化能力。

作者与维护:覃秉丰 · 关于覃秉丰 · 引用本页讲解

继续学习

覃秉丰