avatar

Xiaojun Wu

Ph.D. Candidate, HKUST(GZ)
Affiliate LLM Researcher, IDEA Research
wuxiaojun@idea.edu.cn & wuxiaojun@pku.edu.cn & xwu647@connect.hkust-gz.edu.cn


← Blog

最优化

最优化(一):从梯度下降到 Adam、AdamW、Muon,优化器到底在优化什么?

在知乎查看原文

阅读 知乎未公开 收藏 57 点赞 26

互动数据为 2026-09-14 的知乎数据快照;阅读量未在当前可用的知乎公开接口中提供。

训练神经网络的时候,我们常说“换个优化器试试”。SGD 不行换 AdamW,AdamW 不稳调学习率,最近又有人把 MLP 和 Attention 的矩阵权重交给 Muon。

但优化器到底在做什么?

最直观的答案是:每一步都要回答一个问题。

现在参数在这里,loss 在这里,我应该往哪个方向走、走多远,才更可能让 loss 下降?

这篇先不急着提出新优化器。我们先把传统数值优化和深度学习优化器放到同一张地图上:梯度、曲率、Hessian、牛顿法、动量、Adam、AdamW、Muon,各自到底在利用什么信息。

如果你想找一个工程上的入口,scipy.optimize 是很好的目录。它把无约束最小化、有约束最小化、全局优化、最小二乘、求根、线性规划、分配问题、混合整数线性规划等常见工具放在一起。

但要注意,它是一个非常实用的工具箱目录,不是“最优化学科的全部”。最优化还包括凸优化、组合优化、随机优化、鲁棒优化、最优控制、动态规划、变分法、大规模混合整数优化、PDE 约束优化、分布式训练优化等很多方向。SciPy 适合帮你建立第一张地图,但真实问题会继续往外长。

01-gradient-curvature


1. 最优化的基本问题:选择一次更新

最优化问题最常见的写法是:

 \min_{\theta} L(\theta)

\theta 是决策变量。在神经网络里,它就是模型参数;在运筹优化里,它可能是产量、路径、排班、库存;在控制论里,它可能是控制输入或轨迹。

L(\theta) 是目标函数。深度学习里常叫 loss,运筹优化里常叫成本、收益的负数、总时间、总能耗。

很多最优化问题还有约束:

 c(\theta)\le 0,\quad h(\theta)=0

所以一个优化模型通常有三要素:决策变量、目标函数、约束条件。深度学习训练常被写成无约束问题,但正则化、梯度裁剪、投影、参数化约束,本质上也在控制可行更新的范围。运筹优化更常显式写约束,比如容量、预算、路径、排班规则。控制论则会把“时间演化”也写进约束里,比如:

 x_{t+1}=f(x_t,u_t)

这里 x_t 是系统状态,u_t 是控制输入。机器人路径规划、轨迹优化、模型预测控制,经常就是“最优化 + 动力学约束 + 反馈”的组合。

优化器真正决定的是这一步的更新:

 \Delta \theta_t

然后把参数改成:

 \theta_{t+1}=\theta_t+\Delta\theta_t

所以所有优化器都可以粗暴地问成一句话:你准备用什么信息来决定 \Delta\theta_t?

这也是为什么运筹学、控制论、深度学习优化器会经常互相碰到。它们不一定研究同一种问题,但都在处理“怎么选择变量,让目标变好,同时别违反约束”。差别主要在问题结构:运筹优化常面对显式约束和离散决策;控制论常面对时间、动力学和反馈;深度学习训练常面对高维、随机、非凸和分布式计算。

2. 一阶方法:只看“坡往哪边下”

梯度下降是最容易理解的一阶方法。

 \theta_{t+1}=\theta_t-\eta \nabla L(\theta_t)

这里的 \nabla L(\theta_t) 就是当前位置的梯度。它告诉你:在当前位置,哪个方向上升最快。既然我们要最小化 loss,就反着走。

学习率 \eta 控制步子大小。

如果每一步都用全量数据算梯度,就是 batch gradient descent;如果每次只用一个 mini-batch 的数据估计梯度,就是 stochastic gradient descent,简称 SGD。

SGD 的优点是便宜、直接、泛化常常不错。缺点也明显:mini-batch 梯度有噪声,如果每一步都完全相信当前梯度,路线会抖。

于是出现了 Momentum。

 m_t=\beta m_{t-1}+(1-\beta)g_t

