损失函数基不变但Adam对基敏感:优化器与参数化的隐秘关系
发布时间:2026/8/28 20:22:20 作者:尧图编辑部 阅读量:1,286

这次我们看一个偏优化理论、但对模型训练有直接影响的题目论文《The Loss Does Not See the Basis, but Adam Does》。标题本身已经把结论说完了——损失函数在基变换下是“看不到”坐标系的但 Adam 优化器“看得到”而且它的行为会被基的选择明显改变。首先要说明这不是一篇讲怎么调参的教程也不是给你一个开箱即用的推理工具。它讨论的是优化器与参数化之间的关系。你不需要 4090不需要 CUDA甚至不需要 GPU——用 CPU 在几分钟内就能验证核心现象。但你如果平时训练模型总是遇到 loss 下不去、换一个特征预处理结果就变、Adam 和 SGD 差距过大这类问题这篇文章能帮你定位一部分根因。本文会做四件事拆解损失的基不变性说清楚“损失为什么看不到基”。分析 Adam 的逐坐标自适应机制说明它为什么能看到基。给出一套基于 PyTorch 的可复现小实验用旋转特征验证现象。把结论映射到特征预处理、Adam/AdamW、perceptual loss、loss 曲线排查等实践问题。好直接开始。1. 核心信息速览项目说明研究对象损失函数在基变换下的不变性以及 Adam 优化器对这种不变性的破坏核心结论损失对可逆线性变换存在对称性SGD 等一阶方法在正交变换下保持等价性Adam 的逐坐标归一化依赖坐标系因此基选择会改变训练轨迹和最终解影响范围特征预处理、参数化方式、优化器选择、loss 曲线调试、Adam/AdamW 差异理解验证方式CPU PyTorch/NumPy合成数据旋转实验即可复现硬件门槛无 GPU 需求纯 CPU 可跑显存占用不是本实验的关注点数据类型小规模合成回归/分类数据足够不需要真实业务数据适合读者训练调参工程师、优化器研究者、对损失函数与梯度几何敏感的人这个表里没有写“模型大小”“显存占用”这些常规栏目因为本文讨论的不是一个生成模型或推理框架而是一个优化现象的机理分析。理解它之后你再去排查训练问题思路会更清晰。2. 问题背景损失函数为什么对“基”不敏感2.1 什么是“基”先说清楚这里的“基”指什么。机器学习里模型的输入、隐藏层特征、权重矩阵都活在某个向量空间里。基就是描述这个空间的坐标系。同一个向量在不同基下的坐标值不同但向量本身没变。举一个最简单的例子。假设输入是 x特征变换是 z Qx其中 Q 是一个正交矩阵满足 Q^TQ I。正交矩阵的作用是旋转或镜像不改变向量的长度和夹角。数据从 x 变成 z只是换了一套坐标系信息没有丢失。如果模型是线性映射 f(x) Wx那么在新基下可以定义 W WQ^T。此时f(z) Wz WQ^TQx Wx f(x)也就是说模型可以通过权重矩阵的相应变换在新基下表示同一个函数。输入基变了权重跟着变函数不变损失也不变。2.2 损失景观的对称性从这个例子可以推广对于很多常见的损失函数比如均方误差、交叉熵如果对输入空间做一个可逆线性变换同时把模型第一层权重“补偿”过去损失值是完全不变的。换句话说权重空间中存在一个等价类属于同一个等价类的点对应同一个函数也对应同一个损失值。loss 曲面在这个意义下具有对称性。论文标题里的“The Loss Does Not See the Basis”说的就是这个你只给损失函数一个函数值它无法告诉你这个函数是在哪套基下计算出来的。但这里有一个容易被忽略的点损失值不变不代表优化轨迹不变。轨迹是否等价取决于优化算法本身是否与这个变换“兼容”。2.3 SGD 为什么能保持等价考虑最朴素的梯度下降θ_{t1} θ_t - η∇L(θ_t)如果对参数空间做正交变换 θ Qθ那么梯度也随之前进。因为正交变换保持梯度方向与等高线的关系SGD 的迭代在新坐标系里恰好是对应点的保序映射。也就是说SGD 在“原基”和“旋转后的基”里走出的轨迹是同一个轨迹在不同坐标下的投影。SGD 也看不到基。这里需要注意SGD 的“看不到基”成立的前提是对所有参数做一致的变换并且初始化也要对应。实际训练中如果只旋转输入而不调整初始化分布统计上因为常见初始化是各向同性的旋转后的分布不变所以现象仍然近似成立。但 Adam 不一样下一节详细说。3. Adam 为什么能看到基3.1 Adam 的更新规则Adam 是自适应矩估计类优化器。它的核心是每个参数坐标独立维护一阶矩和二阶矩m_t β1 m_{t-1} (1-β1)g_t v_t β2 v_{t-1} (1-β2)g_t^2 θ_{t1} θ_t - η m̂_t / (√v̂_t ε)其中 m̂_t 和 v̂_t 是偏差校正后的矩估计g_t 是当前梯度。关键就在这个逐坐标除法梯度向量的每一个分量被自身的历史平方根归一化。这个归一化作用在每个坐标上而不是作用在整个向量上。当你把参数空间旋转一下梯度向量的分量会重新混合每个坐标上的历史平方根也会改变。于是归一化后的更新方向和步长都变了。即使损失函数值、损失景观在数学上是等价的Adam 实际走出的路径不一样最后停下的位置也不一样。3.2 问题出在“逐坐标”Adam 本质上是在用对角矩阵近似 Fisher 信息矩阵或 Hessian。对角近似的优点是计算便宜、显存占用小缺点就是它绑定在当前坐标系上。坐标系一换对角矩阵的结构就变了近似质量也变了。自然梯度法用完整的 Fisher 信息矩阵作为预条件θ_{t1} θ_t - η F_t^{-1}∇L(θ_t)F_t 在可逆变换下会按照张量规则变换因此自然梯度法对参数化具有近似不变性。这也是自然梯度在理论上优美的地方。Adam 出于工程考虑把 F 换成了坐标方向上的逐元素二阶矩估计相当于只保留了 Fisher 矩阵的对角线而且是在当前坐标系里取的对角线。这一步节省了大量计算但也放弃了变换不变性。这才是论文标题的完整含义损失函数本身对基是盲的SGD 的轨迹也对基是盲的但 Adam 的预条件矩阵依赖基所以 Adam 能“看到”基而且会受基的影响。3.3 一个直观类比可以把 Adam 理解成给每个参数分配了一个独立的“学习率调节旋钮”。旋钮的刻度是依据这个参数方向上的梯度历史算出来的。当你把坐标系旋转相当于把所有旋钮重新喷漆、打乱重排。旋钮还是那些旋钮但哪个旋钮控制哪个方向已经变了。SGD 没有旋钮每个方向步长一致旋转对它只是换了件衣服。4. 从理论到实践这会带来哪些实际问题到这里理论已经清楚了。接下来把结论落到训练里。4.1 特征预处理不是“无差别”的很多人处理特征时习惯先标准化再按需 PCA 白化。这些操作本质上都是对输入空间做线性变换。换成新的基之后SGD 的训练结果在理想情况下几乎不受影响但 Adam 会受影响最终模型可能收敛到不同的局部解泛化性能也可能不同。这可能正是同一个任务、同一套超参别人白化后效果好、你白化后效果差的原因之一。问题不一定是白化本身而是“白化 Adam”这个组合对基敏感。4.2 模型参数化方式影响 Adam 行为改变参数化方式比如给权重加 weight normalization、weight standardization或者把网络输出改成残差结构都会改变坐标系的度量结构。这些改变对 SGD 来说可能只是路径相同换了个写法对 Adam 来说却是实打实的轨迹改变。所以在做这些改动时不能只比较“换了参数化方式后效果变好/变差”还要意识到一部分效果来自 Adam 的基敏感性。反过来说如果哪天你尝试一个理论上“应该等价”的改进实际效果却掉了点可以先想想是不是 Adam 的坐标系变了。4.3 Adam 和 AdamW 的区别不只是权重衰减位置AdamW 把权重衰减从梯度里解耦出来改成直接在参数更新后乘以衰减系数。这个改动本身是为了解决 L2 正则与自适应学习率的耦合问题。但注意权重衰减是在当前坐标系下对每个坐标独立缩放的。如果参数空间发生旋转解耦的权重衰减同样会被“旋转”作用方式会变化。所以 AdamW 和 Adam 的差异不只是“decay 放在哪里”还包括它们对基选择的不同敏感程度。迁移学习、Fine-tune 场景里预训练权重所在的坐标系是固定的直接用 AdamW 微调每一步的权重衰减都和坐标相关这点在做模型复现和调参时要留意。4.4 与 focal loss、perceptual loss 等损失设计的关系focal loss、perceptual loss、VGG loss 这些损失设计怎么和基扯上关系先说 focal loss。它解决的问题是类别不平衡核心是给困难样本更大的梯度权重。它改变的是损失函数本身的梯度分布和优化器的基敏感性是两个维度。但两者会叠加focal loss 改变了梯度向量在各坐标上的分量Adam 的逐坐标归一化又会对这些分量重新分配步长。也就是说即使 focal loss 的理论设计合理Adam 也可能在不知不觉中改变了它的实际效果。再说 perceptual loss / VGG loss。这类损失把模型输出映射到预训练 VGG 的特征空间再计算特征图上的距离。这里的“基”就是预训练网络的特征空间。同一个视觉差异在 VGG 不同层、不同归一化条件下损失值差异很大。VGG 特征空间本身就是一个手工选择的基它好用的前提是这个基和人眼感知大致对齐。如果换一个特征提取器等于换基perceptual loss 的性质也随之改变。所以在使用 perceptual loss 时除了关注它在验证集上的效果也要意识到它本质上是在“选定基”上定义距离而不是在所有基上都成立的距离。4.5 loss 曲线下不去的另一种归因平时排查“loss 函数下不去”时大家习惯先看学习率、batch size、模型容量。看完这些还找不到原因可能会怀疑数据、标签、网络结构。这篇文章提供了另一个排查分支是不是基选择导致的 Adam 优化路径卡住了具体表现是训练集上 loss 在某个平台期停滞但同数据换一组正交化预处理、或换用 SGDloss 又能继续下降。如果遇到这种情况可以去检查特征的尺度分布是否差异很大、数据是否经过白化、模型参数化是否合理然后对比 Adam 和 SGD 的行为差异。这不是说 Adam 一定差而是说明当前这套“特征基 Adam”的组合可能选得不合适。5. 复现实验让 Adam 的基敏感性可见这里给出一套可在 CPU 上几分钟跑完的 PyTorch 实验用来观察现象。实验设计如下生成一份线性回归合成数据特征维度 d16样本量 n4096。构造一个随机正交矩阵 Q把输入旋转成新基X_rot X Q^T。分别在原基和旋转基上用相同结构模型训练比较 SGD 与 Adam 的 loss 曲线和最终误差。为了让对照公平每个 (数据, 优化器) 组合都从相同随机种子初始化模型。先准备数据和旋转矩阵。import torch import torch.nn as nn def make_data(n4096, d16, seed0): g torch.Generator().manual_seed(seed) X torch.randn(n, d, generatorg) W_true torch.randn(d, 1, generatorg) y X W_true 0.05 * torch.randn(n, 1, generatorg) return X, y def random_orthogonal(d16, seed1): g torch.Generator().manual_seed(seed) A torch.randn(d, d, generatorg) Q, _ torch.linalg.qr(A) return Q X, y make_data() Q random_orthogonal() X_rot X Q.t() print(X shape:, X.shape, rotation shape:, Q.shape)再定义一个训练函数接收模型、数据、优化器返回 loss 序列。def train(model, X, y, opt, steps300): loss_fn nn.MSELoss() losses [] for _ in range(steps): opt.zero_grad() loss loss_fn(model(X), y) loss.backward() opt.step() losses.append(loss.item()) return losses最后跑四个组合SGD/原基、SGD/旋转基、Adam/原基、Adam/旋转基。模型统一用单隐层 MLP。def build_model(d16): return nn.Sequential( nn.Linear(d, 32), nn.ReLU(), nn.Linear(32, 1), ) results {} for name, xdata, opt_name in [ (SGD-orig, X, sgd), (SGD-rot, X_rot, sgd), (Adam-orig, X, adam), (Adam-rot, X_rot, adam), ]: torch.manual_seed(42) model build_model() if opt_name sgd: opt torch.optim.SGD(model.parameters(), lr0.05) else: opt torch.optim.Adam(model.parameters(), lr0.01) losses train(model, xdata, y, opt) results[name] losses[-1] print(f{name}: final loss {losses[-1]:.6f})从经验上看SGD 两个组合的最终 loss 会非常接近而 Adam 两个组合的最终 loss 可能有明显差异loss 曲线的形态也会不同。这个实验只用了 4096 条数据和 300 步训练CPU 几秒钟就能跑完。更换随机种子、正交矩阵、网络宽度现象都存在只是幅度不同。需要说明上面是验证现象的最小脚本不是论文作者的官方复现。论文里会有更严格的实验设置和更多维度的分析。如果要在自己的任务上看这个效应应该把旋转换成实际业务里的预处理变换比如标准化、白化、随机旋转增强然后对比 SGD 与 Adam 的轨迹差异。6. 实验观察什么、怎么判断是否复现跑完脚本只是第一步重点是要知道看什么。6.1 看最终 loss 的配对差异把四个组合的结果列成表数据/优化器SGDAdam原基记录最终 loss记录最终 loss旋转基记录最终 loss记录最终 loss如果 SGD 两行的数值接近Adam 两行的数值差得比较明显就说明在当前任务上复现了基敏感性。数值差异越大说明 Adam 对基的选择越敏感。6.2 看训练曲线的形态除了最终 loss还要画出 loss 曲线。SGD 在两种基下的曲线通常几乎重合Adam 的曲线可能在早期步长上就有分叉一个下降快一个下降慢甚至一个稳定收敛、一个明显震荡。6.3 看梯度统计可以打印每个参数方向上的梯度二阶矩 v 的分布。旋转前后SGD 的梯度方向整体跟着坐标转而 v 的逐坐标分布会完全不同。这是 Adam 能看到基的直接证据。下面这段代码可以观察第一层权重的梯度二阶矩分布for name, p in model.named_parameters(): if p.grad is not None: v p.grad.detach() ** 2 print(name, grad mean:, v.mean().item(), max:, v.max().item())把这个统计放到每个训练组合的最后一步对比两个基下的数值直观就能看出来。6.4 资源占用这类小实验不需要 GPUCPU 单核也能跑完内存占用在几百 MB 以内显存占用为 0。这是它的优势任何一台装了 Python 环境的电脑都能复现不需要考虑 CUDA、驱动、显存容量。如果要在真实模型上观察基敏感性那才需要按模型的规模评估显存和时间建议先在最小配置上跑通再逐步放大。7. 常见问题与排查方法这里把文章里的结论整理成一份排查表供训练时对照。问题现象可能原因排查方式解决方案loss 函数下不去停留在平台期学习率或 batch size 不合理也可能是基选择导致 Adam 路径被卡住对比 SGD 和 Adam 的 loss 曲线检查特征尺度分布尝试白化/标准化换 SGD 或降低 Adam 学习率检查参数化方式同一数据不同预处理后结果差异大特征变换改变了 Adam 的逐坐标归一化用正交旋转做对照组实验固定一套预处理用 SGD 交叉验证是否稳定Adam 和 SGD 在验证集上差距过大两者对基的敏感度不同优化终点不同观察训练轨迹和最终权重的范数根据任务选择优化器对 Adam 调 lr、eps、beta2AdamW 微调效果不稳定解耦权重衰减在当前坐标系下逐坐标缩放基改变时衰减含义变化检查权重衰减量级和参数范数保持一致的输入预处理和参数化必要时改用 SGD 对照loss 曲线震荡不收敛自适应学习率在部分坐标上过大查看 v 的最大值与均值比调小 lr增大 eps增大 batch size换了模型结构后效果反而下降参数化改变影响 Adam 轨迹并不代表结构本身更差固定优化器与数据单独比较结构先用 SGD 或较小的 lr 做结构消融相同代码不同随机种子结果差异大Adam 对坐标敏感加上初始化随机性会被放大多次重复实验取均值方差固定种子必要时退化为 SGD 检查稳定性排查时记住一个原则换数据预处理、换模型结构、换优化器这三个变量不要同时动。一次只改一个控制变量后才能判断差异来自哪个环节。如果改了预处理后 SGD 结果稳定而 Adam 结果变差那么问题很可能出在基的敏感度上。8. 最佳实践与工程建议基于这篇论文的机理分析下面几条建议可以直接用到日常训练流程里。8.1 把特征预处理当成超参来对待预处理会影响 Adam 的行为所以白化、标准化、归一化、旋转增强都不是纯数据的“无差别操作”。建议在每次实验记录里明确写入预处理方式和优化器、学习率一样对待。跨实验对比时如果预处理不一致结果差异不能简单归因于模型改动。8.2 用 SGD 做参数化消融的对照组当你想验证一个结构改进是否真的有效时只跑 Adam 是不够的因为 Adam 的基敏感性会把参数化的改变和优化轨迹的改变混在一起。更好的做法是同一个结构改进分别用 SGD 和 Adam 各跑一组。如果 SGD 下改进成立、Adam 下不成立说明改进本身可能是对的只是与 Adam 的坐标系不兼容。8.3 优先用 AdamW 而不是 AdamAdamW 的权重衰减解耦方式在工程上更容易控制。虽然它同样存在基敏感性但至少不会把 L2 正则和自适应学习率绑在一起出问题时更容易隔离原因。在设置 AdamW 时把 lr 调低一点权重衰减从 0.01 这一类常用值开始试曲线不稳就优先调 lr 而不是调网络。8.4 对 loss 曲线要有“归因”意识当 loss 曲线迟迟不下降时按顺序排查数据问题 → 标签问题 → 学习率 → 优化器 → 特征预处理 → 模型结构 → 参数化方式。“特征预处理”这一项排在模型结构前面是有原因的它成本最低且经常被忽略。跑一次 SGD 对照只需要几分钟能过滤掉一大类原因。8.5 涉及感知损失时明确“基”的选择使用 perceptual loss / VGG loss 时要意识到你是在一个特定的预训练特征空间里度量差异。换 VGG 变体、换提取层级、改变输入归一化都会改变“基”。对比不同感知损失时固定特征提取器的版本和层是基本要求。实际项目中先在少量样本上对比特征图差异再投入全量训练更稳妥。8.6 合规与复现边界本文讨论的是数学和训练优化机制不涉及图像、音频、视频等生成内容因此不存在肖像授权、版权素材、声音克隆等合规风险。但如果你把上述实验方法迁移到真实业务数据仍然要遵守数据使用授权和隐私保护要求。用于论文复现和开源实验时尽量使用公开合成数据用真实数据前确认授权范围。9. 总结与下一步这篇论文最值得关注的点不是“Adam 有缺陷”这种简单结论而是它揭示了一个容易被忽略的机制损失函数的对称性并不自动传导给优化算法。SGD 在正交变换下保持等价Adam 因为逐坐标预条件而破坏等价。这是“优化”和“参数化”相互耦合的一个具体例子也是实践中很多诡异训练现象的深层原因。如果你只想做一件事建议跑一遍上面第 5 节的小实验。数据集 4096 条、模型单隐层、CPU 十几秒出结果亲眼看一下四个组合的 loss 曲线差异比读十篇文章都直观。最容易踩的坑是“把所有训练问题都归因于基”。基敏感性只是众多因素之一数据质量、标签噪声、学习率选择、模型容量仍然是最常见的问题来源。正确用法是把它作为排查工具当损失曲线异常、预处理改动