深度学习中的优化器

深度学习中的优化器

培训课件 · 面向深度学习入门与进阶

配套案例:MNIST 手写数字识别(Flatten → Dense(128) → Dense(10))


1. 开场:为什么要谈「优化器」?

想象你在一座大雾弥漫的山谷里找最低点:

  • 损失函数告诉你:现在站的地方有多「高」(误差有多大);
  • 梯度告诉你:脚下往哪个方向是下坡;
  • 优化器决定:你迈多大步、要不要参考走过的路、每条路上的步长要不要不一样。

训练神经网络,本质上就是在参数空间 里找一组权重 W,bW, bW,b,让预测误差尽量小。

网络结构决定了「山谷的形状」,而优化器决定了你怎么下山

同一套 MNIST 网络,换成 SGD 或 Adam,收敛速度、最终精度、显存占用都会不一样------这正是优化器值得单独学一课的原因。

本课件将从概念讲到公式,再落到你熟悉的 MNIST 案例,并对照五种常用优化器的参数量、优缺点与面试考点。


2. 通俗讲解:优化器是什么?

2.1 一句话定义

优化器(Optimizer):根据损失函数对参数的梯度,按某种规则更新网络权重的算法。

一次典型的训练步骤:

复制代码
前向传播 → 算损失 Loss → 反向传播得到梯度 g → 优化器根据 g 更新参数 w

没有优化器,你就算得出梯度,也不知道「参数该怎么改」。

2.2 三个核心角色

角色 通俗比喻 符号
参数 www 你在山谷中的位置 网络里的权重、偏置
梯度 g=∇wLg=\nabla_w Lg=∇wL 当前位置最陡的下坡方向 反向传播算出来
学习率 η\etaη 这一步打算迈多大 learning_rate

最朴素的更新只有一句话:

w←w−η⋅g w \leftarrow w - \eta \cdot g w←w−η⋅g

「沿着梯度的反方向走一小步。」------这就是 SGD 的核心思想。

后面更高级的优化器,都是在这句话上加「记忆」和「自适应步长」。

2.3 为什么不只用「减梯度」这么简单?

真实损失曲面往往像崎岖山地,而不是光滑碗底:

  1. 有的方向陡、有的方向平:固定步长容易在陡处震荡、在平处爬不动;
  2. 噪声大:每个 batch 的梯度都在抖,直走容易走偏;
  3. 鞍点多:梯度接近 0,但不一定到了谷底。

于是人们给优化器加上两类「外挂」:

  • 一阶历史(动量):记住刚才大概往哪走,减少左右摇摆;
  • 二阶历史(自适应学习率):哪个参数经常被大力更新,就给它把步长调小。

2.4 五种优化器的「进化故事」(先建立直觉)

复制代码
SGD      → 只会看当前这一步的梯度
   ↓
SGDM     → 加上「惯性」(动量),走得更稳更快
   ↓
Adagrad  → 给每个参数单独记账:常更新的自动减小步长
   ↓
RMSProp  → 账本改成「近期加权平均」,避免 Adagrad 后期学不动
   ↓
Adam     → 动量 + 自适应步长 两者都要(目前最常用的默认选择)

记住这条进化线,后面的公式就不会显得突兀。

2.5 公式速览(对照记忆)

下面统一约定:www 为参数,ggg 为当前梯度,η\etaη 为学习率,ε\varepsilonε 为防止除零的小数。

(1)SGD

w←w−η g w \leftarrow w - \eta\, g w←w−ηg

无额外状态,最简单。

(2)SGDM(SGD with Momentum)

引入速度 vvv(动量),μ\muμ 一般为 0.9:

v←μ v−η g,w←w+v v \leftarrow \mu\, v - \eta\, g,\quad w \leftarrow w + v v←μv−ηg,w←w+v

像滚下山的球:不只看脚下坡度,还带着惯往前冲。

(3)Adagrad

为每个参数累加历史平方梯度 sss:

s←s+g2,w←w−ηs+ε g s \leftarrow s + g^2,\quad w \leftarrow w - \frac{\eta}{\sqrt{s}+\varepsilon}\, g s←s+g2,w←w−s +εηg

