计算机视觉-04:优化与梯度下降
优化器
统一记号:
- 目标函数(loss):,参数向量:
- 第 次迭代(iteration)参数:
- 梯度:
- 学习率:
- mini-batch:,其梯度估计记为
- 动量法中的速度变量记为 ;Adam 系列中的一阶矩、二阶矩分别记为
优化器是在反向传播给出梯度之后,决定“参数往哪里走、走多远”的更新规则,一个最常见的形式是损失最小化:
反向传播(backprop)负责高效地算出梯度 ;优化器负责把梯度变成一次次参数更新。
Vanilla GD(批量梯度下降,Batch Gradient Descent)
最朴素的梯度下降每次用全量数据计算精确梯度,然后沿负梯度更新:
优点:
- 梯度精确、更新方向稳定;对凸问题有清晰理论。
缺点:
- 每步都要扫全数据集,代价高;大模型/大数据下几乎不可用。
- 对非凸深网也不具备“逃离坏点”的随机性。
SGD(随机梯度下降,Stochastic Gradient Descent)
SGD 每次只用一个样本(或极小 batch)来计算梯度:
优点:
- 单步开销小、更新频繁;在大数据下非常高效。
- 梯度噪声有时反而有益:更容易“抖”出鞍点或糟糕的局部区域。
缺点(直觉上也最常见):
- 更新噪声大,loss 曲线抖动明显。
- 在狭长沟壑(某些维度很陡、某些维度很平)中容易来回震荡。
- 在鞍点附近(一个方向上凸、另一个方向上凹)可能进展很慢。

图 a) 中,起点的位置会影响梯度下降的结果:在点 1,3 处,参数梯度下降到了全局最小值,而在 2 处,错误的起点使其下降到了局部最小值。在图 b) 中,SGD 的更新方向由于噪声的存在而变得不稳定,从而使得参数能够跳出鞍点区域,继续向下优化。
Mini-batch SGD
实践中最常见的是 mini-batch SGD:用一个小批量 在当前位置 估计梯度:
它介于 GD 和 SGD 之间:
- batch 变大 → 梯度方差更小、更新更稳,但单步更贵。
- batch 变小 → 更新更“吵”,探索更强,但可能更难调、吞吐不一定更高。
工程里通常按硬件吞吐与收敛稳定性折中选 batch size;并配合学习率缩放(例如线性缩放)与 warmup。
SGD with Momentum(动量法)
动量法的核心是引入“速度”变量 ,对梯度方向进行指数平滑,从而减少震荡并加速沿一致方向的前进:
其中 是动量系数,常见经验值是 0.9。
优点:
- 在“长沟壑”场景明显加速;抑制来回震荡。
- 比 vanilla SGD 更稳、更好调。
缺点:
- 仍可能在某些非凸区域走得过头(overshoot)。
- 额外超参数()与更复杂的调度策略。

直观上看无动量的随机梯度下降以非直接的路径接近最小值,而有动量的随机梯度下降则由前一段优化方向和当前 batch 的梯度加权组合产生,可以平滑轨迹加快收敛。
Nesterov Momentum(NAG,Nesterov 加速梯度)
Nesterov 的直觉是“先按动量往前看一步,再在那个位置上评估梯度”,因此更像是在用更前瞻的梯度修正动量方向。
一种常见写法是:
优点:
- 在很多任务上比普通 Momentum 稍稳,收敛更“聪明”。
缺点:
- 仍需调学习率与动量。

Second-order methods(二阶方法)
深度学习优化里还有一类很常见的思路是基于 Newton’s method(二阶方法),其核心迭代为:
其中 是损失函数 关于参数 的 Hessian 矩阵(由二阶偏导数组成的方阵), 是梯度向量。直觉上,Hessian 描述了损失函数的局部曲率:乘上 Hessian 的逆,会让优化在“曲率较小(更平坦)”的方向迈更大步,在“曲率较大(更陡)”的方向迈更小步。注意这个更新式里没有显式学习率超参数,这也是二阶方法常被拿来对比一阶方法的一个优点。
但在深度学习里直接计算并求逆 Hessian 往往不可行:时间和空间开销都极其昂贵。比如一个有 100 万参数的网络,Hessian 是 的矩阵,显式存储就需要约 3725 GB 内存。
因此出现了大量 quasi-Newton(拟牛顿)方法来近似 。其中最常见的是 L-BFGS:它利用一段时间内的梯度信息来隐式构造近似(不显式存整张矩阵)。
但即使缓解了内存问题,L-BFGS 的一个朴素应用仍然通常需要在全量训练集上工作;而把它可靠地用在 mini-batch 上更困难,至今仍是研究/工程上的活跃方向。
所以在大规模深度学习与 CNN 训练中,目前更常见的仍是基于(Nesterov)Momentum 的 SGD 变体:实现更简单、扩展性更好。
AdaGrad(自适应学习率:累积平方梯度)
AdaGrad 的动机是:不同参数维度的更新频率差异很大(例如稀疏特征/embedding),希望“常更新的参数走慢点,少更新的参数走快点”。
做法:对每个参数维护平方梯度累积 :
其中 、、除法都是逐元素(element-wise), 防止除 0。
优点:
- 在稀疏特征场景非常强;对每个参数都有自适应步长。
缺点:
- 单调增大,导致有效学习率单调衰减,训练后期可能“走不动”。
RMSProp(自适应学习率:滑动平均平方梯度)
RMSProp 可以看作对 AdaGrad 的“降温”:不再把所有历史平方梯度都累积进去,而是用指数滑动平均跟踪一个有限时间尺度内的平方梯度。远离当前时间点的梯度信息会被逐渐丢弃,从而避免学习率过快衰减的问题。
其中 常取 0.9 或 0.99。
优点:
- 避免 AdaGrad 学习率过快衰减;在很多深网任务上表现稳定。
缺点:
- 仍需要调学习率;不同任务对 也可能敏感。
AdaDelta(自适应学习率:进一步减少对初始学习率依赖)
AdaDelta 也是“滑动窗口”的思想:它在 RMSProp 的基础上,进一步把更新步长做得更自洽,尽量减少对手工设定初始学习率的依赖。
一种常见的表达是同时跟踪:平方梯度的滑动平均 与平方更新量的滑动平均 :
优点:
- 经验上更不容易出现“有效学习率衰减到 0”的尴尬。
缺点:
- 现代深度学习中常被 Adam/AdamW 取代;生态与默认配置更少。
Adam(Adaptive Moment Estimation)
Adam 可以理解为:
- Momentum:对梯度做一阶动量(均值)的滑动平均
- RMSProp:对平方梯度做二阶动量(方差规模)的滑动平均
更新(逐元素)为:
由于 会导致早期偏置(bias),使得初始动量估计偏小,Adam 通常使用偏置修正:
初始时将 和 放大,抵消 和 靠近 0 的影响。随着时间推移,修正项趋近于 1,对原始动量的影响减小。
最终更新:
经验默认值常见为:。
优点:
- 收敛快、对学习率不那么敏感;新任务上很适合快速跑通 baseline。
潜在缺点(常见讨论点):
- 在部分设置下可能出现训练后期震荡或泛化不如精调的 SGD 系列。

