AI

优化算法

动手深度学习

Posted by LXG on April 28, 2026

优化和深度学习

优化的目标

概念 目标
优化(Optimization) 降低训练误差
深度学习(ML目标) 降低泛化误差

为什么深度学习必须用“数值优化”

现实情况:

  • 深度学习模型参数:上百万甚至上亿
  • 损失函数:高度非线性

👉 结果:

  • 没有解析解(不能直接算)
  • 只能靠迭代逼近

训练误差和泛化误差


        泛化误差
            ↑
            |        ● 过拟合模型(训练误差低,但泛化差)
            |
            |
            |   ● 理想模型(泛化最好)
            |
            |
            |● 欠拟合模型
            +--------------------→ 训练误差(经验风险)

深度学习中的优化挑战

局部最小值(Local Minimum)

local_minimum

在深度学习中,局部最小值其实没那么可怕

在高维参数空间(比如 Transformer):

  • 局部最小值很少
  • 鞍点更多(更大的问题)

鞍点 (Saddle Point)

鞍点 = 梯度为 0,但其实还有路可以走的地方

特点 局部最小值 鞍点
梯度 0 0
是否最小 是(局部) ❌ 不是
是否可继续下降 ❌ 不行 ✅ 可以
在深度学习中 较少 🔥 非常多

saddle_point

梯度消失

梯度消失就是:反向传播时信号在层层传递中不断变弱,最终导致前面网络“学不到东西”。

凸性

convexity

凸函数:

  • 梯度下降 → 直接收敛到最低点
  • 路径平滑稳定 非凸函数:

  • 可能掉进“局部最小值”
  • 甚至停在某个坑里不动
情况 结果
凸函数 平均值 ≥ 中间值(安全)
非凸函数 平均可能更差(有坑)

凸性 = 没有坑的地形;优化问题如果是凸的,梯度下降几乎就是“自动找到最优解”

约束优化

凸优化里最核心的思想之一:约束优化(constrained optimization)

如果约束是凸的,那么可行域也是“没有坑”的结构

✔ 凸约束的好处

  • 任意两点连线仍在区域内
  • 不会出现“断裂/坑洞”

👉 优化不会被困住

投影法(Projection)

projections

轨迹:

  • 在区域内自由下降
  • 一旦越界 → 直角“弹回”

拉格朗日法(Lagrangian)——“加一个隐形力场”

lagrangian

📌 几何效果

目标函数 + 约束变成“新地形” 最优点 = 梯度为0的点(含约束影响)

👉 你可以理解为:

“地形被改造了”

惩罚法(Penalty Method)——“违规就变贵”

penalty_method

🎯 几何理解

不是改规则,而是:

❗ 违反约束 → loss 变大

📌 几何效果 可行域外:地形突然变高(惩罚墙) 优化器自动远离

总结

constraint_methods


- 投影法:每一步梯度更新后都“投影回约束线”,所以可行性最好, |g(x)| 基本立刻很小。
- 拉格朗日法:通过乘子 λ 动态调节“目标下降”和“满足约束”的平衡,轨迹通常靠近约束并逐步收敛。
- 惩罚法:把约束违反写进目标函数,早期可能偏离约束,随着罚系数 ρ 增大才更强地逼近可行域。
- 右图对数曲线 |x+y-1| 用来直观看“谁更快满足约束”。

方法 几何理解 核心直觉
投影法 走出去再拉回来 “强制回到合法区域”
拉格朗日 改造地形 “约束变成力场”
惩罚法 加高墙 “违规成本无限大”

梯度下降

学习率

学习率 结果
太大 发散 ❌
太小 收敛慢 ❌
合适 稳定下降 ✅

多元梯度下降

gradient_descent

1️⃣ 等高线(背景)

  • 每条线 = 同一高度
  • 你可以理解为“山的地图”

2️⃣ 红色点轨迹

  • 每一步参数更新
  • 就是优化路径

3️⃣ 蓝色箭头(重点!!!)

👉 每一步梯度方向:指向“上坡最快方向”, 反方向就是下降方向

🔵 1. zigzag(之字形)

原因:

  • x方向坡度小
  • y方向坡度大

👉 导致来回震荡

🔵 2. 逐渐进入“谷底”

  • 远处走得快
  • 近处变慢

🔵 3. 最终收敛

→ (0, 0)

自适应方法-牛顿法

newton_smooth

任何光滑函数,在足够小范围内都“像一个二次函数”

几何直觉(最关键)

想象你在山上:

🟥 梯度下降


