笔记约 3 分钟阅读

反向传播:展开一次完整的前向与反向计算

以一个 2–2–1 XOR 网络为例,通过交互图展开一次完整的前向与反向传播。

src/content/posts/notes/ai/neural-networks/backpropagation/index.mdx
粉紫色调的少女与柔和光影插画

下面使用一个规模刻意缩小的 2–2–1 XOR 网络,把一次前向计算和反向传播完整展开。所有节点值与梯度均由浏览器实时计算。

神经网络的训练可以拆成两个方向相反的过程:

  1. 前向传播把输入逐层变成预测,并据此计算损失;
  2. 反向传播从损失出发,利用链式法则计算每个参数应当如何变化。

公式本身不难,难的是同时追踪节点值、局部导数和梯度流向。下面把网络压缩到一个 2–2–1 的 XOR 例子,让所有中间量都能直接看到。

一次前向传播

每个隐层节点先计算线性组合,再通过 sigmoid:

zj=iwjixi+bj,hj=σ(zj).z_j = \sum_i w_{ji}x_i + b_j, \qquad h_j = \sigma(z_j).

输出层重复同样的过程,得到预测 y^\hat y。二分类任务使用交叉熵:

L=ylogy^(1y)log(1y^).L = -y\log \hat y - (1-y)\log(1-\hat y).

下图由浏览器实时计算。切换 XOR 样本后,节点激活与梯度随之更新;“输入”“隐层”“输出”“反向”四个阶段用于分解同一轮计算。

Interactive figure

XOR:2–2–1 网络

在一个足够小的网络里,逐层观察激活值、预测、损失与梯度。

target 0ŷ 0.062loss 0.064
样本
观察阶段
XOR 神经网络计算图两个输入节点、两个 sigmoid 隐层节点和一个 sigmoid 输出节点。控制按钮可以切换样本与观察阶段。x₁0.000x₂0.000h₁0.047h₂1.000ŷ0.062L0.064
01 / 04

输入层只携带样本特征。选择不同的 XOR 样本,后续所有激活值与梯度都会重新计算。

梯度从哪里开始

sigmoid 输出与二元交叉熵组合后,输出节点的误差信号可以化简为:

Lzo=y^y.\frac{\partial L}{\partial z_o} = \hat y-y.

于是输出权重的梯度只是误差信号乘以前一层激活:

Lwj(o)=(y^y)hj.\frac{\partial L}{\partial w^{(o)}_j} = (\hat y-y)h_j.

梯度继续经过输出权重和隐层 sigmoid 的局部导数,回到每个隐层节点:

Lzj=wj(o)(y^y)hj(1hj).\frac{\partial L}{\partial z_j} = w^{(o)}_j(\hat y-y)h_j(1-h_j).

最后,输入到隐层的每条边都有:

Lwji=Lzjxi.\frac{\partial L}{\partial w_{ji}} = \frac{\partial L}{\partial z_j}x_i.

这就是图中“反向”阶段展示的数值。某个输入为零时,与它相连的权重梯度也会变成零;这不是数值异常,而是链式法则里最后一个乘数恰好为零。

这个例子没有展示什么

为了让所有状态保持可见,图中省略了 batch、优化器、正则化与更深网络中的张量维度。它解释的是反向传播的局部机制,而不是完整训练管线。

真正进入矩阵实现时,仍然是同一件事:前向过程保存反向阶段需要的中间量,损失提供初始梯度,各层再按照计算图的反方向应用局部导数。自动微分框架替我们管理了这张图,但没有改变其中的数学关系。