NingG +

AI 系列:反向传播 & 梯度下降

1.反向传播 Backward Propagation

反向传播 Backward Propagation,是什么?

1.1. 直观理解

反向传播(Backpropagation) 是一种训练神经网络的方法。

它的核心思想是:

  1. 先正向算一遍(forward pass):输入数据 → 经过各层运算 → 得到预测结果。
  2. 算误差(loss):预测结果真实标签之间的差距
  3. 再反向算一遍(backward pass):用 链式法则 逐层计算损失函数对每个参数梯度
  4. 更新参数:把这些梯度传给优化器(SGD/Adam),调整参数,使模型在下一次预测时更接近正确答案。

就像老师给学生判卷子:

1.2. 数学层面

反向传播 = 多层复合函数链式求导。复合函数,参数也是函数、嵌套下去还有参数。

如果神经网络是:

\[y = f(x; W)\]

损失函数是:

\[L = \ell(y, y_{true})\]

那么反向传播要做的是:

\[\frac{\partial L}{\partial W}\]

因为网络有多层:

\[L = \ell(f_n(f_{n-1}(\dots f_1(x; W_1)\dots; W_{n-1}); W_n), y_{true})\]

利用 链式法则,我们从最后一层开始,把梯度一步一步往前“传递”:

\[\frac{\partial L}{\partial W_i} = \frac{\partial L}{\partial f_i} \cdot \frac{\partial f_i}{\partial W_i}\]

所以叫 Back-propagation(反向传播)

1.3. 为什么要“反向”

1.4. 例子

假设网络只有一层:

\[y = w \cdot x, \quad L = (y - t)^2\] \[y = w \cdot x, \quad L = (wx - t)^2\] \[\frac{\partial L}{\partial w} = 2(wx - t)\cdot x\]

更新参数(学习率 η):

\[w \leftarrow w - \eta \cdot \frac{\partial L}{\partial w}\]

1.5.总结

反向传播就是:利用链式法则,把输出误差逐层传回去,计算每个参数的梯度,从而让优化器更新参数,使模型逐渐学会任务。

2.反向传播,耗时

反向传播,需要的计算量确实很大,但有一些规律和优化点。我们分几个层次来看:

2.1. 理论计算量

在神经网络中,反向传播的计算量和正向传播大致同一个量级

因此:

2.2. 为什么计算量大

  1. 参数多:大语言模型(比如 GPT-4、LLaMA2-70B)动辄几十亿上百亿参数,计算量主要来自矩阵乘法
  2. 梯度需要逐层保存:反向传播要用到正向的中间结果(激活值),所以训练时要存储并反向使用。
  3. GPU 显存占用大:不仅要保存参数,还要保存梯度优化器状态(比如 Adam 需要额外保存一阶、二阶矩估计)。

2.3. 和推理(inference)的对比

2.4. 工程优化手段

为了减轻反向传播的开销,常见的优化手段有:

2.5. 总结

反向传播确实需要大量计算,但其复杂度和正向传播同阶,因此训练的计算成本大约是推理的 2–3 倍

在大模型里,计算量大主要来自 参数规模庞大,而不是反向传播的“额外复杂性”。

3.反向传播,耗时细节剖析

疑问:反向传播时,需要计算对「每个参数」的导数,所以,反向传播的耗时应该是 参数量 乘以 正向传播的耗时吧?

回答:

  • 不是的,反向传播的耗时,并不是参数量乘以正向传播的耗时。
  • 有上面的疑问很自然,但实际情况没那么夸张

拆开来看:

3.1. 直觉里的误区

你说的逻辑是:

但实际上,反向传播不会对每个参数单独重跑一次 forward。它用的是 链式法则的共享计算,很多梯度在矩阵运算里是“一次性”批量得到的。

3.2. 一个例子:全连接层

假设有一层:

\[y = W x\]

其中:

正向传播:

\[y = W x \quad \Rightarrow \quad O(mn)\]