常更新的参数,分母变大 → 有效学习率变小。

(4)RMSProp

把「永久累加」改成指数滑动平均 Eg2Eg\^2Eg2,ρ\rhoρ 一般为 0.9:

Eg2←ρ Eg2+(1−ρ) g2,w←w−ηEg2+ε g Eg\^2 \leftarrow \rho\, Eg\^2 + (1-\rho)\, g^2,\quad w \leftarrow w - \frac{\eta}{\sqrt{Eg\^2}+\varepsilon}\, g Eg2←ρEg2+(1−ρ)g2,w←w−Eg2 +εηg

解决 Adagrad 后期步长过小的问题。

(5)Adam

同时维护一阶矩 mmm 与二阶矩 vvv(这里的 vvv 是平方梯度均值,不是 SGDM 的速度):

m←β1m+(1−β1) gv←β2v+(1−β2) g2m^=m1−β1t,v^=v1−β2tw←w−ηm^v^+ε \begin{aligned} m &\leftarrow \beta_1 m + (1-\beta_1)\, g \\ v &\leftarrow \beta_2 v + (1-\beta_2)\, g^2 \\ \hat{m} &= \frac{m}{1-\beta_1^t},\quad \hat{v} = \frac{v}{1-\beta_2^t} \\ w &\leftarrow w - \eta \frac{\hat{m}}{\sqrt{\hat{v}}+\varepsilon} \end{aligned} mvm^w←β1m+(1−β1)g←β2v+(1−β2)g2=1−β1tm,v^=1−β2tv←w−ηv^ +εm^

默认常用:β1=0.9, β2=0.999\beta_1=0.9,\ \beta_2=0.999β1=0.9, β2=0.999。

直觉上:Adam ≈ 动量方向(像 SGDM)+ 自适应步长(像 RMSProp)

2.6 自然过渡:从概念到你的代码

理论再清楚,也要落到一行配置上。在 Keras 里,换优化器往往只改 compile 里的一个参数:

python 复制代码
model.compile(
    optimizer='adam',  # 也可换成 SGD / RMSprop / Adagrad 等
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics=['sparse_categorical_accuracy']
)

接下来用你已经跑通过的 MNIST Sequential 网络,把「优化器到底多占了多少参数」这件事算清楚------这是理解优化器成本最直观的案例。


3. 应用案例:MNIST 网络里的优化器参数

3.1 案例网络长什么样?

text 复制代码
输入 (batch, 28, 28)
  → Flatten          → (batch, 784)      参数: 0
  → Dense(128, relu) → (batch, 128)      参数: 784×128 + 128 = 100,480
  → Dense(10, softmax)→ (batch, 10)      参数: 128×10 + 10 = 1,290

可训练参数总量:

P=100,480+1,290=101,770 P = 100{,}480 + 1{,}290 = 101{,}770 P=100,480+1,290=101,770

对应 model.summary() 中的 Trainable params: 101,770

这些是网络真正「认识数字」的权重。

说明:Dense(128) 里的 128 是隐藏层宽度(超参数,可改);

输出层 Dense(10) 的 10 对应 0~9 十类,一般不要乱改。

3.2 你可能看到过这样的 summary

text 复制代码
Total params: 305,312 (1.16 MB)
Trainable params: 101,770 (397.54 KB)
Non-trainable params: 0 (0.00 B)
Optimizer params: 203,542 (795.09 KB)

很多人第一次会懵:网络明明只有约 10 万参数,为什么 Total 变成了 30 万?

答案是:

Total params=Trainable+Optimizer=101,770+203,542=305,312 \text{Total params} = \text{Trainable} + \text{Optimizer} = 101{,}770 + 203{,}542 = 305{,}312 Total params=Trainable+Optimizer=101,770+203,542=305,312

Optimizer params 不是网络结构的一部分 ,而是优化器在训练时额外保存的「内部状态」(如动量、平方梯度均值等)。

推理部署时通常只加载 Trainable;断点续训才需要连同优化器状态一起保存。

3.3 统一公式(结合本案例)

在当前 Keras 实现中,优化器几乎都会额外挂 2 个标量:

  • iteration:更新了多少步
  • learning_rate:当前学习率

