跳到内容

第 10 卷 / 第 11 章 / 第 3 课

11.3 梯度与优化:从下降方向到可验证的解 ​

梯度只描述函数在当前位置的一阶变化。沿负梯度移动是自然起点,但优化算法还要回答:步长多大、何时停止、约束怎样处理,以及得到的是局部极小值、鞍点还是可证明的全局解。

本课目标 ​

  • 从局部一阶近似推导梯度下降;
  • 区分凸问题、局部极小值、鞍点和驻点;
  • 理解学习率、随机梯度与动量的作用;
  • 建立比“损失下降了”更可靠的优化检查清单。

1. 从局部模型得到下降步骤 ​

对可微函数 f,在 x 附近有:

f(x+Δx)≈f(x)+∇f(x)TΔx.

当梯度非零时,在欧氏范数下,负梯度是局部下降最快的方向,于是得到:

xt+1=xt−ηt∇f(xt),

其中 ηt>0 是步长或学习率。

这个推导是局部的。步长过大时,一阶近似不再可靠,可能越过谷底甚至发散;步长过小时,进展缓慢,也可能在数值精度范围内看似不动。

2. 一个可检查的单变量例子 ​

对

f(x)=x2+3x+2,

导数是 f′(x)=2x+3,解析最小点为 x=−1.5。

python
def loss(x: float) -> float:
    return x * x + 3 * x + 2

def gradient(x: float) -> float:
    return 2 * x + 3

x = 8.0
learning_rate = 0.2

for step in range(100):
    grad = gradient(x)
    if abs(grad) < 1e-10:
        break
    x -= learning_rate * grad

print(f"{x:.8f} {loss(x):.8f}")   # -1.50000000 -0.25000000
print(abs(gradient(x)) < 1e-10)  # True

这个问题是严格凸二次函数,结构非常友好。把它的行为直接推广到神经网络,会忽略非凸性、随机梯度、病态曲率和参数冗余。

可以直接推导步长边界:令误差 et=xt+1.5,则 et+1=(1−2η)et。除起点已最优外,收敛当且仅当 0<η<1;η=0.5 一步到最小点,η=1 在两点间等幅振荡,η>1 则振幅增长。一般问题不能照搬这个区间,因为曲率变了。

3. 驻点不等于最小值 ​

满足 ∇f(x)=0 的点称为驻点,可能是:

  • 局部极小值;
  • 局部极大值;
  • 鞍点;
  • 更高阶的平坦点。

一维中可用二阶导数辅助判断。多元函数的 Hessian 矩阵由二阶偏导数组成:

Hij=∂2f∂xi∂xj.

若函数在该内点附近二阶连续可微,驻点处的 Hessian 正定可保证严格局部极小,负定保证严格局部极大,不定说明鞍点。半正定不能单凭二阶信息判断:x4 与 −x4 在零点的 Hessian 都是零,却分别有极小和极大。边界点还必须结合可行方向分析。

若可行域为凸集且目标函数在其上为凸函数,任意局部极小值也是全局极小值。若还是严格凸,极小值至多一个。但“使用梯度下降”本身不保证收敛:还需要对光滑性、步长等条件作出约束。对一般非凸函数,更不能声称一定收敛到局部最优;算法可能停在鞍点附近、振荡或发散。

严格凸保证的是“至多一个”,不保证最小值存在。例如 ex 在实数上严格凸,趋向下确界 0,却没有任何有限点取到 0。对无约束凸可微问题,驻点一旦存在就是全局最优;带约束时,最优点的普通梯度未必为零。

4. 学习率控制局部模型的可信范围 ​

常见步长策略:

  • 固定学习率:简单,但需要调参;
  • 衰减学习率:后期减小震荡;
  • 线搜索:尝试满足充分下降条件;
  • 自适应方法:根据历史梯度调整不同参数的有效步长。

Adam、RMSprop 和带动量的 SGD 都利用历史信息,但它们的行为、内存成本和收敛性质不同。不能把“最终都减去某个更新量”理解成它们在所有问题上等价。

动量的一种形式为:

vt+1=βvt+∇f(xt),xt+1=xt−ηvt+1.

它能在方向一致时积累速度、减轻狭长谷地中的来回摆动,也会引入新的超参数和过冲风险。

