梯度下降:方向、步长与噪声怎样共同决定学习
从一维斜率和方向导数出发,手算一次更新,再看学习率、曲率、mini-batch、动量与 Adam 为什么改变训练轨迹。
- 为什么负梯度是局部最陡下降方向,而不是“通往全局最低点的箭头”?
- 怎样从一阶近似推导更新式,并手算一次参数变化?
- 学习率过大、过小和曲率不均分别呈现什么症状?
- mini-batch 的噪声只是缺点吗?动量和 Adam 在改什么?
- 怎样用损失、梯度范数和更新比率定位训练故障?
ŷ=wx。这里 w 是模型要学习的“倍数”参数,真实规律 y=3x 需要 w=3;训练却从故意设错的 w=2 开始。对样本 x=2,y=6,模型预测 4,半平方损失 L=½(ŷ−y)² 为 2,损失对 w 的梯度为 −4。本页要回答:为什么要减去梯度,以及一步究竟能走多远。1只看脚下斜率,为什么还能下山直觉
如果看不见整张损失地形,只知道当前位置往各方向倾斜多少,下一小步该怎么选?
只有一个参数时,导数就是当前位置的斜率:导数为正,向右一小步会让损失上升,因此应试着向左;导数为负则相反。
模型通常有很多参数。训练程序读取当前位置的参数与损失函数,计算时先固定其他参数求每一维斜率:我们暂时只改变其中一个、把其他参数固定,得到的斜率叫这个参数的偏导数。再把这些斜率按顺序排成一个向量,输出的就是梯度。例如两个参数的梯度 (3,−1) 表示:第一个参数增大时损失上升得很快,第二个参数增大时损失反而下降。
某个梯度分量绝对值较大,表示损失在该坐标附近更敏感;但梯度不是整张地图,不能据此断言这个参数更重要,也不知道远处最低点在哪里。
2为什么负梯度在局部下降最快数学
“梯度指向上升最快”是比喻,还是能由公式推出的结论?
先用语言理解:梯度把每个参数“往正方向动一点会让损失怎样变化”记录下来。给定当前位置的梯度和允许迈出的长度,我们要选出一条下降单位方向;若想让各分量的变化尽量反过来,就应朝每个分量都取反的方向移动,也就是负梯度。
公式把这件事写得更精确。θ 表示当前全部参数,Δθ 表示准备迈出的一小步,J 是训练目标。只看很小的局部范围时:
J(θ+Δθ) ≈ J(θ)+∇J(θ)·Δθ
点积可以理解为“这一步在梯度方向上投影了多少”:同向时为正,损失倾向上升;反向时为负,损失倾向下降。若把一步的欧氏长度固定为 ε,先用点积估计每个候选位移造成的损失变化,完全朝梯度反方向走会让点积最负,因此在这一阶近似里下降最多:
||∇J|| 是梯度向量的长度;除以它只保留方向,再乘 ε 决定这一步多长。这个结论只保证“当前位置附近、同样短的一步”最陡,不保证通往全局最低点。
可选证明:为什么反方向使点积最小?
柯西—施瓦茨不等式给出 ∇J·Δθ ≥ −||∇J||·||Δθ||。当两向量方向完全相反时取到等号;固定 ||Δθ||=ε 后,右侧就是可能达到的最小一阶变化。
3更新式怎样从局部近似落到参数上数学
有了方向,怎样把它写成训练循环里真正执行的一步?
更新式把抽象方向变成训练程序真正执行的动作:输入当前参数、当前或小批估计的梯度以及学习率,输出下一步参数。逐项翻译这个公式:
t是当前第几次更新;θt是更新前的全部参数,θt+1是更新后的参数;gt是当前位置的梯度,或由一小批样本估计出的梯度;ηt读作 eta,是学习率,控制这次沿梯度走多远;- 前面的减号表示朝梯度反方向走。
程序先计算梯度,再用学习率缩放,最后从旧参数中减去这段改变量。现在回到页首已经定义的例子:w 是倍数参数,理想值为 3,当前错误初始值为 2。当前梯度是 −4,取学习率 η=0.1:
| 量 | 更新前 | 更新后 |
|---|---|---|
| 参数 | w=2 | 2−0.1×(−4)=2.4 |
| 预测 | 2×2=4 | 2.4×2=4.8 |
| 损失 | ½(4−6)²=2 | ½(4.8−6)²=0.72 |
损失从 2 降到 0.72 表示这一次局部移动有效;但单步下降不能证明后续每步稳定,也不能证明模型已学会真实规律或能泛化到新样本。若取 η=1,会得到 w=6、预测 12、损失 18:同一个正确梯度,被过大步长用坏了。
4学习率为什么存在稳定上限曲率
“足够小”到底受什么控制,为什么碗壁越陡就越容易一步跨过谷底?
曲率描述斜率变化得有多快。平缓地面上多走一点,斜率变化不大;陡峭而弯曲的碗壁上多走一点,斜率可能迅速反号,于是一步从谷底左侧跨到右侧。学习率必须小到让局部斜率仍有参考价值。
贯穿示例可以给出一个完全具体的答案。这里 w 仍是模型要学习的倍数参数,J(w) 是参数取值对应的损失,g(w) 是损失对 w 的梯度,η 是学习率。把 ŷ=2w、y=6 代入半平方损失:
梯度 g(w)=4(w−3)
最优参数是 w*=3。定义当前参数离最优值的距离 et=wt−3,更新一步后:
这里以局部曲率和学习率为输入,先得到误差倍率 1−4η,再检查其绝对值是否小于 1:绝对值小于 1 才会逐步收缩;倍率为负表示每一步越过最优点,在两侧来回摆动。
| 学习率 η | 误差倍率 1−4η | 从 w=2 更新一次 | 含义 |
|---|---|---|---|
| 0.1 | 0.6 | w=2.4,损失 0.72 | 不跨谷底,稳定靠近 |
| 0.25 | 0 | w=3,损失 0 | 这个理想二次例子中恰好一步到达 |
| 0.4 | −0.6 | w=3.6,损失 0.72 | 跨过谷底,但误差仍缩小 |
| 0.5 | −1 | w=4,损失仍为 2 | 两侧等幅震荡,不再靠近 |
| 1 | −3 | w=6,损失 18 | 误差放大,训练发散 |
一般二次函数写成 J(w)=½a(w−w*)²,其中 a 就控制曲率,稳定条件是 0<η<2/a。a 越大,安全上限越低。真实神经网络不是一个完美二次碗,曲率也会随位置变化,因此这个区间解释局部稳定边界,不是所有训练过程通用的固定许可证。
5狭长谷地为什么让普通梯度之字形前进几何
“狭长谷地”不是一种新算法,而是两个参数方向陡峭程度相差很大的损失地形。
想象损失由两个参数决定,把相同损失的点连起来会得到一圈圈等高线。若等高线接近圆形,各方向陡峭程度相近;若它们被拉成长椭圆,就像一条狭长山谷:
- 横穿山谷的方向很陡:参数稍微变化,损失就变化很大;
- 沿着谷底的方向很平:要走较远,损失才明显变化;
- 最低点在谷地深处:训练真正想沿谷底向前,但梯度常被两侧陡坡主导。
从当前损失曲面和起点出发,普通梯度下降会输出一条参数轨迹;如果各方向曲率差异很大,这条轨迹就能解释“梯度不为零、损失也在降,训练却很慢”的现象。
计算更新时,梯度先被陡方向主导。统一学习率必须照顾横向陡坡,不能太大;但同一个小学习率用在谷底方向又显得太小,于是轨迹一边横向反复摆动,一边缓慢向最低点挪动。第 7 节的动量会记住长期一致的谷底方向,并部分抵消左右交替的摆动。
之字形越明显通常说明尺度不均越严重,但图形会受参数坐标和缩放影响,不能只凭二维示意图诊断真实高维网络。这里的高维是指参数坐标数量很多;提到它是为了提醒读者,二维等高线只能帮助理解局部机制。
6mini-batch 为什么故意使用不精确梯度随机性
既然全量数据能给更准确的梯度,为什么深度学习通常用一小批样本估计?
全量梯度先计算训练集中每个样本的梯度,再求平均,完成后才更新一次参数。mini-batch(小批量)输入随机抽取的一组样本和当前参数,只对这组样本求平均梯度,然后立刻更新;换一批样本后重复这一过程。只要抽样方式合理,小批梯度长期平均才接近全量梯度,但某一步会有抽样误差,所以轨迹会抖动。
例如训练集有 100 万个样本、批量大小为 256:全量方法必须处理完 100 万个样本才反馈一次;小批方法一个数据轮次大约可以反馈 1,000,000/256≈3906 次。两者看完一轮数据的样本计算量相近,但单次更新的等待时间和反馈频率完全不同。
这里的硬件效率主要指单位时间能处理多少样本、计算单元是否充分工作,以及需要多少显存和设备间通信:
- 批量太小,GPU 每次只做一点工作,启动和搬运数据的开销占比高,很多计算单元闲着;
- 批量增大,矩阵运算更容易并行,单位时间吞吐通常提高;
- 批量过大,会占用更多显存,多台设备还要同步大量梯度;全量数据通常根本放不进显存,等待一次更新也很久。
| 批量 | 梯度噪声 | 硬件表现 | 训练含义 |
|---|---|---|---|
| 很小 | 大 | 反馈快,但 GPU 可能吃不满 | 更新频繁而抖动,学习率通常较小 |
| 中等 | 可控 | 并行度和显存占用通常较平衡 | 最常见的吞吐/噪声折中 |
| 很大 | 小 | 样本吞吐高,但显存与同步开销上升 | 每轮更新次数减少,需重调学习率 |
| 全量 | 没有抽样噪声 | 单次更新需读完全部数据,可能跨设备同步 | 每一步精确,不代表达到目标所需总时间更短 |
批次之间抖动大表示估计方差较高,不必然代表训练失败;噪声有时能帮助越过局部平坦区域,但不能把它神化成自动找到更好解。批量大小仍受显存、吞吐、设备同步和任务泛化共同约束,改变批量后,学习率、更新次数和验证表现都应重新比较。
7从 SGD 到动量和 Adam优化器
优化器是“拿到梯度后怎样更新参数”的规则;三种方法的差别在于是否记住历史。
这些规则共同输入当前梯度与超参数,输出新参数,用来缓解批次噪声、往返摆动和参数尺度差异。SGD 是 stochastic gradient descent,即随机梯度下降。历史上“随机”可指每次只用一个随机样本;现代训练通常也把使用一个随机 mini-batch 的更新称为 SGD。它每一步拿当前小批梯度 gt 直接更新:
SGD 简单、额外内存少,但当前批次若有噪声,方向就会跟着抖;在狭长谷地中也容易左右摆动。
动量(Momentum)增加一个“速度” v,把过去梯度的衰减平均保留下来:
θt+1=θt−ηvt
β 控制记忆有多长。连续多步同向的分量会累积;左右交替的分量会互相抵消。因此它能沿谷底加速,并减少横向摆动。
Adam 同时保存两种历史:m 是梯度的移动平均,可理解为近期方向;v 是平方梯度的移动平均,可理解为近期尺度。更新时用 m/v 调整每个参数的有效步长:长期梯度较大的坐标会被适当缩小,较小的坐标相对放大。正式实现还包含防止除零的 ε 和训练初期的偏差修正。
| 方法 | 记住什么 | 主要作用 | 代价或边界 |
|---|---|---|---|
| SGD | 不保存梯度历史 | 规则简单、额外内存小 | 容易受批次噪声和狭长谷地影响 |
| Momentum | 近期梯度方向 | 强化持续方向、抵消往返摆动 | 仍需选择学习率和记忆系数 β |
| Adam | 近期方向与平方梯度尺度 | 为不同参数自适应缩放步长 | 每个参数需额外状态;默认设置不保证所有任务或泛化都最好 |
更平滑或更快的训练曲线只说明当前配方下优化更顺,不代表 Adam 必然泛化最好。
8预热、衰减和梯度裁剪分别解决什么工程
它们分别控制训练初期、训练后期和偶发异常步,不是三个可互换的名字。
实际执行时,预热与衰减根据当前训练步和学习率日程给出本步实际学习率;裁剪则读取梯度长度,再决定是否缩短。三者改的不是同一个量:前两者改学习率,裁剪改本步梯度。
观察曲线时,训练初期不再猛冲、后期震荡减弱和偶发尖峰被截住,分别表示对应机制正在起作用;下面按执行顺序拆开看。
| 方法 | 怎样执行 | 看到什么说明在起作用 | 失效边界 |
|---|---|---|---|
| 预热 Warmup | 训练开始时先输出很小的实际学习率,再在前若干步逐渐升到目标值,给参数和 Adam 的历史统计留出稳定时间。 | 训练最初几步不再突然发散,第一批更新不再大步猛冲。 | 只保护训练开头,不能修复长期过大的学习率。 |
| 学习率衰减 | 训练前期用较大步长找方向,后期逐渐缩小步长做精细调整;cosine decay 只是按余弦曲线下降的一种日程。 | 接近低损失区域后,后期在低点附近的来回震荡减弱。 | 不能修复错误梯度或错误目标。 |
| 梯度裁剪 | 先计算梯度向量长度;若超过阈值 C,只在超过阈值时按比例缩短,再把受限梯度交给优化器。 | 某个异常批次造成的更新尖峰被截住;同时应记录多少步触发、每次裁掉多少。 | 不能代替正常学习率选择,也不能消除持续梯度爆炸的根因。若几乎每步都触发或损失仍持续发散,应继续检查异常批次、数值溢出和模型结构。 |
9一次训练停滞怎样逐层诊断运行示例
看到损失不降时,先确认信号在哪一环断掉,不要一上来就换 Adam 碰运气。
这套诊断流程把“损失不降”拆成可验证的故障假设。它接收小样本实验、预测与标签、梯度范数、更新比率和验证曲线,逐步缩小数据、计算链、步长、优化器或目标错位的排查范围:
- 先做“小样本记忆测试”:只给模型几十个样本,反复训练到几乎记住它们。连这都做不到,通常不是泛化问题,而是数据、损失或更新链没有接通。
- 核对预测和损失输入:直接打印少量样本的输入、目标、预测和单样本损失,确认标签没有错位、需要计算损失的位置没有被全部遮掉。
- 查看梯度长度:梯度范数就是所有参数梯度组成向量的长度。持续为 0 时,检查参数是否被“冻结”(排除在更新之外)或计算链是否被意外切断;突然出现巨大尖峰时,检查异常批次和数值溢出。
- 查看实际更新有多大:计算
||Δθ||/||θ||,即“参数这一步改变量的长度 ÷ 参数自身长度”。梯度非零但这个比率接近 0,说明学习率太小、数值精度吞掉了变化,或优化器没有更新到目标参数。 - 做学习率短跑:用多个从小到大的学习率各训练很少几步,找到“开始明显下降”和“开始震荡或发散”的区间,而不是直接跑完整实验。
- 再比较优化器与日程:固定模型、数据顺序、批量和训练步数,每次只换 SGD、动量、Adam 或学习率日程中的一个因素。
- 最后看独立验证:训练损失下降更快只说明代理目标优化更快;停止点仍应由未参与更新的数据和真实任务指标决定。
这个顺序先证明模型能记住小样本,再核对损失输入和梯度,随后检查真实更新,最后才比较优化器与独立验证。某一项异常只缩小排查范围,并不自动证明唯一根因;日志口径错误、随机波动和多个故障同时存在时仍需受控对照实验。
10把整条因果链连起来综合
从局部斜率到可靠训练,每一环怎样约束下一环?
- 损失把当前预测质量写成标量。
- 梯度给出该标量对每个参数的局部敏感度。
- 负梯度在给定几何下使一阶近似下降最快。
- 学习率把方向变成实际距离,必须尊重局部曲率。
- mini-batch 用有噪估计换取更频繁、可并行的更新。
- 动量、预条件和调度改善轨迹与不同阶段的步长。
- 诊断指标确认梯度、更新和数值状态真实有效。
- 独立验证决定这条优化轨迹是否也改善未知数据和真实任务。
11常见误解消歧
| 误解 | 更准确的说法 |
|---|---|
| 梯度指向全局最优 | 它只描述当前位置的局部一阶变化。 |
| 负梯度每一步都让真实损失下降 | 步长过大或梯度有噪时,单步可以上升。 |
| 反向传播就是梯度下降 | 前者算梯度,后者使用梯度更新参数。 |
| 更大 batch 的梯度更准,所以一定更好 | 还要考虑更新频率、算力、学习率重调与泛化。 |
| Adam 永远优于 SGD | 收敛速度、内存、稳定性和最终泛化取决于任务与配方。 |
12检查你是否真的理解自测
从局部斜率、具体手算走到批量和优化器选择;答案必须解释符号或机制。
- 偏导数和梯度分别是什么?为什么梯度不是通往全局最低点的地图?
- 只看局部一阶近似时,为什么固定长度的一步沿负梯度下降最多?
- 贯穿示例中学习率为 0.25 时,一步后
w、预测和损失是多少? - 在
J(w)=2(w−3)²中,为什么 η=0.4 会跨过最优点却仍收敛,而 η=1 会发散? - “狭长谷地”具体表示哪两个方向的曲率关系?为什么轨迹会之字形前进?
- mini-batch 的“硬件效率较好”具体指什么?为什么批量并非越大越好?
- SGD、Momentum 和 Adam 分别记住哪些历史信息?它们怎样改变狭长谷地中的轨迹?
- 预热、学习率衰减和梯度裁剪分别应对训练的哪个阶段或哪类异常?
参考答案
- 偏导数是在其他参数固定时,一个参数变化对应的损失斜率;梯度是所有偏导数组成的向量。它只描述当前位置附近的一阶变化,不知道远处地形、障碍或全局最低点。
- 局部损失变化近似为梯度与位移的点积。固定欧氏长度时,位移和梯度完全反向会使点积达到最小,因此一阶预测下降最多。
- 当前梯度为 −4,所以
w=2−0.25×(−4)=3;预测为 6,半平方损失为 0。在这个理想一维二次例子中恰好一步到最优点。 - 误差倍率为
1−4η。η=0.4 时倍率 −0.6,负号表示跨到另一侧,但绝对值 0.6<1,所以误差缩小;η=1 时倍率 −3,误差每步放大三倍,因此发散。 - 横穿谷地的方向曲率大、沿谷底的方向曲率小。统一学习率受陡方向限制;梯度又常被陡坡主导,于是左右摆动明显、沿谷底前进缓慢。
- 指单位时间样本吞吐、计算单元利用率、显存和通信开销。小批量可能吃不满 GPU;过大批量占显存、同步昂贵且每轮更新次数少,所以要在吞吐、噪声和反馈频率间折中。
- SGD 只使用当前小批梯度;Momentum 保存近期方向,累积持续分量并抵消交替摆动;Adam 还保存平方梯度尺度,为不同参数调整有效步长。它们改善轨迹,但不能改变或修复错误目标。
- 预热在训练初期逐渐升高学习率;衰减在后期缩小步长以减少震荡;裁剪限制偶发巨大梯度,防止单步爆炸。三者不能互相替代。
13概念依赖与延伸学习路线
| 方向 | 接下来读 | 关键问题 |
|---|---|---|
| 梯度从哪里来 | 反向传播 | 怎样用一次逆向遍历得到全部参数梯度? |
| 目标由谁定义 | 损失函数 | 局部优化的标量是否与真实目标一致? |
| 步长怎样随时间变化 | 优化器与学习率调度 | 预热、衰减、AdamW 分别解决什么? |
| 深层梯度为什么异常 | 梯度消失、残差连接 | 网络结构怎样改变梯度路径? |
| 训练好却验证差 | 过拟合 | 优化成功为什么不等于泛化成功? |
- Deep Learning — Numerical Computation:用于核对导数、梯度、曲率、条件数和局部下降。
- Deep Learning — Optimization for Training Deep Models:用于核对小批量随机优化、动量和训练诊断。
- Practical Recommendations for Gradient-Based Training of Deep Architectures:用于核对 SGD、批量、学习率与实践建议。
- Adam: A Method for Stochastic Optimization:用于核对一阶矩、平方梯度二阶矩与自适应更新。
图示、数值例子和诊断链均为本项目原创组织。