随机梯度下降
真实的代价函数常常是几百万条数据误差的平均。每走一步都把所有数据看一遍,太贵了。随机梯度下降 (SGD) 的想法很朴素:只抽一小撮样本(一个小批量)估计梯度,宁可走得歪一点,也要走得快。这个"歪",也就是噪声,既带来代价(走到最后停不稳),也带来意外的好处(能逃出鞍点)。
1为什么机器人需要它
机器人学习的数据又多又杂:一次遥操作采集就是几十万帧图像加动作,训练一个模仿学习策略的代价函数就是"每一帧上动作预测误差的平均"。如果每次更新参数都要遍历整个数据集,一轮训练可能要几个小时,而参数只更新了一次。
所以训练几乎都用小批量:每次随机抽几十到几千帧,算这些帧上的平均梯度,更新一次,再抽下一批。同样的思路也出现在机器人在线运行时:标定参数一边采数据一边更新,不必等数据采完;每来一个新测量,就沿着它的梯度挪一小步。
这一节回答三个问题:为什么抽一小撮样本算出来的梯度仍然"可用"?噪声对收敛有什么影响,学习率该怎么随时间变化?噪声什么时候反而是朋友?
2直觉:民意调查
想象要估计全国人口的平均身高。把所有人都量一遍最准,但太贵;随机抽 100 个人,算出来的平均值每次都不同,却围绕真值上下波动,抽得越多,波动越小。梯度也是平均值:\(\nabla f=\frac1N\sum_i\nabla f_i\),是所有样本梯度的平均。随机抽 \(B\) 个样本再平均,就是一次"民意调查",得到一个有噪声但没有偏向的估计。
"没有偏向"是整件事的支点:噪声会让每一步走歪,但平均而言走的方向是对的。用 SGD 下山,就像一个带着不太准的指南针的徒步者:每一步都偏一点,走一百步,大方向没错。
3动手玩:SGD 对 GD
任务是用一条直线 \(y=wu+b\) 拟合 200 个带噪声的点,参数 \(\x=(w,b)\),代价是平均平方误差。左图是数据和当前的直线,右图是参数空间的代价地形。紫色是每一步都用全部 200 个点的 GD,琥珀色是每一步只抽 \(B\) 个点的 SGD(左图中带圈的点)。两者起点、学习率相同。
- 设 \(B=1\) 运行 100 步以上:路径在最小值附近"抖"成一团,永远停不下来。
- 把 \(B\) 拉到 200:两条路径完全重合,因为这时 SGD 就是 GD。
- 保持 \(B=1\),把 \(\eta\) 调小到 0.01 以下再跑:抖动变小了,但前进变慢。这是噪声与速度的权衡。
SGD 每一步的成本只有 GD 的 \(B/N\),却走得几乎一样"对"。早期(离最优点很远)时,梯度信号远大于噪声,小批量足够;晚期(离最优点很近)时,真梯度很小,噪声占了上风,这就是为什么要逐渐减小学习率或增大批量。
4噪声到底有多大:梯度的"云"
固定在参数空间的一个点 \(\x\),反复抽取小批量,每次得到一个梯度估计 \(\mathbf g_B\)。把这些估计画在"梯度空间"里,就是一团围绕真梯度 \(\nabla f(\x)\) 的点云。点云的中心就是真梯度(无偏),点云的大小随 \(B\) 增大而缩小,标准差按 \(1/\sqrt B\) 收缩。拖动左图的手柄换一个位置,改变批量,对照理论预测的椭圆。
- 把 \(B\) 从 4 调到 16:点云的大小缩小为约一半(\(\sqrt{16/4}=2\))。
- 把手柄拖到最小值(右下方的最优点 \(\x^\star\))附近,设 \(B=4\):真梯度几乎被噪声淹没,这时单个小批量甚至可能指向上坡。
5学习率日程:先大后小
噪声让 SGD 在最小值附近不断被"踢"开。固定学习率 \(\eta\) 时,每一步被踢的幅度 \(\propto\eta\),而回拉的力来自曲率,两者平衡下来,参数不会收敛到最优点,而是停在一个噪声球里,球的"代价高度"约为 \(\eta\,\mathrm{tr}(C)/(4B)\)(\(C\) 是单样本梯度在最优点的协方差,后面会推导)。想要更低,要么减小 \(\eta\),要么增大 \(B\)。
实践中的常规做法是让 \(\eta\) 随时间减小:开头用大学习率快速接近,结尾用小学习率压低噪声球。下面比较五种常见的日程;每条曲线是 24 次独立运行的平均,每次运行都是真实的 SGD。
- 让余弦日程的最终误差比常数日程低 3 倍以上(默认设置就够,调一下滑块试试它为何稳健)。
- 不用任何衰减日程,只靠调 \(\eta_0\) 或 \(B\),让常数日程的最终误差低于 \(10^{-3}\)。
- 把 \(\eta_0\) 调到最大并取 \(B=1\):常数日程发散。衰减日程会在学习率降下来之前就被"炸飞"吗?
6噪声什么时候是朋友:逃出鞍点
6.3 节的"鞍点"地形 \(f=\tfrac12x^2+\tfrac14y^4-\tfrac12y^2\):沿 \(x\) 方向是碗,沿 \(y\) 方向,原点处是山脊(\(f_{yy}=-1\)),两侧才是 \((0,\pm1)\) 两个谷底。如果起点恰好在 \(y=0\) 这条线上,梯度的 \(y\) 分量永远是 0,GD 会老老实实滑进鞍点 \((0,0)\) 并停在那里。
现在给每个样本加一个零均值的扰动 \(f_i(\x)=f(\x)+\boldsymbol\xi_i^\top\x\)(\(\sum_i\boldsymbol\xi_i=\mathbf 0\),所以全批量梯度还是 \(\nabla f\))。小批量梯度是 \(\nabla f(\x)+\bar{\boldsymbol\xi}_B\):噪声自带 \(y\) 方向的分量,把 24 个小球从 \(y=0\) 线上踢开,山脊的负曲率再把它们推向两个谷之一。
- 选 "GD",运行:所有小球都停在鞍点。(梯度为零 ≠ 最小值,6.1 节。)
- 选 "SGD",运行:大部分小球逃出鞍点,分别落入上下两个谷底。
- 逃出之后,小球仍在谷底附近"抖动"。把 \(B\) 调大或 \(\sigma\) 调小,抖动的幅度怎么变?
7再看数学
提示:悬停在带底色的符号上,FIG 1、FIG 2 和 FIG 3 中对应的元素(小批量梯度、真梯度、噪声椭圆、噪声球虚线)会被强调。
有限和与小批量梯度
机器学习与标定里的代价几乎总是样本平均:
其中 \(\mathcal B\) 是随机抽出的 \(B\) 个下标。若每个下标被抽到的概率相同,则 \(\mathbf g_B\) 是 \(\nabla f\) 的无偏估计;协方差为
\(\Sigma\) 是单样本梯度的协方差。因子 \(1/B\) 就是 FIG 2 里点云随 \(B\) 缩小的原因;\((N-B)/(N-1)\) 是"不放回"抽样的修正,\(B=N\) 时为 0(没有随机性)。
SGD 的更新与收敛条件
要让 SGD 收敛到最优点(凸问题),Robbins–Monro 条件要求:\(\sum_k\eta_k=\infty\)(走得动:总路程够长)且 \(\sum_k\eta_k^2<\infty\)(停得住:噪声的累积方差有限)。\(\eta_k=\eta_0/(1+k/\tau)\) 这类 \(1/k\) 衰减满足条件,常数 \(\eta\) 不满足。
噪声球的高度(二次函数上的推导)
在最优点附近 \(f\approx f^\star+\tfrac12\mathbf e^\top H\mathbf e\),\(\mathbf e=\x-\x^\star\)。一步更新为 \(\mathbf e_{k+1}=(I-\eta H)\mathbf e_k-\eta\boldsymbol\zeta_k\),其中噪声 \(\boldsymbol\zeta_k\) 均值为 0、协方差 \(C_B=C/B\)(\(C\) 是 \(\Sigma\) 在最优点处的值)。取稳态协方差 \(P=\mathbb E[\mathbf e\mathbf e^\top]\),令 \(P=(I-\eta H)P(I-\eta H)+\eta^2C_B\),展开并略去 \(\eta^2\) 项:
取迹时用到 \(\mathrm{tr}(HP+PH)=2\,\mathrm{tr}(HP)\)。结论非常干净:噪声球的高度与 \(\eta\) 成正比,与 \(B\) 成反比。把 \(\eta\) 和 \(B\) 同时乘以 2 的话,球的高度不变,这就是深度学习里"批量加倍,学习率也加倍"的线性缩放经验(小批量范围内)的来源。FIG 3 的虚线正是这个公式。
动量与 Adam 放在 SGD 里
6.3 节的动量、RMSProp、Adam,在实际训练里都是用小批量梯度代替 \(\nabla f\) 来运行的。动量对连续多步的 \(\mathbf g_B\) 取指数平均,等于把噪声平均掉了一部分,但它同时把有效学习率放大到约 \(\eta/(1-\beta)\),噪声球也按这个有效学习率缩放;Adam 的二阶矩 \(\mathbf s\) 里含有噪声的方差,因此在梯度很小、几乎全是噪声的坐标上它会自动把步子变小。这些在 Part V 的"损失、泛化与正则化"和"反向传播"章节里会反复用到;这里只需记住:噪声来自小批量,与用哪种优化器无关。
8机器人中的它:边采数据边标定连杆长度
一台两连杆机械臂的连杆长度 \((l_1,l_2)\) 因为装配误差与出厂标称值有偏差。让手臂摆出一系列姿态 \(\mathbf q_i\),用动捕测出手爪的真实位置 \(\mathbf p_i\)(带 5 cm 噪声)。正运动学 \(\mathrm{FK}(\mathbf q_i;\mathbf l)=l_1\mathbf a_i+l_2\mathbf b_i\),其中 \(\mathbf a_i=(\cos q_1,\sin q_1)\),\(\mathbf b_i=(\cos(q_1+q_2),\sin(q_1+q_2))\),对 \(\mathbf l\) 是线性的,所以代价
是凸二次函数(6.2 节:与仿射映射复合)。单个测量的梯度是 \(\big(\mathbf a_i^\top\mathbf e_i,\ \mathbf b_i^\top\mathbf e_i\big)\),\(\mathbf e_i\) 是该测量的预测误差。下图可以让 SGD 每次只用 \(B\) 条测量,GD 每次用全部 300 条;横轴是用掉的测量条数而不是迭代次数,这才是真实世界里的成本。
- 用"窄姿态范围"运行:在用掉 1000 条测量时,SGD 的误差已经比 GD 小得多(GD 才走了三步多)。
- 切换到"多样姿态":代价变圆,两种方法都快得多,条件数从约 22 降到约 1.4。数据采得好,比算法选得好更重要。
对机器人学习,SGD 是日常:行为克隆、扩散策略、VLA 的训练都是在几十万到上亿条 (观测, 动作) 样本上用 AdamW + 小批量 + 余弦或线性衰减的学习率日程,前面还要加一小段预热(FIG 3 的最后一条曲线,Adam 的二阶矩刚启动时估计不准)。在线标定、在线系统辨识则是"流式"的:每个新测量只做一次小更新,不保存历史。标定的另一个现实问题就是 FIG 5 里的激励不足:姿态太单一时,\(H\) 的条件数很大,不论 GD 还是 SGD 都慢,要靠主动设计采集姿态来解决。
9常见误区
训练日志里的损失是各个小批量上的损失,本身带噪声。曲线上下跳动不代表出了问题,也不代表过拟合;要比较两次运行,需要看平滑后的曲线或固定验证集上的损失,并多跑几个随机种子(FIG 3 就是 24 次平均)。
批量越大,每步噪声越小,但每步成本也线性增加。过了某个"临界批量"之后,再增大 \(B\) 只是浪费算力:梯度已经足够准,瓶颈在步数。另外,极大的批量常常泛化更差(噪声的正则化作用变弱),需要重新调学习率和日程。
"无偏"要求小批量是总体的随机子集。机器人数据往往按时间顺序存放,相邻帧高度相关;若按顺序取,一个批量里全是同一个场景,梯度严重有偏,训练会在不同场景之间来回摆。务必在每个 epoch 前打乱,或在多个 episode 之间随机混合采样。
噪声既让你停不稳(FIG 1、3),又能把你从鞍点和尖锐的谷里踢出去(FIG 4)。这是一个有时间尺度的权衡:训练早期,噪声帮你探索;晚期,要把它压下去才能收敛。因此"先大后小"的日程是几乎所有系统的标配,而不是一种技巧。
10小练习
11延伸阅读
- I. Goodfellow, Y. Bengio & A. Courville, Deep Learning, Ch. 8 — 小批量大小、学习率日程、动量与自适应方法在神经网络训练中的实践
- L. Bottou, F. E. Curtis & J. Nocedal, Optimization Methods for Large-Scale Machine Learning, SIAM Review, 2018 — SGD 的收敛理论、噪声球与批量选择的严格综述
- H. Robbins & S. Monro, A Stochastic Approximation Method, Annals of Mathematical Statistics, 1951 — 随机逼近的原始论文,Robbins–Monro 条件的出处
- S. Boyd & L. Vandenberghe, Convex Optimization, Ch. 9 — 确定性梯度法的收敛分析,是理解 SGD 噪声球的基础