还有 note 上的动图:


Nadam(Nesterov + Adam)
Nadam 把 Nesterov 的“lookahead”思想融入 Adam 的一阶动量中,本质上是用更前瞻的方式来计算动量项,从而在一些任务上获得更快或更稳的收敛。
一个常用、也比较容易和代码对齐的 Nadam(带 bias correction)可以写成:
先算 Adam 的动量与偏置修正:
然后把 Nesterov 的“lookahead”体现在一阶动量上(把它看作一个更前瞻的一阶动量项):
最终参数更新:
实现上常见做法是对 的使用方式做 Nesterov 风格的修正(不同实现细节略有差异),但核心思想是:Adam 负责“自适应步长 + 动量”,Nadam 负责“在动量上再更前瞻一点”。
优点:
- 有时比 Adam 更快、更稳。
缺点:
- 并非总是优于 Adam;生态不如 AdamW 常用。
AdamW(Decoupled Weight Decay)
在很多代码里你会看到把 L2 正则写进 loss:
这会让梯度多出一项 。
但对 Adam 这类自适应方法来说,“把 L2 正则并入梯度”与“做权重衰减(weight decay)”并不完全等价。
AdamW 的核心就是把权重衰减从梯度里解耦出来,直接在参数更新时做衰减:
优点:
- 在大量任务里比 Adam + L2 更稳,泛化更好;现代训练中非常常用。
学习率调度
很多时候,“用什么优化器”不如“学习率怎么随时间变化”重要。一个常用经验是:
- 前期需要更大的学习率来探索与快速下降
- 后期需要更小的学习率来稳定收敛到更好点
下面列几类常见调度方式(它们可与上面任何优化器组合):
可以把学习率理解成优化器每一步的“步长”。步长太大时,参数可能在最优区域附近来回震荡甚至发散;步长太小时,训练会非常慢,并且容易停在不够好的平坦区域。调度器的作用就是让训练前期敢走大步、后期逐渐收小步,从而兼顾探索速度和收敛稳定性。
Step decay(阶梯衰减)
每隔若干 epoch 把学习率乘一个系数 :
优点是简单、超参数好解释;缺点是学习率跳变可能带来波动。
这种方法常和验证集曲线一起使用:如果 loss 或 accuracy 在一段时间内进入平台期,就把学习率降低一档。它的缺点是衰减时刻需要人为设定,如果降得太早会影响探索,降得太晚则会浪费训练时间。
Exponential decay(指数衰减)
更平滑,但需要合适的 。
指数衰减每一步都在连续变小,不会像 Step decay 那样突然改变训练动态。它适合希望学习率平滑下降的场景,但 过大时后期学习率会很快接近 0,模型可能过早停止有效更新。
decay
衰减更温和,常用但不一定总是最优。
与指数衰减相比, decay 后期下降更慢,因此还能保留一定的参数微调能力。它在理论分析中很常见,但现代深度学习实践里通常会结合具体任务选用阶梯、余弦或带 warmup 的策略。
Cosine decay(余弦退火)
在现代训练(尤其是视觉任务)中非常常见:
余弦退火的特点是前期下降较慢,中期下降加速,后期又逐渐变平滑。直觉上,它让模型在训练初期保持较强探索能力,最后以较小学习率进行细致收敛;如果配合周期性重启,还可以让训练多次跳出当前区域重新探索。
Warmup
无论用哪种 decay,大 batch 或大模型训练常常会在前几百/几千 step 用 warmup:
- 从很小的学习率线性/非线性升到目标学习率
- 减少初期不稳定与梯度爆炸风险
Warmup 解决的是训练刚开始时参数、梯度统计和归一化层状态都还不稳定的问题。此时如果直接使用较大学习率,优化器可能在还没形成可靠方向前就走得太猛;先从小学习率缓慢升高,可以让网络先进入一个更可控的训练状态。




