AI 系列:反向传播 & 梯度下降
2025-09-13
1.反向传播 Backward Propagation
反向传播
Backward Propagation
,是什么?
1.1. 直观理解
反向传播(Backpropagation) 是一种训练神经网络
的方法。
它的核心思想是:
- 先正向算一遍(forward pass):输入数据 → 经过各层运算 → 得到预测结果。
- 算误差(loss):预测
结果
和真实标签
之间的差距
。 - 再反向算一遍(backward pass):用
链式法则
逐层计算损失函数对每个参数
的梯度
。 - 更新参数:把这些梯度传给
优化器
(SGD/Adam),调整参数,使模型在下一次预测
时更接近正确答案。
就像老师给学生判卷子:
- 正向传播 = 学生写答案。
- 算 loss = 老师打分。
- 反向传播 = 老师告诉学生“错在哪儿”,每道题的错误量分摊到知识点上。
- 参数更新 = 学生根据反馈改进。
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\]- 正向:
- 反向(对 w 求导):
更新参数(学习率 η):
\[w \leftarrow w - \eta \cdot \frac{\partial L}{\partial w}\]1.5.总结
反向传播就是:利用链式法则
,把输出误差
逐层
传回去,计算每个参数的梯度,从而让优化器更新参数
,使模型逐渐学会任务。
2.反向传播,耗时
反向传播,需要的计算量确实很大
,但有一些规律和优化点。我们分几个层次来看:
2.1. 理论计算量
在神经网络中,反向传播
的计算量和正向传播
大致同一个量级。
- 正向传播:输入向量逐层做
矩阵乘法
、非线性变换
,得到输出。 - 反向传播:需要把 loss 对输出的梯度“乘回来”,同样涉及
矩阵乘法
和逐元素操作
。
因此:
- 如果正向传播耗时
T
,反向传播也大约是O(T)
,整体训练一次(forward + backward)大概耗时2T
左右。
2.2. 为什么计算量大
- 参数多:大语言模型(比如 GPT-4、LLaMA2-70B)动辄几十亿上百亿参数,计算量主要来自
矩阵乘法
。 - 梯度需要逐层保存:反向传播要用到正向的
中间结果
(激活值),所以训练时要存储
并反向使用。 - GPU 显存占用大:不仅要
保存参数
,还要保存梯度
和优化器状态
(比如 Adam 需要额外保存一阶、二阶矩估计)。
2.3. 和推理(inference)的对比
- 推理(inference):只做正向传播。
- 训练(training):要做
正向
传播 +反向
传播 +参数
更新。 - 一般训练的计算量 ≈ 推理的 2~3 倍。
2.4. 工程优化手段
为了减轻反向传播的开销,常见的优化手段有:
- 混合精度训练(FP16 / bfloat16):减少显存和计算量。??? 如何混合?
- 梯度检查点(gradient checkpointing):不保存所有中间激活,反向时
部分重算
,用计算换显存。 - 分布式训练:
数据
并行、模型
并行、流水线
并行,3类并行措施。 - 稀疏化:利用注意力或权重的
稀疏结构
,减少无效计算。???细节?
2.5. 总结
反向传播确实需要大量计算,但其复杂度和正向传播同阶,因此训练的计算成本大约是推理的 2–3 倍。
在大模型里,计算量大
主要来自 参数规模庞大,而不是反向传播的“额外复杂性”。
3.反向传播,耗时细节剖析
疑问:反向传播时,需要计算对「每个参数」的导数,所以,反向传播的耗时应该是 参数量 乘以 正向传播的耗时吧?
回答:
- 不是的,反向传播的耗时,并
不是
参数量乘以正向传播的耗时。- 有上面的疑问很自然,但实际情况没那么夸张
拆开来看:
3.1. 直觉里的误区
你说的逻辑是:
- 有 N 个参数
- 需要算对每个参数的梯度
- 所以好像需要 “N 次” 正向传播
但实际上,反向传播
不会对每个参数单独重跑一次 forward。它用的是 链式法则的共享计算
,很多梯度在矩阵运算
里是“一次性”批量得到的。
3.2. 一个例子:全连接层
假设有一层:
\[y = W x\]其中:
- \(W\) 是形状 \([m, n]\) 的参数矩阵(有 \(m \times n\) 个参数)。
- \(x \in \mathbb{R}^n\),\(y \in \mathbb{R}^m\)。
正向传播:
\[y = W x \quad \Rightarrow \quad O(mn)\]反向传播的核心,就是链式法则:
\[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial x}\]反向传播需要:
-
梯度传给输入:
\[\frac{\partial L}{\partial x} = W^T \frac{\partial L}{\partial y}\]也是一个矩阵乘法,复杂度 \(O(mn)\)。
-
梯度传给参数:
\[\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y} \cdot x^T\]这其实就是一个 外积,复杂度 \(O(mn)\)。
所以,虽然参数有 \(m \times n\) 个,但所有梯度 一次矩阵乘法就都出来了,并不是对每个参数单独算。
3.3. 复杂度对比
- 正向传播:大约一次矩阵乘法 → \(O(mn)\)。
- 反向传播:需要
两次
类似规模的运算(对输入
、对权重
),所以大约也是 \(O(mn)\)。
因此:
\[\text{反向传播的复杂度} \approx 2 \times \text{正向传播的复杂度}\]而不是
“参数量 × 正向传播的耗时”。
3.4. 放到大语言模型
在 Transformer 里:
- 最重的操作是
自注意力 (QK^T)
和前馈网络
(矩阵乘法)。 - 这些地方的参数梯度,同样通过
大矩阵运算
一次性得到。 - 所以整体规律依旧成立:训练的计算量 ≈ 2–3 倍推理的计算量。
3.5. 结论
反向传播
确实要为每个参数算梯度
,但不是“逐个参数”算,而是 一次矩阵运算同时得到所有梯度。
所以它的计算复杂度和正向传播 同阶,而不是“参数量 × 正向传播耗时”。
4.两次求导
问题:
反向传播
需要两次类似规模的运算(对输入
、对权重
);为什么需要 2 次?是否只需要对权重
的运算就行了?回答:这个问题问得非常关键,两次运算是必须的。
4.1. 我们想要的是什么?
反向传播的目标是:
- 更新参数 → 需要得到 \(\frac{\partial L}{\partial W}\)(权重的梯度)。
- 继续传递误差 → 需要得到 \(\frac{\partial L}{\partial x}\)(输入的梯度),这样才能把梯度传回到前一层。
所以通常有两部分:
- 参数梯度:\(\frac{\partial L}{\partial W}\)
- 输入梯度:\(\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 x}\) → 用来
继续往前传递
。
4.4. 总结
- 如果只需要更新最后一层(比如做 logistic 回归),只算
权重梯度
就够了。 - 但在
深层网络
里,必须同时算输入梯度
,否则误差
无法往前传播
,前面层的参数得不到更新。 - 所以在一般的深度学习框架里,反向传播每层都会做“两次类似规模的运算”:
- 梯度 wrt 权重(更新参数)
- 梯度 wrt 输入(往前传)
5.外积 & 矩阵乘法
问题:反向传播时,为什么有 外积、又有 矩阵乘法?
回答:这个问题问得非常关键,切中了反向传播里“算梯度”的核心。
在反向传播(Backpropagation)中,外积
和矩阵乘法
并不是凭经验硬加进去的,而是严格由复合函数的链式法则推导
出来的。
5.1. 正向传播:全连接层
设:
\[y = W x\]其中:
- \(W \in \mathbb{R}^{m \times n}\) (权重矩阵,参数)
- \(x \in \mathbb{R}^n\) (输入向量)
- \(y \in \mathbb{R}^m\) (输出向量)
5.2. 反向传播的两个需求
当我们从上一层(实际上是下一层的 perspective)得到输出梯度 \(\frac{\partial L}{\partial y}\),需要算两样东西:
-
对参数的梯度 \(\frac{\partial L}{\partial W}\)
- 这是优化器用来更新参数的。
-
对输入的梯度 \(\frac{\partial L}{\partial x}\)
- 这是为了把误差信息继续往前一层传递。
5.3. 参数梯度:外积
\[\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y} \cdot x^T\]- \(\frac{\partial L}{\partial y} \in \mathbb{R}^m\)(列向量)
- \(x^T \in \mathbb{R}^{1 \times n}\)(行向量)
它们相乘结果是 \(\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}\]- \[W^T \in \mathbb{R}^{n \times m}\]
- \[\frac{\partial L}{\partial y} \in \mathbb{R}^m\]
- 结果是 \(\mathbb{R}^n\),正好和 \(x\) 的形状一样。
这里用的是标准的 矩阵乘法。
5.5. 为什么两种操作
- 外积:更新参数。
- 告诉我们每个权重,对损失的贡献是多少。
- 矩阵乘法:传播误差。
- 把误差“加权”传回去,让前一层知道自己该如何调整。
换句话说:
- 外积是 “
算责任
(每个参数
该改多少)”。 - 矩阵乘法是 “
传口信
(告诉前一层
你要改多少)”。
5.6. 总结
反向传播时:
- 外积 出现在
参数梯度计算
中:\(\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}\)。 - 这两步缺一不可:一个用来更新参数,一个用来继续传递梯度。
原文地址:https://ningg.top/ai-series-backward-propagation-gradient-descent-intro/