这是一种未归一化的动量约定,常取 0≤β<1、初始速度为零。有些实现将梯度乘以 1−β,此时学习率尺度也不同;比较公式前应先核对约定。

5. 全批量、随机与小批量梯度 ​

机器学习目标常写成样本损失的平均:

F(w)=1N∑i=1Nℓi(w).
  • 全批量梯度每步使用所有样本,方向稳定但成本高;
  • 随机梯度每步使用单个样本,便宜但噪声大;
  • 小批量梯度在硬件并行、估计噪声和吞吐之间折中。

随机性有时帮助离开某些平坦区域,但它不是全局最优保证。抽样方式、批大小和数据顺序都会影响训练轨迹。

若各样本损失可微,给定当前参数后均匀随机抽一个样本,它的梯度才是上述经验平均梯度的无偏估计。非均匀抽样需要相应加权;相关样本、固定顺序和有状态的数据处理也会改变这个推导。全批量消除了这类抽样噪声,仍可能因步长过大而发散。

6. 有约束优化不能只做普通更新 ​

若参数必须满足约束,例如概率非负且和为 1,直接梯度下降可能走出可行域。常见思路包括:

  • 投影梯度:更新后投影回可行集合;
  • 重新参数化:用 softmax 等结构保证约束;
  • 拉格朗日乘子:分析等式约束下的必要条件;
  • 惩罚或障碍方法:把约束违反转入目标函数。

投影到非空闭凸集时,欧氏投影唯一。Softmax 用有限参数只产生严格正概率,不能精确到达单纯形边界上的零概率;重新参数化因此可能改变可表示的可行点。下面最小化 (x-2)² 且要求 0≤x≤1,每次更新后截回区间:

python
def constrained_gradient(x):
    return 2 * (x - 2)

def project(x):
    return min(1.0, max(0.0, x))

x, eta = 0.0, 0.25
for _ in range(5):
    x = project(x - eta * constrained_gradient(x))
mapping = (x - project(x - eta * constrained_gradient(x))) / eta
print(x, constrained_gradient(x), mapping)  # 1.0 -2.0 0.0

最优点是 1,普通梯度仍为 -2,但再做一次投影更新已经不动,mapping 为零。这解释了为什么有约束问题要检查投影梯度或相应 KKT 条件,不能一律等待普通梯度归零。一般非凸可行集的投影也未必唯一。

7. 优化结果的检查清单 ​

停止训练前至少检查:

  1. 目标值的趋势是否符合算法预期,随机梯度不要求每步下降;
  2. 适合当前约束的驻点残差或参数更新量是否足够小;
  3. 是否出现 NaN、无穷大或明显震荡;
  4. 约束是否满足;
  5. 验证集指标是否与训练目标一致;
  6. 更换初值或随机种子后结果是否稳定;
  7. 数值梯度检查是否支持自动微分结果。

仅看训练损失会把过拟合、数据泄漏和错误目标函数藏起来。优化器只负责寻找你写下的目标,不负责判断目标是否代表真实需求。

常见误区 ​

  • 负梯度指向全局最小值:它只给出当前点的局部下降方向。
  • 梯度为零就是训练成功:还可能是鞍点、极大值或数值下溢。
  • 损失下降说明模型正确:错误标签、泄漏特征和不合适目标也能被优化。
  • 自适应优化器不需要学习率:它们仍有全局步长和其他关键超参数。

练习 ​

  1. 改变单变量示例的学习率,观察稳定、振荡和发散区域。
  2. 分析 f(x,y)=x2−y2 在原点的梯度和 Hessian,说明它为何是鞍点。
  3. 为约束 x+y=1 的最小化问题写出拉格朗日函数。
  4. 给一个训练循环设计停止条件,避免只依赖固定迭代次数。

小结 ​

梯度下降来自局部线性近似,学习率决定一次能相信这个近似多远。凸性提供全局结构,Hessian 描述局部曲率,随机梯度和动量改变计算成本与轨迹。真正可信的优化结果还需要约束检查、数值检查和任务指标验证。

最后一章会处理两类经常被藏在公式背后的边界:信息究竟怎样度量,以及同一个数学表达式为什么在有限精度计算机上可能给出完全不同的结果。

Built with VitePress | Software Systems Atlas