深入解析 SGD(随机梯度下降) 优化器
tensorflow.keras.optimizers.SGD是随机梯度下降(Stochastic Gradient Descent, SGD)优化器在 TensorFlow/Keras 中的实现。它是深度学习中最基础、最经典的优化算法之一,尽管简单,但在许多场景下依然有效,尤其在配合动量(Momentum)或学习率调度时表现优异。
下面从作用、用法、数学原理三个方面进行详细介绍:
一、作用(What it does)
SGD 的核心目标是:通过迭代更新模型参数,最小化损失函数。
- “随机”指每次更新使用一个小批量(mini-batch)数据计算梯度,而非全量数据(即“批量梯度下降”),从而大幅加速训练并引入噪声,有助于跳出局部极小值。
- 基础 SGD 仅使用当前梯度方向更新参数;但 Keras 的
SGD支持动量(Momentum)、Nesterov 动量等增强机制,显著提升收敛速度和稳定性。
适用场景:
- 图像分类(如 ResNet 训练常用带 Momentum 的 SGD);
- 需要强泛化能力的任务(有研究表明 SGD 泛化性优于 Adam);
- 微调大型预训练模型(如 ViT、BERT 微调阶段)。
二、用法(How to use in TensorFlow/Keras)
1. 基础用法(无动量)
importtensorflowastf model=tf.keras.Sequential([...])model.compile(optimizer='sgd',# 使用默认 SGD(learning_rate=0.01)loss='categorical_crossentropy',metrics=['accuracy'])2. 自定义参数(推荐显式声明)
optimizer=tf.keras.optimizers.SGD(learning_rate=0.01,# 学习率(关键超参)momentum=0.9,# 动量系数(0 表示关闭)nesterov=False,# 是否使用 Nesterov 动量name='SGD')model.compile(optimizer=optimizer,...)3. 结合学习率调度(最佳实践)
# 学习率衰减:每 10 个 epoch 衰减为原来的 0.9lr_schedule=tf.keras.optimizers.schedules.ExponentialDecay(initial_learning_rate=0.1,decay_steps=1000,decay_rate=0.9)optimizer=tf.keras.optimizers.SGD(learning_rate=lr_schedule,momentum=0.9,nesterov=True# 常用于 ResNet 等架构)经验建议:
- 图像任务常用
lr=0.1+momentum=0.9+nesterov=True;- 若训练不稳定,可降低学习率(如 0.01 或 0.001)。
三、数学原理(How it works)
1. 基础 SGD(无动量)
设第 $ t $ 步的参数为 $ \theta_t $,损失函数对 $ \theta $ 的梯度为 $ g_t = \nabla_\theta J(\theta_t) $,则更新规则为:
θt+1=θt−η⋅gt \theta_{t+1} = \theta_t - \eta \cdot g_tθt+1=θt−η⋅gt
其中 $ \eta $ 是学习率。
缺点:易震荡、收敛慢、易陷入局部极小值。
2. 带动量的 SGD(Momentum)
引入速度项$ v_t $,累积历史梯度信息,平滑更新路径:
vt=γvt−1+ηgtθt+1=θt−vt v_t = \gamma v_{t-1} + \eta g_t \\ \theta_{t+1} = \theta_t - v_tvt=γvt−1+ηgtθt+1=θt−vt
其中:
- $ \gamma $ 是动量系数(通常 0.9);
- $ v_0 = 0 $。
效果:加速收敛、减少震荡、帮助越过局部极小值。
3. Nesterov 动量(Nesterov Accelerated Gradient, NAG)
Nesterov 动量是对标准动量的改进:先根据动量“向前看一步”,再计算该位置的梯度。
更新公式(Keras 实现方式):
vt=γvt−1+η⋅∇θJ(θt−γvt−1)θt+1=θt−vt v_t = \gamma v_{t-1} + \eta \cdot \nabla_\theta J\left( \theta_t - \gamma v_{t-1} \right) \\ \theta_{t+1} = \theta_t - v_tvt=γvt−1+η⋅∇θJ(θt−γvt−1)θt+1=θt−vt
优势:更“前瞻”,能提前减速避免冲过头,理论收敛更快。
在 Keras 中,只需设置
nesterov=True即启用。
四、关键参数详解
| 参数 | 默认值 | 说明 |
|---|---|---|
learning_rate(η\etaη) | 0.01 | 控制步长,最重要超参 |
momentum(γ\gammaγ) | 0.0 | 动量系数,[0,1),常用 0.9 |
nesterov | False | 是否使用 Nesterov 动量 |
name | ‘SGD’ | 优化器名称(调试用) |
五、SGD vs Adam:如何选择?
| 特性 | SGD(带动量) | Adam |
|---|---|---|
| 收敛速度 | 较慢(需 warmup 或者调 lr) | 快 |
| 泛化能力 | 通常更好(尤其在 CV 任务) | 有时泛化稍差 |
| 超参敏感度 | 对 lr 敏感 | 对 lr 不敏感 |
| 内存占用 | 低(仅存动量) | 较高(存一阶+二阶矩) |
| 默认选择 | 图像分类微调 | NLP、快速原型 |
经验法则:
- 训练 CNN(如 ResNet、EfficientNet)→SGD + Momentum + LR Decay
- 训练 Transformer / 快速实验 →Adam
六、注意事项
- 学习率至关重要:SGD 对学习率非常敏感,建议配合
ReduceLROnPlateau或CosineDecay。 - Batch Size 影响有效学习率:大 batch 时可能需要增大学习率(如 linear scaling rule)。
- 不要忽略 warmup:在 large batch 或 fine-tuning 时,前几个 epoch 用小 lr warmup 可提升稳定性。
- Nesterov 并非总是更好:某些任务中标准 Momentum 更稳定。
总结
SGD 是深度学习的“基石优化器”。
虽然简单,但配合动量、Nesterov、学习率调度后,仍是计算机视觉等领域的黄金标准。
在 TensorFlow/Keras 中,tf.keras.optimizers.SGD提供了灵活且高效的实现,既可用于教学理解优化原理,也可用于工业级模型训练。掌握它,是深入理解深度学习训练过程的关键一步。
