在大屏或电脑上体验更佳——动画和操作区域更宽敞。
输入

损失函数

损失函数给预测误差打分,基于梯度的训练用它的导数决定更新。两种损失可以认定同一个答案有错,却给出不同的纠正力度。本课把单个 sigmoid 单元、样本和学习率固定,比较平方误差与交叉熵:当模型自信地答错时,前者的 logit 梯度约小 25 倍。

损失怎样影响更新

原始分数称为 logit,记作 z。sigmoid 把它变成概率:

p = σ(z) = 1 / (1 + e⁻ᶻ)

本课直接更新 z ← z − η·∂L/∂z。平方误差 L = (p − y)² 经过链式法则得到:

∂L/∂z = 2(p − y) · p(1 − p)

其中 p(1 − p) 是 sigmoid 的导数。二元交叉熵为:

L = −[y log p + (1 − y) log(1 − p)]

∂L/∂z = p − y

交叉熵与 sigmoid 配合后,p(1 − p) 因子抵消。两种梯度幅度之比为:

1 / (2p(1 − p))

在 p = 0.5 时比值最小,为 2;p = 0.02 时为 25.5;p = 0.001 时约为 500。sigmoid 两端越平,平方误差的信号越弱,包含自信但错误的那一端。

25.5 依赖损失的缩放约定。若写成 ½(p − y)²,比值为 51;若写成 c(p − y)²,则为 1 / (2c·p(1 − p))。常数能改数值,却不能消去随预测变化的因子。

画布横轴是 z,因为改成 p 会隐藏 dp/dz 的饱和。平方误差在左端形成平台,交叉熵形成斜坡。空心圆表示平方误差,实心圆表示交叉熵,二者从相同预测出发。纵轴同时容纳概率平方和 nat 两种量,曲线高度不适合比较;可比较的是同一学习率下沿 z 的更新步长。

逐步演示

默认 p₀ = 0.02、目标 y = 1、η = 1.00,共 8 步。模型起初以 98% 的概率认为答案是否。η = 1 时,梯度条幅度就是 logit 更新量。

步骤平方误差轨道交叉熵轨道
起点p = 0.02、z = −3.892相同
损失0.96043.9120,单位不同,不比较大小
1梯度 −0.0384,p = 0.0208梯度 −0.9800,p = 0.0516
2梯度 −0.0398,p = 0.0216梯度 −0.9484,p = 0.1231
30.02250.2523
40.02340.4161
50.0245z = 0.245、p = 0.5610,越过分类边界
6–8第 8 步为 0.02820.6647 → 0.7349 → 0.7832

第一步梯度比为 25.5。相同横向跨度下,图中切线分别下降约 6 和 145 像素。第二步平方误差梯度增长不到 4%,前几步轨迹仍挤在约 55 像素内。

8 步后,交叉熵使概率增加 0.7632,平方误差只增加 0.0082,进展约差 93 倍。各自损失分别下降 94% 和 1.7%。默认学习率下,平方误差需要 33 步才达到 p = 0.5。

饱和为何拖慢纠错

p(1 − p) 在 p = 0.5 时为 0.25,在 0.02 时为 0.0196,两端趋近零。平方误差把误差信号 2(p − y) 乘上这个因子,导致 sigmoid 尾部的纠正力度变小,即使预测离目标很远。

交叉熵在 y = 1、p → 0 时的 −log p 增大,链式法则最终留下 p − y。这消除了输出 sigmoid 造成的衰减,不保证网络其他层没有梯度问题。

问题来自平方误差与饱和输出的组合。线性输出的导数是 2(p − y),没有这个衰减因子,所以平方误差仍是回归的常用选择。sigmoid 或 softmax 分类通常配交叉熵;具体任务也可能需要其他目标。

把学习率改为 η = 5.00,平方误差会在第 8 步跨过边界。但学习率是全局系数,p(1 − p) 却随单元、样本和训练阶段变化;提高学习率也会放大其他梯度。真实网络继续向权重传递 ∂L/∂w = (∂L/∂z)·x,输出梯度的缩小会影响由它传回的更新。

边界情况

  • 不确定的起点 p₀ = 0.50:梯度比为 2.0,两者都能学习,最终概率为 0.775 和 0.886。这是饱和问题,不是所有平方误差都有问题。
  • 已接近正确 p₀ = 0.98、y = 1:比值仍为 25.5,但梯度幅度只有 0.0008 和 0.0200,移动很小是合理的。
  • 目标为 y = 0:本课画的是 y = 1。公式不变,若 p = 0.98 却应回答否,另一端会出现镜像的停滞。
  • η = 0.25:8 步内两者都没有达到 p = 0.5;预算内未跨界不等于永远不收敛。
  • 概率端点:数学上的有限 logit 不会使 sigmoid 等于 0 或 1,但浮点数可能舍入到端点。生成器在取对数前截断概率,避免 log(0);可选配置的交叉熵都有限。
  • 标记重合:两条轨道接近零损失时,空心圆可能围住实心圆,这是实际位置,不是绘图错误。

常见错误

  • 比曲线高度。概率平方和 nat 不是同一种量,应比较同一 z 和学习率下的步长。
  • 以为更新直接使用损失数值。本课用解析梯度更新,损失函数数值只用于报告,删去报告计算不改变更新。自动微分训练则需要保留产生梯度的计算图。
  • 一见小梯度就认为训练坏了。接近正确答案时,小步长是合理的;需要解释的是错误端的饱和。
  • 把问题归结为平方误差本身,忽略输出函数。
  • 在生产代码中先 sigmoid 再取对数。本课为展示概率这样计算并截断;PyTorch 的 BCEWithLogitsLoss 和 Keras 的 from_logits=True 可直接接收 logit,融合为数值稳定的计算。
  • 先靠放大学习率掩盖问题。它会放大全网络的梯度,不能逐样本补偿变化的饱和因子。

模型范围

这里使用真实 sigmoid、解析梯度和固定 8 步预算。两个独立模型并排比较,并非同一个模型同时优化两种损失。实际训练通常对小批量样本和输出求平均,更新 z = w·x + b 的权重;本课直接更新 z,以展示几何关系,未加入正则化、动量或 Adam。