深度学习主流优化器:原理、公式推导与PyTorch实战,附赠论文代码!
在深度学习中,优化器的核心作用是通过调整模型参数(如权重和偏置),最小化损失函数,从而使模型逐步学习到数据中的规律。不同优化器通过不同的参数更新策略,在收敛速度、稳定性、泛化能力等方面表现出差异。本文将详细拆解主流优化器的原理、公式推导,并提供基于PyTorch的可运行完整代码。相关论文及代码可以自取
一、优化器核心背景:参数更新的本质
所有优化器的本质都是迭代更新模型参数,其通用框架为:
对于模型参数 θ \theta θ(如权重矩阵 W W W、偏置 b b b),每次迭代时根据损失函数的梯度 ∇ L ( θ ) \nabla L(\theta) ∇L(θ)(损失对参数的偏导数)和优化器特定的更新规则,调整参数:
θ t + 1 = θ t − η ⋅ UpdateRule ( ∇ L ( θ t ) , 历史信息 ) \theta_{t+1} = \theta_t - \eta \cdot \text{UpdateRule}(\nabla L(\theta_t), \text{历史信息}) θt+1=θt−η⋅UpdateRule(∇L(θt),历史信息)
其中:
- t t t:迭代步数(epoch或step);
- η \eta η:学习率(Learning Rate),控制每次参数更新的幅度,是优化器的关键超参数;
- UpdateRule \text{UpdateRule} UpdateRule:优化器的核心策略,决定是否利用历史梯度、动量等信息。
二、主流优化器详解(原理+公式+代码)
1. 随机梯度下降(SGD):最基础的优化器
SGD是所有优化器的“基石”,直接使用当前批次的梯度更新参数,无额外复杂策略。
1.1 原理
- 全批量梯度下降(GD):使用全部训练数据计算梯度,梯度准确但计算量大(适用于小数据集);
- 随机梯度下降(SGD):使用单个样本计算梯度,计算快但梯度波动大(易震荡);
- 小批量SGD(Mini-batch SGD):使用一小批样本(如32、64、128)计算梯度,平衡计算效率和梯度稳定性(实际训练中最常用,下文简称“SGD”)。
1.2 核心公式
参数更新规则仅依赖当前批次的梯度 ∇ L ( θ t ) \nabla L(\theta_t) ∇L(θt):
θ t + 1 = θ t − η ⋅ ∇ L ( θ t ) \theta_{t+1} = \theta_t - \eta \cdot \nabla L(\theta_t) θt+1=θt−η⋅∇L(θt)
1.3 优缺点
- 优点:实现简单、内存占用低、泛化能力较强(震荡可能跳出局部最优);
- 缺点:收敛速度慢(梯度方向波动大)、学习率难以选择(固定学习率可能导致后期不收敛或更新幅度过小)。
1.4 可运行代码(PyTorch)
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# 1. 构造模拟数据(输入维度10,输出维度2,样本数1000)
X = torch.randn(1000, 10) # 输入特征
y = torch.randint(0, 2, (1000,)) # 标签(二分类)
dataset = TensorDataset(X, y)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True) # 小批量加载
# 2. 定义简单模型(全连接网络)
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(10, 20) # 输入层→隐藏层
self.fc2 = nn.Linear(20, 2) # 隐藏层→输出层
def forward(self, x):
x = torch.relu(self.fc1(x)) # ReLU激活函数
x = self.fc2(x)
return x
model = SimpleModel()
# 3. 定义损失函数和优化器(SGD)
criterion = nn.CrossEntropyLoss() # 交叉熵损失(适用于分类)
optimizer = optim.SGD(model.parameters(), lr=0.01) # 学习率η=0.01
# 4. 模型训练(迭代10个epoch)
num_epochs = 10
for epoch in range(num_epochs):
model.train() # 训练模式
total_loss = 0.0
for batch_X, batch_y in dataloader:
# 前向传播:计算模型输出
outputs = model(batch_X)
# 计算损失
loss = criterion(outputs, batch_y)
# 反向传播:计算梯度
optimizer.zero_grad() # 清空上一轮梯度(避免累积)
loss.backward() # 计算损失对参数的梯度
# 参数更新:执行SGD更新
optimizer.step()
# 累加损失
total_loss += loss.item() * batch_X.size(0)
# 计算每个epoch的平均损失
avg_loss = total_loss / len(dataset)
print(f"Epoch [{epoch+1}/{num_epochs}], Avg Loss: {avg_loss:.4f}")
2. 动量梯度下降(Momentum):解决SGD震荡问题
Momentum借鉴物理中的“动量”概念,通过累积历史梯度的指数移动平均(EMA) 来平滑梯度方向,减少震荡,加速收敛。
2.1 原理
- 引入“动量项” v t v_t vt(velocity,速度),表示历史梯度的累积趋势;
- 动量项通过衰减系数 γ \gamma γ(通常取0.9)控制历史信息的权重,当前梯度仅占小部分;
- 最终参数更新方向由动量项决定,而非单一当前梯度,从而减少方向波动。
2.2 核心公式
- 计算当前动量项(累积历史梯度):
v t = γ ⋅ v t − 1 + η ⋅ ∇ L ( θ t ) v_t = \gamma \cdot v_{t-1} + \eta \cdot \nabla L(\theta_t) vt=γ⋅vt−1+η⋅∇L(θt) - 更新参数(沿动量项方向移动):
θ t + 1 = θ t − v t \theta_{t+1} = \theta_t - v_t θt+1=θt−vt
其中:
- v t − 1 v_{t-1} vt−1:上一步的动量项(初始为0);
- γ \gamma γ:动量衰减系数(典型值0.9,控制历史梯度的影响程度)。
2.3 优缺点
- 优点:减少SGD的震荡,加速收敛(尤其在损失函数的“狭长峡谷”区域);
- 缺点:动量项可能导致“过冲”(即参数越过最优值),且学习率仍需手动调整。
2.4 可运行代码(PyTorch)
仅需修改优化器定义部分,其余代码与SGD一致:
# 定义Momentum优化器(γ=0.9为默认值,可显式指定)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 后续训练代码与SGD完全相同(略)
3. 自适应梯度(Adagrad):动态调整学习率
Adagrad针对不同参数单独调整学习率:频繁更新的参数(如高频特征的权重)使用较小的学习率,稀疏更新的参数(如低频特征的权重)使用较大的学习率,适用于稀疏数据(如NLP、推荐系统)。
3.1 原理
- 引入“梯度累积平方项” G t G_t Gt,记录每个参数从训练开始到当前的梯度平方和;
- 学习率通过 1 / G t + ϵ 1/\sqrt{G_t + \epsilon} 1/Gt+ϵ 动态调整( ϵ \epsilon ϵ 为极小值,避免分母为0);
- 核心逻辑:参数的梯度越大(更新越频繁),学习率衰减越快。
3.2 核心公式
- 累积当前参数的梯度平方(按元素平方和累积):
G t = G t − 1 + ∇ L ( θ t ) ⊙ ∇ L ( θ t ) G_t = G_{t-1} + \nabla L(\theta_t) \odot \nabla L(\theta_t) Gt=Gt−1+∇L(θt)⊙∇L(θt)
( ⊙ \odot ⊙ 表示按元素乘法) - 动态调整学习率并更新参数:
θ t + 1 = θ t − η G t + ϵ ⋅ ∇ L ( θ t ) \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \cdot \nabla L(\theta_t) θt+1=θt−Gt+ϵη⋅∇L(θt)
其中:
- G t − 1 G_{t-1} Gt−1:上一步的梯度平方累积项(初始为0);
- ϵ \epsilon ϵ:数值稳定性项(典型值 1 0 − 8 10^{-8} 10−8,避免分母为0或过小);
- η \eta η:全局学习率(Adagrad中通常取0.01,无需手动微调)。
3.3 优缺点
- 优点:无需手动调整学习率,对稀疏数据友好;
- 缺点:梯度平方项 G t G_t Gt 持续累积,导致学习率逐渐趋近于0,训练后期可能停止收敛。
3.4 可运行代码(PyTorch)
# 定义Adagrad优化器(η=0.01为默认值,ε=1e-10为默认值)
optimizer = optim.Adagrad(model.parameters(), lr=0.01, eps=1e-10)
# 后续训练代码与SGD完全相同(略)
4. 自适应动量估计(Adam):当前最常用的优化器
Adam(Adaptive Moment Estimation)结合了Momentum的动量项和Adagrad的自适应学习率,同时解决了SGD震荡、Adagrad学习率衰减过快的问题,在图像、NLP等多数任务中表现最优,是当前默认选择。
4.1 原理
- 维护两个状态变量:
- 一阶矩(动量项) m t m_t mt:梯度的指数移动平均(类似Momentum,平滑梯度方向);
- 二阶矩(梯度平方项) v t v_t vt:梯度平方的指数移动平均(类似Adagrad,动态调整学习率);
- 对两个矩进行偏差修正(初始阶段矩的估计偏差较大,修正后更准确)。
4.2 核心公式
- 计算一阶矩(动量项,衰减系数 β 1 \beta_1 β1 通常取0.9):
m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ ∇ L ( θ t ) m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot \nabla L(\theta_t) mt=β1⋅mt−1+(1−β1)⋅∇L(θt) - 计算二阶矩(梯度平方项,衰减系数 β 2 \beta_2 β2 通常取0.999):
v t = β 2 ⋅ v t − 1 + ( 1 − β 2 ) ⋅ ∇ L ( θ t ) ⊙ ∇ L ( θ t ) v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot \nabla L(\theta_t) \odot \nabla L(\theta_t) vt=β2⋅vt−1+(1−β2)⋅∇L(θt)⊙∇L(θt) - 偏差修正(解决初始阶段矩估计偏小的问题):
m ^ t = m t 1 − β 1 t \hat{m}_t = \frac{m_t}{1 - \beta_1^t} m^t=1−β1tmt
v ^ t = v t 1 − β 2 t \hat{v}_t = \frac{v_t}{1 - \beta_2^t} v^t=1−β2tvt - 自适应更新参数:
θ t + 1 = θ t − η v ^ t + ϵ ⋅ m ^ t \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \cdot \hat{m}_t θt+1=θt−v^t+ϵη⋅m^t
其中:
- β 1 , β 2 \beta_1, \beta_2 β1,β2:矩的衰减系数(默认0.9、0.999,几乎无需调整);
- ϵ \epsilon ϵ:数值稳定性项(默认 1 0 − 8 10^{-8} 10−8);
- η \eta η:全局学习率(默认0.001,多数任务无需微调)。
4.3 优缺点
- 优点:收敛速度快、稳定性强、无需手动调整大量超参数、适用场景广(图像分类、目标检测、NLP等);
- 缺点:在极少数极端任务(如生成模型的某些场景)中,可能不如专门优化的优化器(如AdamW),但通用性最优。
4.4 可运行代码(PyTorch)
# 定义Adam优化器(默认参数:lr=0.001, betas=(0.9, 0.999), eps=1e-08)
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 后续训练代码与SGD完全相同(略)
5. AdamW:Adam的改进版(解决权重衰减问题)
AdamW是Adam的优化版,核心改进是将“权重衰减(Weight Decay)”与梯度更新解耦,避免Adam原有的权重衰减效果被自适应学习率削弱,在需要正则化的任务(如深度学习分类、回归)中表现更优。
5.1 原理
- Adam原有的权重衰减是“在梯度更新后叠加衰减”,而AdamW是“先对权重进行衰减,再执行梯度更新”;
- 权重衰减本质是L2正则化,用于防止模型过拟合,AdamW确保衰减效果不依赖于梯度大小,更稳定。
5.2 核心公式
在Adam的参数更新前,先对参数进行衰减:
- 权重衰减( λ \lambda λ 为权重衰减系数,典型值 1 0 − 4 10^{-4} 10−4):
θ t decay = θ t ⋅ ( 1 − η ⋅ λ ) \theta_t^{\text{decay}} = \theta_t \cdot (1 - \eta \cdot \lambda) θtdecay=θt⋅(1−η⋅λ) - 后续步骤与Adam完全一致(使用 θ t decay \theta_t^{\text{decay}} θtdecay 替代原 θ t \theta_t θt 进行梯度更新):
θ t + 1 = θ t decay − η v ^ t + ϵ ⋅ m ^ t \theta_{t+1} = \theta_t^{\text{decay}} - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \cdot \hat{m}_t θt+1=θtdecay−v^t+ϵη⋅m^t
5.3 优缺点
- 优点:继承Adam的所有优点,同时增强权重衰减的正则化效果,有效缓解过拟合;
- 缺点:需额外调整权重衰减系数 λ \lambda λ(但通常取 1 0 − 4 10^{-4} 10−4 即可)。
5.4 可运行代码(PyTorch)
# 定义AdamW优化器(权重衰减系数weight_decay=1e-4为常用值)
optimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=1e-4)
# 后续训练代码与SGD完全相同(略)
三、优化器选择与超参数调优建议
| 优化器 | 适用场景 | 核心超参数 | 优点 | 缺点 |
|---|---|---|---|---|
| SGD | 小数据集、需强泛化能力 | lr(0.001-0.1) | 简单、泛化好 | 收敛慢、震荡 |
| Momentum | 需加速SGD收敛的场景 | lr、momentum(0.9) | 减少震荡、收敛快 | 可能过冲 |
| Adagrad | 稀疏数据(NLP、推荐) | lr(0.01) | 自适应学习率、无需微调 | 后期学习率趋近0 |
| Adam | 多数通用场景(默认选择) | lr(0.001) | 收敛快、稳定、通用性强 | 极端场景正则化弱 |
| AdamW | 需强正则化的场景(防过拟合) | lr、weight_decay(1e-4) | 继承Adam优点,增强正则化 | 需调整权重衰减系数 |
调优建议
- 优先选择AdamW:在图像、NLP等多数任务中,AdamW的综合表现最优,默认参数(lr=0.001,weight_decay=1e-4)可覆盖80%以上场景;
- 学习率调整:若训练发散(损失爆炸),可降低学习率(如0.0001);若收敛慢,可适当提高(如0.005);
- 批量大小匹配:批量大小(batch_size)增大时,可适当提高学习率(如batch_size从32→64,lr从0.001→0.002);
- 后期微调:若模型过拟合,可增大weight_decay(如1e-3);若欠拟合,可减小(如1e-5)。
四、完整对比实验代码
以下代码对比SGD、Momentum、Adagrad、Adam、AdamW在同一任务上的收敛效果:
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import matplotlib.pyplot as plt
import numpy as np
from tqdm import tqdm # 用于显示进度条
# 设置随机种子以确保实验可重复性
torch.manual_seed(42)
np.random.seed(42)
# 1. 生成复杂的训练数据
def create_training_data(samples=5000, features=30, classes=2):
"""创建具有非线性关系的复杂数据集,使优化器差异更明显"""
# 生成基础特征
X = torch.randn(samples, features)
# 添加非线性特征交互
X[:, :5] = torch.sin(X[:, :5] * 3.14) # 正弦函数非线性
X[:, 5:10] = torch.exp(X[:, 5:10] * 0.3) # 指数函数非线性
X[:, 10:15] = X[:, 10:15] ** 3 # 立方非线性
X[:, 15:20] = torch.tanh(X[:, 15:20] * 2) # tanh非线性
X[:, 20:25] = X[:, 20:25] * torch.exp(X[:, 25:30]) # 特征交互
# 生成标签(通过一个隐藏的决策边界)
weights = torch.randn(features, classes)
biases = torch.randn(classes)
logits = X @ weights + biases + torch.randn(samples, classes) * 0.5 # 添加噪声
y = torch.argmax(logits, dim=1)
return X, y
# 生成训练和验证数据
X_train, y_train = create_training_data(samples=5000)
X_val, y_val = create_training_data(samples=1000)
# 创建数据加载器
train_dataset = TensorDataset(X_train, y_train)
val_dataset = TensorDataset(X_val, y_val)
train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=128, shuffle=False)
# 2. 定义统一的神经网络模型
class ComparisonModel(nn.Module):
def __init__(self, input_dim=30, hidden_dim=128, output_dim=2):
super(ComparisonModel, self).__init__()
self.network = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.BatchNorm1d(hidden_dim),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(hidden_dim, hidden_dim//2),
nn.BatchNorm1d(hidden_dim//2),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(hidden_dim//2, hidden_dim//4),
nn.BatchNorm1d(hidden_dim//4),
nn.ReLU(),
nn.Linear(hidden_dim//4, output_dim)
)
def forward(self, x):
return self.network(x)
# 3. 定义评估函数
def evaluate(model, dataloader, criterion):
"""在指定数据集上评估模型性能"""
model.eval()
total_loss = 0.0
correct = 0
total = 0
with torch.no_grad(): # 关闭梯度计算,节省内存和计算资源
for inputs, labels in dataloader:
outputs = model(inputs)
loss = criterion(outputs, labels)
total_loss += loss.item() * inputs.size(0)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
avg_loss = total_loss / total
accuracy = correct / total * 100
return avg_loss, accuracy
# 4. 定义训练函数
def train_optimizer(optimizer_name, optimizer, epochs=50):
"""使用指定优化器训练模型并记录训练过程"""
# 为每个优化器创建独立模型,确保公平比较
model = ComparisonModel()
criterion = nn.CrossEntropyLoss()
# 记录训练过程的指标
history = {
'train_loss': [], 'train_acc': [],
'val_loss': [], 'val_acc': []
}
# 进度条
progress_bar = tqdm(range(epochs), desc=f"训练 {optimizer_name}")
for epoch in progress_bar:
# 训练阶段
model.train()
train_running_loss = 0.0
train_correct = 0
train_total = 0
for inputs, labels in train_loader:
# 前向传播
outputs = model(inputs)
loss = criterion(outputs, labels)
# 反向传播和优化
optimizer.zero_grad() # 清零梯度
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新参数
# 记录训练指标
train_running_loss += loss.item() * inputs.size(0)
_, predicted = torch.max(outputs.data, 1)
train_total += labels.size(0)
train_correct += (predicted == labels).sum().item()
# 计算训练集指标
train_avg_loss = train_running_loss / train_total
train_accuracy = train_correct / train_total * 100
# 在验证集上评估
val_avg_loss, val_accuracy = evaluate(model, val_loader, criterion)
# 保存指标
history['train_loss'].append(train_avg_loss)
history['train_acc'].append(train_accuracy)
history['val_loss'].append(val_avg_loss)
history['val_acc'].append(val_accuracy)
# 更新进度条
progress_bar.set_postfix({
'Train Loss': f'{train_avg_loss:.4f}',
'Val Acc': f'{val_accuracy:.2f}%'
})
return history
# 5. 定义要比较的优化器
def get_optimizers():
"""创建所有要比较的优化器实例"""
base_model = ComparisonModel()
optimizers = {
# SGD优化器
'SGD': optim.SGD(
base_model.parameters(),
lr=0.01, # 学习率
weight_decay=1e-4 # 权重衰减(L2正则化)
),
# 带动量的SGD
'Momentum': optim.SGD(
base_model.parameters(),
lr=0.01,
momentum=0.9, # 动量系数
weight_decay=1e-4
),
# Adagrad优化器
'Adagrad': optim.Adagrad(
base_model.parameters(),
lr=0.01,
weight_decay=1e-4,
eps=1e-8 # 数值稳定性参数
),
# Adam优化器
'Adam': optim.Adam(
base_model.parameters(),
lr=0.001, # Adam通常使用较小的学习率
betas=(0.9, 0.999),# 动量参数
weight_decay=1e-4,
eps=1e-8
),
# AdamW优化器
'AdamW': optim.AdamW(
base_model.parameters(),
lr=0.001,
betas=(0.9, 0.999),
weight_decay=1e-4, # AdamW中该参数效果更明显
eps=1e-8
)
}
return optimizers
# 6. 运行对比实验
if __name__ == "__main__":
# 获取所有优化器
optimizers = get_optimizers()
# 训练所有优化器并记录结果
results = {}
num_epochs = 50
print(f"开始优化器对比实验,共训练 {num_epochs} 个 epoch...\n")
for name, optimizer in optimizers.items():
results[name] = train_optimizer(name, optimizer, num_epochs)
# 7. 可视化实验结果
plt.figure(figsize=(16, 12))
# 绘制训练损失曲线
plt.subplot(2, 2, 1)
for name, history in results.items():
plt.plot(range(1, num_epochs+1), history['train_loss'], label=name, linewidth=2)
plt.title('训练损失对比', fontsize=14)
plt.xlabel('Epoch', fontsize=12)
plt.ylabel('损失值', fontsize=12)
plt.grid(alpha=0.3)
plt.legend()
# 绘制验证损失曲线
plt.subplot(2, 2, 2)
for name, history in results.items():
plt.plot(range(1, num_epochs+1), history['val_loss'], label=name, linewidth=2)
plt.title('验证损失对比', fontsize=14)
plt.xlabel('Epoch', fontsize=12)
plt.ylabel('损失值', fontsize=12)
plt.grid(alpha=0.3)
plt.legend()
# 绘制训练准确率曲线
plt.subplot(2, 2, 3)
for name, history in results.items():
plt.plot(range(1, num_epochs+1), history['train_acc'], label=name, linewidth=2)
plt.title('训练准确率对比', fontsize=14)
plt.xlabel('Epoch', fontsize=12)
plt.ylabel('准确率 (%)', fontsize=12)
plt.grid(alpha=0.3)
plt.legend()
# 绘制验证准确率曲线
plt.subplot(2, 2, 4)
for name, history in results.items():
plt.plot(range(1, num_epochs+1), history['val_acc'], label=name, linewidth=2)
plt.title('验证准确率对比', fontsize=14)
plt.xlabel('Epoch', fontsize=12)
plt.ylabel('准确率 (%)', fontsize=12)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.savefig('optimizer_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
# 8. 输出最终结果统计
print("\n" + "="*60)
print(f"{'优化器':<10} | {'最终训练损失':<15} | {'最终验证损失':<15} | {'最终验证准确率':<15}")
print("-"*60)
for name, history in results.items():
final_train_loss = history['train_loss'][-1]
final_val_loss = history['val_loss'][-1]
final_val_acc = history['val_acc'][-1]
print(f"{name:<10} | {final_train_loss:.6f} | {final_val_loss:.6f} | {final_val_acc:.2f}%")
print("="*60)
这个对比实验代码包含以下关键部分:
-
数据生成模块:创建了具有多种非线性关系的复杂数据集,包括正弦函数、指数函数、立方函数等变换,使优化器的性能差异更加明显。
-
模型定义:使用包含批归一化和dropout层的神经网络,增加模型复杂度,同时防止过拟合,使优化过程更具挑战性。
-
完整训练流程:
- 分离训练集和验证集,全面评估模型性能
- 记录训练损失、训练准确率、验证损失和验证准确率四个关键指标
- 使用进度条可视化训练过程

-
五种优化器对比:
- SGD:基础随机梯度下降
- Momentum:带动量的SGD
- Adagrad:自适应学习率优化器
- Adam:结合动量和自适应学习率
- AdamW:Adam的改进版,优化权重衰减
-
结果可视化:通过四个子图分别展示训练损失、验证损失、训练准确率和验证准确率的对比曲线,并保存图像。

-
结果统计:以表格形式输出各优化器的最终性能指标(简单的demo)效果可能不好,便于定量比较。

预期实验结论
运行此代码后,您将观察到:
- 收敛速度:Adam和AdamW通常最快达到稳定状态,其次是Momentum,然后是Adagrad,SGD最慢。
- 最终性能:AdamW通常能获得最高的验证准确率,且过拟合现象最轻;Adam紧随其后;Momentum和SGD需要更多迭代才能接近前两者的性能;Adagrad可能在后期收敛停滞。
- 稳定性:Adam和AdamW的损失和准确率曲线最平滑,SGD和Momentum波动较大。
这些结果验证了AdamW作为当前深度学习任务中默认优化器的合理性,它在收敛速度、最终性能和稳定性之间取得了最佳平衡。
更多推荐


所有评论(0)