再设每个可训练参数额外保存 kkk 份同形状状态,则:

Optimizer params≈k⋅P+2 \text{Optimizer params} \approx k \cdot P + 2 Optimizer params≈k⋅P+2

对本案例 P=101,770P=101{,}770P=101,770,实测如下:

优化器 kkk 额外状态含义 Optimizer params 计算过程
SGD 0 无 per-param 状态 2 0⋅P+2=20\cdot P+2=20⋅P+2=2
SGDM 1 动量 vvv 101,772 1⋅P+21\cdot P+21⋅P+2
Adagrad 1 平方累加 sss 101,772 1⋅P+21\cdot P+21⋅P+2
RMSProp 1 平方滑动平均 101,772 1⋅P+21\cdot P+21⋅P+2
Adam 2 一阶矩 mmm + 二阶矩 vvv 203,542 2⋅P+22\cdot P+22⋅P+2

以 Adam 为例拆开看:

内容 数量
全部权重的 momentum mmm 101,770
全部权重的 velocity vvv 101,770
iteration + learning_rate 2
合计 203,542

这也解释了你在 Adam 下看到的那行:

Optimizer params: 203,542 (795.09 KB)

3.4 内存直觉

按 float32(4 字节)粗算优化器额外占用:

kkk 代表 约额外内存
0 SGD 可忽略
1 SGDM / Adagrad / RMSProp ≈ 397 KB
2 Adam ≈ 795 KB

MNIST 小网络上差别不大;一旦 PPP 上亿(大模型),Adam 比 SGD 多占约两倍优化器状态,就会成为显存选型的重要因素。

3.5 案例代码片段(训练入口)

python 复制代码
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer='adam',  # 对比实验时可改为 SGD(momentum=0.9) 等
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics=['sparse_categorical_accuracy']
)

model.fit(x_train, y_train, batch_size=32, epochs=2,
          validation_data=(x_test, y_test), validation_freq=1)
model.summary()  # 重点看 Trainable / Optimizer / Total

建议课堂演示: 只改 optimizer,其余不动,观察 Optimizer params 与收敛曲线如何变化。


4. 生产应用场景:优化器怎么选?

场景 常见选择 原因(通俗说)
图像分类 / 通用深度学习起步 Adam 省心、收敛快,超参相对好用
CNN 大规模训练、追求极致精度 SGD + Momentum(常配合学习率衰减) 调好后泛化往往更扎实
循环网络 / 序列模型(部分任务) RMSProp 或 Adam 对非平稳目标更稳
稀疏特征(推荐、广告、部分 NLP 稀疏输入) Adagrad / Adam 低频特征也能得到合适更新幅度
显存极度紧张、超大模型 SGD 或融合优化器 / 低精度状态 优化器状态少,省显存
微调预训练模型 AdamW 等(Adam + 解耦权重衰减) 工业界微调常用变体
教学演示、算法对比实验 五种都跑一遍 便于理解 k=0/1/2k=0/1/2k=0/1/2 与曲线差异

落地经验一句话:

  • 先保证能收敛 → 优先 Adam
  • 要冲榜/要泛化 → 再认真调 SGDM + 学习率策略
  • 要省显存 → 看 kkk,能降则降。

5. 五种优化器对照:优缺点与参数量

5.1 总表(结合 MNIST 案例 P=101,770P=101{,}770P=101,770)

优化器 核心思想 优点 缺点 Optimizer params Total(约)
SGD 当前梯度直接走 实现简单、显存最省、调好后泛化潜力大 慢、易震荡、对学习率敏感 2 101,772
SGDM 加惯性平滑方向 加速收敛、减轻震荡 仍需仔细调学习率;无自适应步长 P+2=101,772P+2=101{,}772P+2=101,772 203,542
Adagrad 按历史强度缩小步长 适合稀疏特征 学习率可能衰减过快,后期「学不动」 P+2=101,772P+2=101{,}772P+2=101,772 203,542
RMSProp 滑动平均版自适应 修正 Adagrad 后期过小问题 超参仍需经验;默认无动量 P+2=101,772P+2=101{,}772P+2=101,772 203,542
Adam 动量 + 自适应 默认常用、收敛快、省调参时间 状态约为 2P2P2P;部分任务泛化略逊精心调过的 SGDM 2P+2=203,5422P+2=203{,}5422P+2=203,542 305,312