动量不是在问“这一秒风往哪吹”,而是在问“最近一段时间,风大体往哪吹”。它把历史梯度做指数平均,让更新方向更稳。

所以 SGD 和 Momentum 都是一阶方法:它们主要使用梯度,不显式使用 Hessian。

这里顺便澄清一个常见误解:不能简单说“SGD 是无约束优化,运筹规划是有约束优化”。SGD/Adam 当然常用于无约束随机非凸优化,但它们也可以和投影、惩罚项、拉格朗日方法结合,用在有约束问题里。运筹优化也不只研究有约束问题,它也有无约束非线性优化、最小二乘、动态规划、随机近似。

更准确的区别是:SGD/Adam 是一类求解方法,运筹优化是一大片问题与建模传统。一个是“怎么走”,一个更偏“问题长什么样”。

3. 曲率:梯度已经告诉我陡不陡,为什么还要曲率?

很多人第一次听 Hessian 会有同一个疑问:梯度不就已经告诉我们山坡陡不陡了吗?为什么还要曲率?

关键区别是:

梯度告诉你“当前位置有多陡”;曲率告诉你“你往前走一点,坡度会怎么变”。

两个地方的当前坡度可能一样,但后面的地形完全不同。

一个地方像长斜坡,坡度稳定;另一个地方像窄山谷,刚走一点坡度就剧烈变化。只看当前梯度,你会以为它们一样;看曲率,你才知道第二个地方更危险,步子应该小一点或换个方向。

对多参数函数来说,曲率由 Hessian 矩阵描述:

 H_{ij}=\frac{\partial^2 L}{\partial \theta_i \partial \theta_j}

它是一个 N \times N 矩阵。对角线元素表示某个参数方向自己的弯曲程度;非对角线元素表示两个参数方向之间的耦合:你改 \theta_i,\theta_j 方向的梯度会不会也跟着变。

Hessian 出现在二阶泰勒展开里:

 L(\theta+\Delta\theta)\approx L(\theta)+g^\top\Delta\theta+\frac{1}{2}\Delta\theta^\top H\Delta\theta

第一项 g^\top\Delta\theta 是“沿当前坡度走会怎样”。第二项 \frac{1}{2}\Delta\theta^\top H\Delta\theta 是“地形弯曲会怎样改变这一步的结果”。

这就是 Hessian 为什么能体现曲率。

4. 牛顿法:不只看坡,还看碗的形状

如果梯度下降像是“看到坡就往下冲”,牛顿法更像是“先估计这个山谷像什么碗,再一步走向碗底”。

牛顿方向是:

 \Delta\theta_{\text{Newton}}=-H^{-1}g

这一步非常漂亮:梯度 g 告诉你哪里下降,Hessian H 告诉你每个方向的曲率和耦合,H^{-1}g 相当于根据地形重新缩放和旋转梯度。

如果某个方向曲率很大,说明那里很窄,牛顿法会少走一点;如果某个方向曲率很小,说明那里很平,牛顿法会允许走大一点。

这就是“二阶方法”的核心气质:不仅看一阶坡度,还看二阶弯曲。

但神经网络里直接用牛顿法很难。

假设一个模型有 N 个参数,Hessian 是 N \times N。大模型的 N 可以是十亿、百亿、千亿。别说求逆,连把 Hessian 存下来都不现实。

所以深度学习里的多数优化器不会真的构造完整 Hessian。

5. 拟牛顿法:不存 Hessian,也想学一点曲率

传统数值优化里有一类方法叫拟牛顿法,比如 BFGS、L-BFGS。

它们的思路是:我不直接算 Hessian,但我观察几步之间梯度怎么变化,从这些变化里估计一个“像 Hessian 逆矩阵”的东西。

如果你从 \theta_t 走到 \theta_{t+1},梯度从 g_t 变成 g_{t+1},那么:

 s_t=\theta_{t+1}-\theta_t,\quad y_t=g_{t+1}-g_t

s_t 是参数变化,y_t 是梯度变化。梯度变化里藏着曲率信息。

BFGS 会维护一个近似的二阶矩阵;L-BFGS 则只保留最近几步的 s_t,y_t,省内存。

为什么它们在深度学习里没有 AdamW 这么流行?主要不是因为它们“不高级”,而是因为大模型训练有三个现实问题:参数太多、梯度噪声太大、分布式训练通信成本太高。拟牛顿法要维护和使用额外的历史曲率结构,在超大规模随机训练里很难像 AdamW 那样简单、稳定、便宜。