我不知道前面地形
→ 先试一步
→ 再试一步

🟦 牛顿法


我看脚下这块地:
- 斜率是多少?
- 弯曲程度是多少?

👉 假设这附近是个“碗”

👉 直接算出碗底在哪

优缺点

⭐ 牛顿法适合:

  • ✔ 光滑函数
  • ✔ 凸问题
  • ✔ 已经接近最优解
  • ✔ 维度不高、

❌ 牛顿法不适合:

  • 非凸(深度学习)
  • 高维(神经网络)
  • 噪声梯度(SGD场景)
  • 非光滑函数

预处理

计算和存储完整的Hessian非常昂贵,而改善这个问题的一种方法是“预处理”

hessian_method


🟥 左图(没预处理)

你会看到:

等高线是“细长椭圆”
路径来回折(zigzag)

👉 本质:

x方向快,y方向慢 → 震荡

🟩 右图(预处理后)

你会看到:

等高线变“圆”
路径更直

👉 本质:

各方向尺度统一了

🔥 核心理解(非常重要)

❗ 预处理做了什么?

不是改函数:

❌ f(x,y) 没变

而是:把“椭圆地形”拉成“圆地形”

👉 坐标变换

🎯 一句话本质 : 预处理 = 改坐标系,让优化问题从“拉伸空间”变成“均匀空间”

线搜索

line_search_optimization


🟥 普通 GD

走一步 → 看情况 → 再调整

🟦 线搜索 GD

每一步:
在这条方向上“试很多步”
找到最优点再走

线搜索的思想是“每一步都走最优距离”,但在深度学习中,这个“最优”太贵了,所以我们用便宜的近似方法替代它。

随机梯度下降

随机梯度更新

gradient_descent_noisy

🟥 1. GD(左图)

👉 特点:

  • 路径稳定
  • 方向一致
  • 但可能“慢”

🟦 2. SGD(右图)

👉 特点:

  • 每一步方向抖动
  • 有点“乱走”
  • 但整体在下降

为什么要加入噪声

噪声 = 用更少计算,换取“探索能力 + 泛化能力 + 跳出坏点能力”

🎯 噪声的三大价值:

1️⃣ 探索能力

→ 跳出鞍点 / 局部最优

2️⃣ 泛化能力

→ 偏向平坦解

3️⃣ 计算效率

→ 用小批量代替全量

动画理解

stochastic_gradient_update

GD 每一步很准但很贵;SGD 每一步很便宜但带噪声,因此在“单位时间/单位算力”下,SGD 往往更高效。

方法 类比
GD 用高清地图,但每走一步都要重新打印地图
SGD 用模糊指南针,但可以快速不断试错

计算量对比

stochastic_gradient_update_2

通俗易懂理解随机梯度


GD (Gradient Descent):梯度下降

形象比喻: 稳扎稳打的“完美主义者”。

在下山之前,你必须站在原地,仔细测量四周每一个方向的坡度,计算出最精确的“下山最快路径”,然后迈出一小步。

操作方式: 每次更新模型,都要把全部数据看一遍。

优点: 走得很稳,方向非常准确,几乎总是朝着山谷前进。

缺点: 极慢。如果你有 1 亿条数据,每走一小步都要算 1 亿次,电脑会累瘫。

########################################

SGD (Stochastic Gradient Descent):随机梯度下降

形象比喻: 追求效率的“急性子”。

你不再测量所有方向,而是随手抓起一条数据(或者一小波数据),瞄一眼大致方向,立马就迈步。

操作方式: 每次更新模型,只看一条(或一小部分)数据。

优点: 极快。模型更新频率高,能够迅速开始“下山”。

缺点: 走得歪歪扭扭。因为只看局部数据,有时会走错路,甚至往山上跑,但大体趋势还是向下的。

stochastic_gradient

特性 GD(批量梯度下降) SGD(随机梯度下降)
数据使用方式 每次用全部样本平均梯度 每次用单个样本梯度近似
梯度本质 真实梯度 ( \nabla L ) 随机估计梯度 ( \nabla L_i \approx \nabla L )
方向稳定性 非常稳定(低方差) 抖动(高方差)
收敛轨迹 平滑下降 锯齿状下降
收敛速度(单步) 慢但稳 快但不稳定
计算开销 O(N) 每步都扫全数据 O(1) 每步只算一个样本
内存需求 需要加载全部数据 只需一个样本
泛化能力 容易过拟合局部最优路径 噪声帮助跳出局部最优
工程应用 小数据集 / 理论分析 大规模深度学习主流