补充:若 RMSProp(momentum=0.9),会再多存一份动量,Optimizer params 升至约 2P+22P+22P+2,与 Adam 同量级。

5.2 优缺点「人话版」

SGD

像谨慎的徒步者,每一步只看脚下。路对了能到山顶,但容易走冤枉路。

SGDM

像带着惯性的滑板:下坡冲得快,过坑少抖一下。但仍是「全场统一步长」。

Adagrad

像给每个参数发「疲劳值」:经常大力更新的参数越走越慢。稀疏场景友好,但可能越来越不敢迈步。

RMSProp

疲劳值改成「只看最近一段时间」,不会无限累积,长期训练更合理。

Adam

既看惯性方向,又按参数自动调步长,像有经验的向导------大多数时候你交给他就行;但背包更重(状态更多)。

5.3 和网络层参数的区别(务必分清)

类型 例子 何时存在 推理时需要吗?
网络可训练参数 Dense 的 W,bW,bW,b 建网后就有 需要
优化器状态参数 Adam 的 m,vm,vm,v 开始训练后由优化器创建 通常不需要(续训才需要)

面试或写报告时,不要把 Optimizer params 说成「模型有 30 万参数」------准确说法是:模型约 10.2 万,Adam 训练时额外约 20.4 万状态。


6. 面试题(含参考思路)

基础概念

Q1. 优化器和损失函数有什么区别?

  • 损失函数:衡量「现在有多差」;
  • 优化器:根据梯度决定「参数怎么改」。

Q2. 学习率太大/太小会怎样?

  • 太大:损失震荡甚至发散;
  • 太小:收敛极慢,易停在较差区域。

Q3. 为什么需要动量(Momentum)?

用历史梯度方向平滑当前更新,加速同向、抑制震荡。

算法对比

Q4. Adagrad 和 RMSProp 的核心差别?

Adagrad 累加全部历史 g2g^2g2;RMSProp 用指数滑动平均,避免长期学习率过小。

Q5. Adam 为什么常作为默认优化器?有什么代价?

结合动量与自适应学习率,收敛快、好调;代价是约 2P2P2P 的额外状态,部分任务泛化可能不如调优后的 SGDM。

Q6. 训练一个 P=1亿P=1\text{亿}P=1亿 参数的模型,Adam 大约比 SGD 多占多少优化器状态(float32)?

粗算:SGD 几乎无 per-param 状态;Adam 约 2P2P2P 个 float → 2×108×4B≈800MB2\times 10^8 \times 4\text{B} \approx 800\text{MB}2×108×4B≈800MB 量级(未计框架开销)。

结合本案例

Q7. 下列 summary 如何解释?

Trainable=101770Optimizer=203542Total=305312,优化器是 Adam。

答:203542=2×101770+2203542 = 2\times 101770 + 2203542=2×101770+2(mmm 与 vvv 各一份,另加 iteration 与 learning_rate)。

Q8. 同一网络,SGD 与 Adam 的 Optimizer params 分别是多少?

SGD:2;Adam:203,542。(以本案例 PPP 与当前 Keras 计数方式为准。)

Q9. Dense(128) 的 128 能改吗?和优化器有关吗?

128 是隐藏层宽度,可改,会影响 PPP,从而影响所有 k⋅Pk\cdot Pk⋅P 的优化器状态规模;与「选哪种优化器」是两件独立的事。

开放题

Q10. 线上要微调大模型且显存紧张,如何从优化器角度省资源?

可选 SGD/SGDM、减小状态精度、使用融合/分页优化器、梯度检查点等;并说明与吞吐、收敛的权衡。