如果对应到 scipy.optimize,你会看到很多传统数值优化器都在这里出现:Nelder-Mead 不需要梯度,BFGS 和 L-BFGS-B 使用梯度和近似曲率,Newton-CG、trust-ncg、trust-krylov、trust-exact 更靠近二阶方法,SLSQP 和 trust-constr 处理有约束最小化。

这份目录很适合建立直觉:传统优化器经常在“是否需要梯度、是否使用曲率、是否处理约束、局部还是全局”这些维度上分类。深度学习优化器则是在另一个极端场景里演化出来的:超高维、mini-batch 噪声、GPU/TPU 并行、参数量巨大。所以它们更在意吞吐、内存、通信、稳定性。

02-optimizer-family-map


6. Adam:不是牛顿法,但确实在“重新缩放梯度”

Adam 的核心更新是两条历史统计:

 m_t=\beta_1m_{t-1}+(1-\beta_1)g_t

 v_t=\beta_2v_{t-1}+(1-\beta_2)g_t^2

m_t 是梯度的一阶矩估计,可以粗略理解成“最近梯度的平均方向”。

v_t 是梯度平方的二阶矩估计,可以粗略理解成“这个方向历史上抖得有多大、尺度有多大”。

这时很容易联想到金融里的 Sharpe ratio。不是因为 Adam 真的在做资产定价,而是因为它也在做一个“信号除以波动”的缩放:如果一个方向平均梯度很稳定,它更值得走;如果一个方向历史梯度很大但也很抖,直接按梯度猛走就容易过冲。

Adam 的方向大致是:

 \Delta\theta_t\propto-\frac{\hat m_t}{\sqrt{\hat v_t}+\epsilon}

这就产生了一个很重要的效果:某个参数方向历史梯度尺度很大,就给它小一点步子;历史梯度尺度小,就相对给大一点步子。

03-adam-risk-adjusted-gradient



这和牛顿法有没有关系?

有关系,但不能说 Adam 就是牛顿法。

共同点是:它们都不是裸梯度下降。它们都会对梯度做某种“预条件化”,也就是先改变不同方向的尺度,再决定更新。

区别是:牛顿法的尺度来自目标函数的曲率,也就是 Hessian;Adam 的尺度来自历史梯度的平方均值,是一种逐坐标的梯度尺度/噪声统计。它通常不理解参数之间的耦合,也不显式估计完整曲率。

一个讨论:Adam 是不是在近似二阶导?

这个问题不能只回答“是”或者“不是”。

如果从严格数学定义看,Adam 没有计算 Hessian:

 H_{ij}=\frac{\partial^2 L}{\partial \theta_i\partial \theta_j}

它没有问“梯度对参数再求一次导是多少”,也没有保存参数之间的交叉项 H_{ij}。所以它不是牛顿法,也不是标准二阶优化器。

但如果从训练直觉看,说 Adam 完全和曲率无关,也太粗暴了。

深度学习的 loss landscape 非常不规则:mini-batch 在变,样本分布在变,激活状态在变,梯度噪声也很大。很多时候,直接估计 Hessian 既贵又脏,得到的局部曲率也未必稳定。于是 Adam 退了一步:我不估计完整曲率,只估计每个坐标方向上“历史梯度到底有多大、多抖”。

这个量不等于 Hessian,但在某些条件下会和二阶信息产生联系。比如在最大似然训练里,梯度平方的期望和 Fisher 信息矩阵的对角线有关;而 Fisher 又常被看作 Hessian 或 Gauss-Newton 矩阵的一种替代曲率。换句话说,Adam 的 v_t 可以被理解成一种非常粗糙、逐坐标、随机采样出来的“曲率/噪声尺度”。

更准确地说:

Adam 不是在近似 Hessian 本身,而是在用历史梯度平方近似一个逐坐标的局部尺度。这个尺度有时表现得像曲率预条件器,有时更像噪声归一化器。

这也是为什么 Adam 的直觉和牛顿法有亲戚关系:它们都在避免所有方向使用同一个步长。但它们的“风险账本”来源不同。牛顿法用 Hessian 账本,Adam 用历史梯度平方账本。

所以更准确的说法是:

Adam 是带动量和逐参数自适应缩放的一阶优化器。它有“像牛顿法一样给不同方向不同步长”的味道,但它不是二阶曲率方法。