反向传播的核心,就是链式法则:

\[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial x}\]

反向传播需要:

  1. 梯度传给输入:

    \[\frac{\partial L}{\partial x} = W^T \frac{\partial L}{\partial y}\]

    也是一个矩阵乘法,复杂度 \(O(mn)\)。

  2. 梯度传给参数:

    \[\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y} \cdot x^T\]

    这其实就是一个 外积,复杂度 \(O(mn)\)。

所以,虽然参数有 \(m \times n\) 个,但所有梯度 一次矩阵乘法就都出来了,并不是对每个参数单独算。

3.3. 复杂度对比

因此:

\[\text{反向传播的复杂度} \approx 2 \times \text{正向传播的复杂度}\]

不是 “参数量 × 正向传播的耗时”。

3.4. 放到大语言模型

在 Transformer 里:

3.5. 结论

反向传播确实要为每个参数算梯度,但不是“逐个参数”算,而是 一次矩阵运算同时得到所有梯度

所以它的计算复杂度和正向传播 同阶,而不是“参数量 × 正向传播耗时”。

4.两次求导

问题反向传播需要两次类似规模的运算(对输入对权重);为什么需要 2 次?是否只需要对 权重 的运算就行了?

回答:这个问题问得非常关键,两次运算是必须的。

4.1. 我们想要的是什么?

反向传播的目标是:

所以通常有两部分:

  1. 参数梯度:\(\frac{\partial L}{\partial W}\)
  2. 输入梯度:\(\frac{\partial L}{\partial x}\)

4.2. 为什么不能只算参数的梯度?

如果只算 \(\frac{\partial L}{\partial W}\):

这就相当于 反向传播断掉了,网络只能更新最后一层,前面层学不到东西。

所以必须同时把梯度“传下去”,让整个网络的所有参数,都能得到更新。

4.3. 全连接层例子

\[y = W x, \quad L = \ell(y)\]

反向传播的核心,就是链式法则:

\[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial x}\] \[\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y} \cdot x^T\] \[\frac{\partial L}{\partial x} = W^T \cdot \frac{\partial L}{\partial y}\]

这两步都需要:

4.4. 总结

5.外积 & 矩阵乘法

问题:反向传播时,为什么有 外积、又有 矩阵乘法?

回答:这个问题问得非常关键,切中了反向传播里“算梯度”的核心。

在反向传播(Backpropagation)中,外积矩阵乘法并不是凭经验硬加进去的,而是严格由复合函数的链式法则推导出来的。

5.1. 正向传播:全连接层

设:

\[y = W x\]

其中:

5.2. 反向传播的两个需求

当我们从上一层(实际上是下一层的 perspective)得到输出梯度 \(\frac{\partial L}{\partial y}\),需要算两样东西:

  1. 对参数的梯度 \(\frac{\partial L}{\partial W}\)

    • 这是优化器用来更新参数的。
  2. 对输入的梯度 \(\frac{\partial L}{\partial x}\)

    • 这是为了把误差信息继续往前一层传递。

5.3. 参数梯度:外积

\[\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y} \cdot x^T\]

它们相乘结果是 \(\mathbb{R}^{m \times n}\),正好和 \(W\) 的形状一样。 这就是一个外积。

直观上:权重矩阵里每个元素 \(W_{ij}\) 的梯度等于 “第 i 个输出的梯度 × 第 j 个输入值”。

5.4. 输入梯度:矩阵乘法

\[\frac{\partial L}{\partial x} = W^T \cdot \frac{\partial L}{\partial y}\]

这里用的是标准的 矩阵乘法

5.5. 为什么两种操作

换句话说:

5.6. 总结

反向传播时:

原文地址:https://ningg.top/ai-series-backward-propagation-gradient-descent-intro/
微信公众号 ningg, 联系我

同类文章:

微信搜索: 公众号 ningg, 联系我, 交个朋友.

Top