8.2 方向导数与梯度下降
本节位置:模块 8 · 微积分与优化 | 前置:8.1 多元函数与梯度 | 预计:35 分钟
一句话:方向导数是「沿某个方向的变化率」,它等于梯度与单位方向向量的点积;梯度下降就是每次都沿负梯度方向走一小步。
0. 场景引入
一个 4K 镜头(,约 830 万像素)要在 3 天内渲染完,每帧只给 256 spp 的采样预算,画面里全是颗粒噪声。降噪器有 8 个参数 :一个 滤波核的权重,加 2 个尺度系数。验收标准只有一条——对着 4096 spp 的参考帧算均方误差 。
一次 评估(整段 120 帧逐帧降噪、再与参考比对)在单张 GPU 上约 0.32 秒,约 48 GFLOP。8 个参数、每个试 5 个取值是 种组合,评估一遍要 s,也就是 34.7 小时;而你只有 3 天,还要留出重渲的时间。
所以真正的问题不是「哪个参数最好」,而是:在当前这组参数上,把 8 个参数同时沿某个方向挪一小步, 会变多少?沿哪个方向降得最快?一步该迈多大? 这三个问题,分别对应方向导数、梯度、学习率。
代价:方向选错,边缘被过度平滑,PSNR 掉 1.5 dB,整条镜头返工——按 3 天机时算,直接损失一周排期。
先把问题剥到最小:你在浓雾里下山,只能看见脚下几米,于是朝着最陡的下坡方向迈一小步,停下来重新感受,再迈一步。这就是梯度下降(gradient descent, GD);Curry(1944) 给出了最速下降的经典收敛分析。
读完本节,你应该能回答三件事:
- 为什么方向导数必须沿单位方向定义,不归一化会坏在哪?
- 「梯度是上升最快的方向」怎么用柯西–施瓦茨一步证出来?
- 学习率 到底在替我们假设什么,为什么它和曲率挂钩?
1. 直觉
1.1 方向导数:拿一根探针沿方向戳
在点 处,沿单位方向 走,函数值的变化率就是方向导数(directional derivative)。
它把「梯度」这个箭头投影到 上:投影越长,沿这个方向变化越快。
1.2 为什么负梯度是下坡
梯度指向上升最快的方向(8.1 节)。把它反过来,就是下降最快的方向。
💡 一句话直觉:梯度是「最陡上坡」的箭头;梯度下降是闭着眼沿箭头反方向走小碎步。
类比边界:真实下山可以一步跨很远、可以绕路;GD 每一步都只看局部一阶信息,地形弯曲时「最陡方向」会不断改变。
1.3 它在现实世界里对应什么
浓雾下山的画面,在渲染农场里是这样落地的:
| 数学对象 | 降噪调参里的对应物 | 单位 |
|---|---|---|
| 参数 | 8 个滤波参数:核权重(无量纲)+ 尺度(像素) | 混合 |
| 与参考帧的均方误差 | 灰度² | |
| 单位方向 | 「8 个参数按这个比例一起动」的一次 A/B 对比 | 无量纲 |
| 方向导数 | 沿这条比例动一格,MSE 变多少 | 灰度²/单位步 |
| 梯度 | 8 个参数各自的敏感度 | 灰度²/参数单位 |
量级直觉:8 维参数下, 常在 量级(每单位步的 MSE 变化),学习率取 ,一次更新把参数挪 。在敏感镜头上,参数动 0.001 就能让 PSNR 动 0.1 dB(经验值)——降噪对参数很敏感,对梯度估计的噪声同样敏感。
边界:8 个参数的单位并不统一(核权重无量纲、尺度是像素)。「单位方向」的欧氏长度 在这组混合单位下没有物理意义:把尺度的单位从像素改成「像素的百分之一」,同一个参数方向在坐标里的长度就变了 100 倍。只有当参数被标准化到同一尺度,梯度方向才是「最陡」的物理方向。 这与 8.1 节的单位反事实是同一件事。
这个类比在哪里失效:浓雾下山假设地形静止;渲染的 曲面会随参考帧(不同镜头、不同采样种子)变化,你在一个镜头上调好的方向,换一个镜头未必还陡。工程上必须按镜头类型分组调参,而不是全局一套。
2. 定义
2.1 方向导数
设 在 处可微, 是单位向量()。沿 的方向导数定义为
2.2 与梯度的关系
。读法:方向导数 = 梯度在方向 上的投影。这就是 8.1 节「梯度决定所有方向一阶行为」的定量版本。
2.3 最陡方向
由柯西–施瓦茨不等式,。等号在 时成立。所以:
- 上升最快:,变化率 ;
- 下降最快:,变化率 ;
- 不变:与 正交的任何方向,变化率为 0(沿等高线走)。
2.4 梯度下降更新
,其中 是学习率(learning rate),控制每步长度。
3. 为什么这样定义
为什么方向导数要求 是单位向量?因为「变化率」必须相对单位距离。若允许任意长度,把 放大两倍,差商会跟着放大两倍,数值就不再是「每米升高多少」。
为什么用负梯度而不是别的下降方向?在所有单位方向里,负梯度让一阶下降量最大:,要让它最小,就取 。
但「一阶最优」不等于「全局最优」。当地形弯曲时,最速方向可能让你 zigzag(8.7 节会看到条件数如何造成这种震荡)。
3.1 反事实:方向导数不归一化会坏在哪
取一个能手算的损失 ,在当前点 ,,。
方案 A:不要求 ,直接报 。 取 (第 2 个参数「两格」),得 ;取真正的单位最陡方向 ,得 。于是你会得出「沿参数 2 走最快」的错误结论——那个 8 只是因为 的长度是 2,不是因为它更陡。一旦允许任意长度, 可以要多大有多大,上确界是无穷,「最陡」这个词就失去意义。 梯度的极大性只在单位球 上成立。
方案 B:用「最大偏导方向」代替梯度。 的最大分量在第 2 个坐标,方向 ,变化率 4;真正的最陡方向变化率 4.472。少算了 10.6%,而这 10.6% 会在迭代里被逐步放大。
方案 C:把方向导数定义成「沿 走完整一步的变化量」而不是变化率。 那就成了 ,量纲是「灰度²」,不再可比:步长翻倍,数值翻倍。变化率必须除以步长,这正是定义里那个 的除法在干的事。
三条合起来说明:单位化 + 取极限不是形式主义,而是让「不同方向之间可以比较」的唯一办法。
4. 性质与推导
4.1 方向导数的链式推导
令 ,则 。由多元链式法则 ,代入 即得。
4.2 梯度下降在近似什么
在 附近做一阶近似,并惩罚走太远:
对 求导令其为零,恰好得到 。
这个视角说明:学习率 是在说「我多大程度上相信这个一阶近似」。 小,信任少、走得稳; 大,信任多、可能冲出近似有效的范围。
4.3 二次函数上的收敛条件(预告)
对 ( 对称正定),GD 在特征方向上把误差乘以 。要全部收敛,需要 。8.7 节会完整推导,并用条件数解释为什么有的方向收敛快、有的慢。
5. 例子
5.1 手算:方向导数与两步 GD
设 ,。
梯度 ,在 处为 ,。
方向导数:取单位方向 (因为 ):
最陡上升方向:,变化率 。它比 略大,符合「最陡」。
两步梯度下降():
函数值:,,。每一步都在下降,但步子越来越小,因为梯度也在变小。
5.2 学习率的影响:
此时 。
| 乘子 | 从 出发 | 行为 | |
|---|---|---|---|
| 0.1 | 0.8 | 单调收敛 | |
| 0.5 | 0 | 一步到最优 | |
| 0.6 | 震荡但收敛 | ||
| 1.1 | 发散 |
同一个函数,学习率越过 就从收敛变成发散。这个上界不是拍脑袋,8.7 节会用 Hessian 解释。
5.3 场景闭环:8 个参数、34.7 小时的网格搜索
把开头的镜头走一遍。
输入:8 个参数;一段 120 帧的 4K 序列,每帧 830 万像素 × 3 通道,fp32 下约 100 MB/帧,整段约 12 GB(分块读,常驻显存约 1.2 GB)。参考帧同尺寸。
计算: 与 用中心差分,每个参数两次评估,共 次评估/步, s/步。30 步梯度下降约 s(2.7 分钟),总计算约 FLOP。
输出:一组 8 维参数,以及每步的 曲线。若某步 上升,回退并把学习率减半(回溯线搜索)。最终 PSNR 提升多少取决于镜头,但参数更新的方向和步长是可复算的。
成本:网格搜索 34.7 小时 → 梯度下降 2.7 分钟,约 770 倍;显存只多存 8 个梯度分量,可以忽略。真正的瓶颈是 IO:每次评估都要把 1.2 GB 的序列读一遍,163 s 里绝大部分时间在搬数据,不在算。
失败条件与兜底:
- 学习率过大: 在第 2–3 步开始上下跳,PSNR 抖动。兜底:回溯线搜索,每步试 。
- 一阶近似失效:核权重被推到负值,画面出现振铃(ringing)伪影, 曲面在这里有陡崖。兜底:参数投影回非负区间,并在 里加振铃惩罚。
- 差分噪声: 是 830 万像素的平均,单帧数值误差约 ;中心差分步长取 时信号仍有 量级,够用,再小就被噪声吃掉。兜底:固定步长,并用 3 个不同参考帧重复评估取中位数。
6. 常见误区
-
误区:方向导数可以直接用 ,不管 长度。 纠正:那是「沿 参数化的变化率」。要比较不同方向,必须先归一化;否则 越长数值越大,没有可比性。
-
误区:负梯度方向是「全局最速下降路径」。 纠正:它只是当前点的最速方向。走一步后地形变了,方向要重算;在狭长山谷里会 zigzag。
-
误区:梯度大就该用大学习率。 纠正:步长是 ,梯度大时步长自动变大。学习率控制的是「相对步长」,过大同样会越过极小点。
-
误区:梯度下降总能到全局最优。 纠正:非凸函数只能保证收敛到驻点附近(且依赖初始化)。凸性(8.6 节)才是「局部最优 = 全局最优」的保证。
7. 概念网络
- 前置:8.1 多元函数与梯度 —— 梯度给出方向。
- 后续:8.4 Hessian 与二阶近似 —— 曲率决定学习率上界。
- 后续:8.6 凸性 —— 什么条件下局部下降能到全局最优。
- 后续:8.7 梯度下降与牛顿法 —— 收敛速度、条件数、动量与 Adam。
- 关联:1.3 点积 —— 方向导数就是投影。
8. 通往大模型:每一次 optimizer.step() 都在做这件事
出现位置:训练循环里,loss.backward() 算出 ,optimizer.step() 执行更新。
形状: 和 都是参数张量,形状相同。一个 4096×4096 的线性层,梯度也是 ;优化器还要为它存一阶矩 和二阶矩 (约参数的 2 倍),加上梯度,训练显存通常是参数量的 3–4 倍。
为什么需要:没有方向导数与梯度的关系,就无法把「所有参数一起调」分解成「每个参数按自己的偏导调」。SGD 的更新是
Adam 则用 ,其中 是偏差修正后的一阶、二阶矩。分母逐元素相除,所以形状必须完全一致。
可检验结论:学习率量级和曲率有关。若某层 Hessian 的最大特征值约为 ,那么 时该方向会震荡发散。实践中 warmup 与 layer-wise 学习率,本质上都在避免早期梯度过大、曲率估计失真。
如果学习率或梯度符号弄错,你在画面上看到什么: 过大时,前几步 PSNR 还在涨,随后开始抖动,画面出现周期性的明暗条纹(参数在两套滤波核之间来回跳);梯度符号整体写反,等价于在做梯度上升, 单调抬升,画面越来越糊,直到退化成均值滤波。这两种失败在数值上都不报错,只能靠每步记录 和 PSNR 发现。
9. 练习
- 概念:为什么方向导数定义里要求 ?如果 , 与真实变化率差几倍?
- 计算:,在 处求沿 的方向导数,以及最陡上升方向。
- 计算:,从 出发,,做两步 GD,写出每步的点和函数值。
- 场景:,从 出发。分别取 ,写出前三个迭代值,判断收敛性。
- 开放:如果每个方向的变化率都能算,但计算一次要一小时,你会怎么设计优化策略?
参考答案
- 为了按「单位距离」度量。若 ,则 在 上的变化率是真实方向导数的 2 倍,数值不可比。
- ;。最陡方向 ,变化率 。
- 。,;,。
- 因子 : 时 ,序列 收敛; 时 , 一步到; 时 ,序列 震荡收敛()。
- 可以做零阶/随机方向近似:每次只采样一个方向(SGD 的 mini-batch 就是这种思路),或用低秩/对角近似曲率(Adam、K-FAC);关键是别为「全方向精确」付出不可承受的代价。
10. 一页速记
- , 必须是单位向量。
- 最陡上升:,变化率 ;最陡下降取负号。
- GD 更新:。
- 学习率看曲率:二次函数上要求 。
- 梯度只给方向,学习率决定步长。
- 物理意义 / 现实对应:方向导数是「沿某条调参路线走一格,误差变多少」;梯度是那条最陡的路线;学习率是这一步迈多大。
11. 参考文献与致谢
这一页的知识不是凭空来的。下面列出本页直接借用的原始工作与权威整理;正文中的人名、定理名已链接到对应条目。链接优先指向 DOI、arXiv 或可长期访问的原文存档。
- Curry(1944):The Method of Steepest Descent for Non-Linear Minimization Problems。最速下降法的经典收敛分析;梯度下降「沿负梯度走一小步」的现代形式可追溯到这类工作。Quarterly of Applied Mathematics
- Nocedal & Wright(2006):Numerical Optimization(2nd ed.)。方向导数、梯度与步长的标准处理,本页 §2.4 的更新式与收敛讨论都在其中。Springer
下一篇 → 8.3 Jacobian:多元映射的导数
随堂测 · 4 题
源文件:08-微积分与优化/02-方向导数与梯度下降.md