7. AdamW:把 weight decay 从梯度里拆出来

AdamW 可以看成 Adam 在大模型训练里的更常用版本。

Adam 原始写法里,L2 正则经常会混进梯度估计里。问题是 Adam 会对梯度做自适应缩放,于是正则项也被缩放了,weight decay 的含义变得不够干净。

AdamW 的做法是把 weight decay 解耦:

 \theta \leftarrow \theta-\eta \cdot \text{AdamStep}(\theta)

 \theta \leftarrow \theta-\eta\lambda\theta

也就是说,优化方向和参数衰减分开处理。这样 weight decay 更像一个稳定的“参数收缩规则”,不会被 Adam 的逐坐标缩放扭曲。

这也是为什么大模型训练里 AdamW 比 Adam 更常作为默认选择。

8. Muon:矩阵权重不是一堆独立坐标

Muon 的核心直觉和 Adam 不一样。

Adam 把每个参数坐标看得很重要:每个坐标都有自己的 m_t、v_t、步长缩放。

但 MLP 和 Attention 里的很多权重是二维矩阵。一个矩阵不是一把散沙。它作为线性变换,真正改变的是表示空间:某些方向被放大,某些方向被压缩,某些子空间被旋转。

Muon 大致做的是:

  1. 先对矩阵梯度做 momentum。
  2. 再对这个 momentum 矩阵做近似正交化。
  3. 用更均衡的矩阵方向更新权重。

可以粗略写成:

 M_t=\beta M_{t-1}+G_t

 \Delta W_t\propto-\text{Ortho}(M_t)

这里的 \text{Ortho} 不是求 Hessian,也不是 Adam 的逐坐标除法。它更像是把一个矩阵更新方向的少数巨大奇异方向压住,让更新不要被少数大方向支配。

04-muon-matrix-orthogonalization


这也是为什么 Muon 通常更适合 MLP、Attention 这类二维 dense weight,而不是 norm、bias、embedding 这些结构。

它不是“Adam 的替代品”这么简单。更准确地说,它换了一种看待更新风险的单位:Adam 看坐标,Muon 看矩阵。

这也对应我们前面聊过的机器人例子:路径规划有时像运筹优化,在图上找最短路、最低成本轨迹;有时又像控制论,要在动力学约束下实时修正轨迹。分类不是靠名字,而是靠问题结构。优化器也一样,Adam 和 Muon 的差别不是“谁更高级”,而是它们假设参数块的结构不同。

这句话会成为第二篇的入口。

9. 一张表记住它们

优化器 主要信息 看待参数的方式 优点 局限
SGD 当前梯度 全局同一步长 简单、便宜、泛化好 噪声大,调参敏感
Momentum 历史梯度均值 方向有惯性 路线更稳 没有逐坐标尺度
Newton 梯度 + Hessian 曲率耦合结构 局部收敛快 大模型不可承受
BFGS/L-BFGS 梯度变化 近似曲率 不显式算完整 Hessian 随机大规模训练不方便
Adam 动量 + 梯度平方均值 逐参数自适应 稳、好用、默认强 不显式理解矩阵结构
AdamW Adam + 解耦 weight decay 逐参数自适应 大模型默认常用 仍是坐标视角
Muon 矩阵动量 + 近似正交化 矩阵几何 适合 dense matrix weight 不适合所有层

10. 小结:优化器不是一个公式,而是一种“风险观”

到这里,我们可以把优化器重新理解一遍。

SGD 说:我相信当前梯度。

Momentum 说:我相信历史平均方向。

Newton 说:我还要知道地形弯曲。

拟牛顿说:我不直接算 Hessian,但我要从梯度变化里学曲率。

Adam 说:每个参数方向都有自己的历史波动,步子要按坐标缩放。

AdamW 说:别把正则化和自适应缩放搅在一起。

Muon 说:矩阵权重不是一堆独立参数,更新应该尊重矩阵几何。

如果只从“谁更快、谁更强”理解优化器,很容易陷入经验主义。但如果从“每个优化器到底在用什么信息、控制什么风险”理解,Adam 和 Muon 就不再是两个互相打架的技巧,而是两个风险度量不同的更新策略。

第二篇我们就从这个角度继续:能不能把 Adam 和 Muon 放进一个金融式的“收益-风险-预算”框架里?

参考资料


© 2025 Xiaojun Wu. All rights reserved. Powered by Jekyll and Minimal Light theme.