7. 总结

  1. 优化器 = 训练时的「下山策略」:在梯度指引下更新权重。
  2. 进化主线:SGD → SGDM(加动量)→ Adagrad/RMSProp(自适应步长)→ Adam(两者结合)。
  3. 状态份数决定成本 :Optimizer params ≈kP+2\approx kP+2≈kP+2,SGD 的 k=0k=0k=0,SGDM/Adagrad/RMSProp 的 k=1k=1k=1,Adam 的 k=2k=2k=2。
  4. MNIST 案例锚点 :P=101,770P=101{,}770P=101,770;Adam 下 Optimizer=203,542,Total=305,312。
  5. 选型口诀 :先求稳用 Adam;要极致泛化打磨 SGDM;要省显存看 kkk。
  6. 分清两本账:Trainable 是模型本体;Optimizer 是训练时的工作记忆。

8. 课后作业

作业 A:概念巩固(书面)

  1. 用自己的话解释:梯度、学习率、优化器三者关系(不超过 200 字)。
  2. 画出五种优化器的「进化关系图」,并在每种旁边标注 k=0/1/2k=0/1/2k=0/1/2。
  3. 证明(算术):当 P=101,770P=101{,}770P=101,770 时,Adam 的 Optimizer params 为何是 203,542。

作业 B:动手实验(代码)

基于 class3/p14_mnist_sequential.py(或等价 MNIST 网络):

  1. 固定网络与 epochsbatch_size,分别使用:
    SGDSGD(momentum=0.9)AdagradRMSpropAdam
  2. 记录每次的:
    • Trainable params
    • Optimizer params
    • Total params
    • 最终 val_sparse_categorical_accuracy
  3. 写成一张对比表,并回答:
    • 哪种 Optimizer params 最大?为什么?
    • 准确率最高的是否一定是 Adam?若不是,可能原因是什么?

作业 C:思考拓展

  1. 若把隐藏层从 128 改为 256,PPP 变成多少?Adam 的 Optimizer params 大约变成多少?
  2. 推理服务保存模型时,需要保存 Adam 的 m,vm,vm,v 吗?什么场景下需要?
  3. (选做)查阅 AdamW 与 Adam 的差别,用三句话说明它在微调中的价值。

提交建议

  • 作业 A:Markdown / 笔记;
  • 作业 B:代码 + 结果表 + 不少于 5 行的结论;
  • 作业 C:简答即可。

附录:速查卡片

text 复制代码
更新通式:  w ← w - η · (某种对 g 的加工)

SGD:      直接用 g                         状态 k=0
SGDM:     用动量平滑 g                      状态 k=1
Adagrad:  用累计 g² 缩小步长                状态 k=1
RMSProp:  用滑动平均 g² 缩小步长            状态 k=1
Adam:     动量 + 滑动平均 g²                状态 k=2

本课锚点: P=101,770
Adam:     Optimizer = 2P+2 = 203,542
Total:    P + Optimizer = 305,312

课件完 · 建议结合 p14_mnist_sequential.py 现场改优化器演示一节课

相关推荐
糖果店的幽灵1 小时前
2026 年最强Obsidian保姆级教程,10分钟打造你的第二大脑
人工智能·langgraph
巫山老妖1 小时前
AI驱动的Flutter工程:如何让AI生成代码不跑偏
人工智能
深度学习lover2 小时前
<数据集>yolo 小麦麦穗识别<目标检测>
人工智能·yolo·目标检测·计算机视觉·数据集·小麦麦穗识别
火山引擎开发者社区2 小时前
让每台终端都成为智能入口:ArkClaw × 云沙箱的规模化实战
人工智能
阳光是sunny2 小时前
LangGraph实战教程:一文搞懂图的状态(State)管理
前端·人工智能·后端
数智化管理手记2 小时前
财务大数据怎么管住资金风险?财务大数据和财务数智化到底怎么结合?
大数据·网络·数据库·人工智能·数据挖掘
AI导出鸭2 小时前
如何让deepseek生成word文档 ?「AI 导出鸭」苹果版:从API流式解析到Pages级渲染,硬核攻克公式裂变与表格回流的终极方案。
人工智能·chatgpt·word·cocoa·ai导出鸭
涛声依旧god2 小时前
如何打造一个 AI Agent 自动写作并一键发布技术文章的自动化系统
人工智能·ai·自动化·ai编程
AI_AGENT_DEV_AI2 小时前
AI 自动化阅卷系统的开发
人工智能