Nesterov先到哪里看梯度:前瞻点用旧速度,不能多走一次
“Nesterov会提前看一眼”是一种方便的记忆法,却很容易让实现多加一次动量,或者在错误的位置求梯度。它没有预知下一步的真实结果,而是在一个由旧速度确定的前瞻点上重新评估当前损失。把参数、速度和求梯度的位置逐项记录,比只看下降曲线更能说明算法是否实现正确。
AI生成的概念示意图,以前方的透明小车和探针表达前瞻点;不是实际产品、训练轨迹或准确的损失曲线。
先约定速度的符号与单位
采用位移形式的速度v:普通动量更新为v新=μv旧−η∇f(x旧),再令x新=x旧+v新。Nesterov在本文使用的等价写法是,先取前瞻点y=x旧+μv旧,然后v新=μv旧−η∇f(y),最后仍从x旧加上v新。
这里v已经包含过往学习率带来的位移,梯度下降符号体现在减号里。某些实现把缓冲区定义成梯度累计量,参数更新时再乘学习率,变量名字虽然也叫momentum,却不能直接与本文的v逐数比较。
取损失f(x)=x²/2,梯度就是x。当前x=1、旧速度v=−0.5,动量μ=0.9,学习率η=0.1。我们从一个已有速度的状态开始,而不是声称这是所有优化器默认初始化。
同一步,两种方法看见了不同斜率
普通动量在x=1求梯度1,得到v新=0.9×(−0.5)−0.1×1=−0.55,因此x新=0.45。
Nesterov先到y=1+0.9×(−0.5)=0.55,那里梯度为0.55。新速度为−0.45−0.055=−0.505,最终参数是1−0.505=0.495。前瞻点已经更靠近最低点0,因此它施加的向左梯度修正较小。
注意最后应从原参数1出发加新速度。若错误地从前瞻点0.55再加−0.505,会落到0.045,相当于把旧动量位移额外加了一次。这种错误可能让某个小例下降得更快,恰好说明“损失更低”不能替代逐项公式验证。
第一步更低,不代表两步以后仍更好
第一步普通动量的损失为0.45²/2=0.10125,Nesterov为0.495²/2=0.1225125,前者反而更低。Nesterov的名字与理论性质,不保证它在任意起点、任意单步都得到更低损失。
继续第二步。普通动量用x=0.45、v=−0.55,得v新=−0.495−0.045=−0.54,参数变为−0.09,越过最低点,损失0.00405。
Nesterov用自己的状态x=0.495、v=−0.505。前瞻点为0.495−0.4545=0.0405,新速度−0.4545−0.00405=−0.45855,参数变为0.03645,损失约0.000664301。此时它比普通动量更接近零。两步对照展示了机制差别,没有证明某种优化器对所有损失都更优。
前瞻不提供任意步长的安全保证
保持同一二次损失,改从x=1、v=0开始,取μ=0.9、η=2。第一步前瞻点仍为1,新速度−2,参数到−1。第二步前瞻点为−1−1.8=−2.8,梯度也是−2.8;新速度为−1.8+5.6=3.8,参数跳到2.8。
损失从初始0.5,经第一步0.5,增加到第二步3.92。前瞻点能够改变修正方向,但不能替代与曲率匹配的学习率。凸、光滑问题中的加速收敛结论还附带参数安排和梯度条件,不能直接移植成非凸随机训练中的逐步保证。
若μ=0,两种方法都退化为普通梯度下降,是一个简单边界测试。若v旧=0,则当前一步在本文状态约定下也相同,但之后速度累积起来才出现区别。第一步相等并不说明代码没有开启Nesterov。
框架比较先核对状态定义
有些框架将参数重参数化,直接在保存在内存中的前瞻位置计算梯度;还有的把学习率放在速度累计外面。这样的实现可能与论文形式等价,但“同一时刻的参数变量”未必代表同一个数学量。迁移优化器状态或比较手写代码时,需要把变量之间的映射写出来。
尤其在学习率随时间变化时,先乘学习率再累计,与先累计原始梯度再乘当前学习率,不一定继续完全相同。阻尼、权重衰减、最大化选项也会改变更新。不要只把两个接口的momentum与nesterov参数设置相同,就宣布轨迹应该逐点重合。
让AI写最小测试时,要求每一步输出旧x、旧v、前瞻点、实际求得梯度、新v和新x。再用一份不依赖优化器库的标量算术作为参考。将更新顺序写成先算所有临时量、最后统一覆盖状态,可以避免原地修改让第二行误读“新旧混合”的速度。
这个检查适合验证优化器实现、讲解动量机制和排查状态恢复差异。它没有涉及批次噪声、混合精度或真实网络性能;这些因素进入之后,应各自增加测试,而不能让一个二次函数上的漂亮数字替整套训练作担保。
资料核对日期:2026年10月3日。数值均为原创教学设定,使用本地独立程序复算;未进行真实模型训练或生产性能测试。
参考资料
Sutskever等:On the Importance of Initialization and Momentum in Deep Learning,第2节


