第9课:PyTorch|优化器原理与主流优化器实战调参【模型训练的“引擎控制单元”】

文章目录
📖 课前导读
为什么优化器决定了你的模型能否“成事”?
前面我们学习了损失函数——它告诉模型“你现在错得有多离谱”。但光知道错了还不够,模型需要知道“怎么改”。这就是优化器的工作:它接收损失函数对每个参数的梯度,然后按照某种规则更新参数,使得下一次前向传播的损失变小。
如果把训练一个神经网络比作开一场赛车比赛:
- 损失函数是赛道上的每个弯道——告诉你当前状态的好坏;
- 梯度是方向盘上的力反馈——告诉你怎么打方向能过弯;
- 优化器就是整辆车的发动机控制单元(ECU)——它决定踩多少油门(学习率)、是否用氮气加速(动量)、何时点刹(梯度裁剪)。
不同优化器的差别,就是ECU调校风格的差别。SGD(随机梯度下降)像一位稳健的拉力车手,一步一个脚印;Adam则像一位配备了智能扭矩分配系统的F1车手,能根据路况自动调整每个车轮的动力输出。
💡 关键认知:优化器不是“万能药”,但选错优化器会让模型训练效率降低数倍甚至无法收敛。理解每个优化器的设计初衷和数学直觉,才能为你的任务选出最合适的那个。
学完这一课,你将能够:
- ✅ 理解梯度下降的三种变体(BGD、SGD、Mini-batch GD)的优缺点
- ✅ 掌握动量(Momentum)和Nesterov动量的数学原理及实现
- ✅ 理解自适应学习率优化器(AdaGrad、RMSprop)解决的核心问题
- ✅ 精通Adam/AdamW的参数含义及调优技巧
- ✅ 根据任务特点选择优化器(CV用SGD+动量,NLP/Transformer用AdamW)
- ✅ 设置合适的学习率、权重衰减、梯度裁剪,避免训练崩溃
- ✅ 结合学习率调度器实现动态学习率调整
一、知识原理:优化器的数学基础
1.1 梯度下降的三种形式
深度学习中所有的优化器都基于一个共同的目标:最小化损失函数 L(θ)。基本思想是沿着梯度的反方向更新参数:θ_new = θ_old - η * ∇L(θ)。
但根据每次更新使用的数据量,梯度下降分为三种:
| 类型 | 数据量 | 更新频率 | 优点 | 缺点 |
|---|---|---|---|---|
| BGD(批量梯度下降) | 全部训练集 | 每个epoch一次 | 梯度精确,收敛稳定 | 内存占用大,无法在线学习 |
| SGD(随机梯度下降) | 单个样本 | 每个样本一次 | 更新快,可在线学习 | 梯度噪声大,收敛震荡 |
| Mini-batch GD | 小批量(如32/64/128) | 每个batch一次 | 平衡效率和稳定性 | 需要选择batch size |
现代深度学习几乎全部使用Mini-batch SGD及其各种变体。PyTorch中的torch.optim.SGD实际上就是mini-batch SGD(如果你设置batch_size=1,才是真正的SGD)。
1.2 学习率(Learning Rate)的关键作用
学习率η是优化器中最重要的超参数。它决定了每次参数更新的步长:
- 学习率太大:损失剧烈震荡,可能无法收敛甚至发散(loss变成NaN)
- 学习率太小:收敛极其缓慢,可能陷入局部极小点无法跳出
理想的学习率:初期较大以快速接近最优区域,后期逐渐减小以精细调优。这正是学习率调度器(第10课)要做的事情。
1.3 动量(Momentum):给梯度下降加上“惯性”
SGD的更新方向完全依赖于当前batch的梯度,容易产生震荡(尤其是在狭窄的峡谷区域)。动量方法引入了累积梯度的概念,让参数更新方向结合历史梯度的加权平均,就像一个小球滚下坡时带有惯性。
公式:
v_t = β * v_{t-1} + (1-β) * ∇L(θ_t) # 累积动量
θ_{t+1} = θ_t - η * v_t
其中β通常取0.9。动量能加速收敛,并帮助冲出局部极小点和鞍点。
1.4 自适应学习率优化器的演进
| 优化器 | 核心思想 | 解决什么问题 | 局限性 |
|---|---|---|---|
| SGD | 统一学习率 | 基础 | 所有参数共享学习率,收敛慢 |
| Momentum | 累积历史梯度方向 | 加速收敛、减少震荡 | 仍然使用统一学习率 |
| AdaGrad | 每个参数独立学习率(除以梯度平方和) | 稀疏特征自动调小学习率 | 学习率单调递减,后期可能停止 |
| RMSprop | 使用梯度平方的指数移动平均替代累加和 | 解决AdaGrad学习率消失问题 | 需要手动设置衰减率 |
| Adam | RMSprop + Momentum | 既自适应又带动量,几乎通吃 | 需要调优β1,β2,可能有泛化问题 |
| AdamW | Adam + 解耦的权重衰减 | 修正Adam权重衰减实现 | 当前默认推荐(替代Adam) |
二、环境搭建与准备
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
import torchvision
import torchvision.transforms as transforms
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
print(f"PyTorch版本: {torch.__version__}")
torch.manual_seed(42)
np.random.seed(42)
# 准备一个简单的模型和数据集用于演示
class SimpleNet(nn.Module):
def __init__(self, input_dim=784, hidden_dim=128, output_dim=10):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, output_dim)
self.relu = nn.ReLU()
def forward(self, x):
x = x.view(x.size(0), -1)
x = self.relu(self.fc1(x))
x = self.fc2(x)
return x
# 数据加载
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
三、代码实战:PyTorch优化器详解
3.1 SGD(随机梯度下降)基础版
# 创建模型
model = SimpleNet()
# SGD优化器:所有参数使用相同学习率
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 查看优化器参数
print(f"优化器状态: {optimizer.defaults}") # {'lr': 0.01, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}
# 训练循环中(典型用法)
for epoch in range(1):
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = nn.CrossEntropyLoss()(outputs, labels)
loss.backward()
optimizer.step() # 更新参数:param = param - lr * grad
3.2 SGD with Momentum(带动量的SGD)
动量是SGD的最重要改进,几乎在所有CV任务中都会使用。
model_mom = SimpleNet()
optimizer_mom = optim.SGD(model_mom.parameters(), lr=0.01, momentum=0.9)
# 参数说明:
# - momentum: 动量系数β,通常0.9或0.99
# - dampening: 阻尼系数(默认为0),如果非零,则动量计算公式变为 v = β*v + (1-dampening)*grad
# - nesterov: 是否使用Nesterov加速梯度(NAG),一种动量变体,能提前预测参数位置
# Nesterov动量
optimizer_nesterov = optim.SGD(model_mom.parameters(), lr=0.01, momentum=0.9, nesterov=True)
何时使用:几乎所有CNN图像分类任务。SGD+Momentum通常能获得比Adam更好的泛化性能,但需要更多epoch调优学习率。
3.3 AdaGrad:自适应学习率的开创者
model_adagrad = SimpleNet()
optimizer_adagrad = optim.Adagrad(model_adagrad.parameters(), lr=0.01, lr_decay=0, weight_decay=0)
# 内部机制:对于每个参数i,累积梯度平方和 G_i = Σ g_i^2,学习率调整为 lr / (sqrt(G_i)+eps)
# 稀疏特征(出现频率低)对应的梯度平方和小,学习率相对较大;频繁特征学习率自动变小
缺点:G_i单调递增,学习率会不断下降直到趋近于0,在训练后期模型无法学到新东西。
适用场景:自然语言处理中有大量稀疏特征的任务(如词嵌入),但已被Adam替代。
3.4 RMSprop:解决AdaGrad学习率消亡
model_rms = SimpleNet()
optimizer_rms = optim.RMSprop(model_rms.parameters(), lr=0.01, alpha=0.99, eps=1e-8, weight_decay=0, momentum=0)
# 参数:
# - alpha: 平滑常数,用于计算梯度平方的指数移动平均 (类似 momentum 但针对二阶矩)
# - eps: 防止除零的小常数
# - momentum: 可选的一阶动量(类似SGD的momentum)
RMSprop由Geoff Hinton在课堂上提出,是Adam的前身。它使用指数移动平均代替累加和,避免了学习率单调递减的问题。
3.5 Adam:自适应动量的集大成者
Adam(Adaptive Moment Estimation)是目前最流行的优化器,结合了Momentum(一阶矩)和RMSprop(二阶矩)。
model_adam = SimpleNet()
optimizer_adam = optim.Adam(model_adam.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, amsgrad=False)
# 参数详解:
# - lr: 学习率(默认1e-3),通常比SGD的学习率小一个数量级
# - betas: (β1, β2) 一阶矩和二阶矩的衰减率,默认(0.9, 0.999)
# - eps: 防止除零
# - weight_decay: 权重衰减(L2正则化),注意Adam的实现与SGD略有不同(后面讨论)
# - amsgrad: 是否使用AMSGrad变体(防止学习率震荡)
为什么Adam有效:
- 一阶动量(momentum)提供惯性方向
- 二阶动量(自适应学习率)为每个参数独立调整步长
- 偏差校正(bias correction)解决了初期估计为0的问题
# 查看Adam内部参数(调试用)
print(optimizer_adam.defaults)
# 访问每个参数组的状态
for param_group in optimizer_adam.param_groups:
print(f"学习率: {param_group['lr']}, betas: {param_group['betas']}")
3.6 AdamW:修正Adam的权重衰减
AdamW是Adam + 解耦的权重衰减(Decoupled Weight Decay)。在Adam中,weight_decay参数实际上是在梯度上加了wd * p,这并不等于L2正则化,因为Adam的自适应学习率会破坏正则化效果。AdamW将权重衰减与梯度更新分开,成为目前训练Transformer和大模型的默认选择。
model_adamw = SimpleNet()
optimizer_adamw = optim.AdamW(model_adamw.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.01)
# 使用AdamW时,weight_decay通常取0.01~0.1,而Adam中weight_decay通常为0(或很小)
Adam vs AdamW:如果你在使用预训练模型(如BERT、ViT)的官方代码,几乎肯定用的是AdamW。在分类任务中,AdamW通常略优于Adam。
3.7 其他优化器简介
| 优化器 | PyTorch类 | 特点 | 使用频率 |
|---|---|---|---|
| Adamax | optim.Adamax | 基于无穷范数的Adam变体 | 较少 |
| NAdam | optim.NAdam | Adam + Nesterov动量 | 低 |
| RAdam | optim.RAdam | 整流Adam,提升稳定性 | 中(部分研究) |
| LBFGS | optim.LBFGS | 拟牛顿法,适用于小批量 | 很低(全批量) |
3.8 优化器参数分组
PyTorch允许为模型的不同部分设置不同的优化参数(如不同学习率、不同权重衰减)。这在迁移学习中很常用(微调最后几层,冻结前面的层)。
# 假设有一个预训练模型,我们要微调最后一层
model = SimpleNet()
# 将fc2的参数单独分组
param_groups = [
{'params': model.fc1.parameters(), 'lr': 0.001, 'weight_decay': 0.0001},
{'params': model.fc2.parameters(), 'lr': 0.01, 'weight_decay': 0.001},
]
optimizer = optim.SGD(param_groups, momentum=0.9) # 公共参数作为默认值
# 查看参数组
for i, group in enumerate(optimizer.param_groups):
print(f"Group {i}: lr={group['lr']}, weight_decay={group['weight_decay']}, 参数数量={len(group['params'])}")
3.9 动态调整学习率(优化器层面)
虽然学习率调度器(下一课)是更推荐的方法,但也可以直接修改优化器的学习率。
# 手动调整学习率
for param_group in optimizer.param_groups:
param_group['lr'] *= 0.9 # 每epoch衰减10%
# 获取当前学习率
current_lr = optimizer.param_groups[0]['lr']
3.10 梯度裁剪(Gradient Clipping)
梯度裁剪不是优化器的一部分,但常常与优化器配合使用,防止梯度爆炸(尤其在RNN、Transformer中)。
# 在 loss.backward() 之后,optimizer.step() 之前
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) # 裁剪梯度的L2范数
# 或 clip_grad_value_ 按值裁剪
torch.nn.utils.clip_grad_value_(model.parameters(), clip_value=0.5)
四、优化器对比实验:在MNIST上的性能比较
我们设计一个公平的实验,比较SGD、SGD+Momentum、Adam、AdamW在相同条件下的表现。
def train_model(model, optimizer, criterion, train_loader, epochs=5, device='cpu'):
model.to(device)
model.train()
losses = []
for epoch in range(epochs):
epoch_loss = 0.0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
epoch_loss += loss.item() * inputs.size(0)
epoch_loss /= len(train_loader.dataset)
losses.append(epoch_loss)
return losses
# 设置设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
criterion = nn.CrossEntropyLoss()
epochs = 5
# 不同优化器配置
optimizer_configs = {
'SGD': optim.SGD(SimpleNet().parameters(), lr=0.01),
'SGD+Momentum': optim.SGD(SimpleNet().parameters(), lr=0.01, momentum=0.9),
'Adam': optim.Adam(SimpleNet().parameters(), lr=0.001),
'AdamW': optim.AdamW(SimpleNet().parameters(), lr=0.001, weight_decay=0.01)
}
losses_dict = {}
for name, optimizer in optimizer_configs.items():
model = SimpleNet()
losses = train_model(model, optimizer, criterion, train_loader, epochs, device)
losses_dict[name] = losses
print(f"{name} 最终损失: {losses[-1]:.4f}")
# 绘图对比
plt.figure(figsize=(10,6))
for name, losses in losses_dict.items():
plt.plot(range(1, epochs+1), losses, marker='o', label=name)
plt.xlabel('Epoch')
plt.ylabel('训练损失')
plt.title('不同优化器在MNIST上的收敛速度对比')
plt.legend()
plt.grid(True)
plt.show()
典型结论:
- SGD收敛最慢,最终损失可能也略高。
- SGD+Momentum收敛速度显著提升,最终性能通常最好(泛化)。
- Adam和AdamW收敛最快,但最终损失可能略高于SGD+Momentum(尤其在小数据集上)。
五、优化器调参实战指南
5.1 学习率(lr)的设定
| 优化器 | 常用学习率范围 | 建议起点 |
|---|---|---|
| SGD | 0.1 ~ 0.001 | 0.01 |
| SGD+Momentum | 0.1 ~ 0.001 | 0.01 |
| Adam | 1e-4 ~ 1e-2 | 1e-3 |
| AdamW | 1e-5 ~ 1e-3 (大模型) / 1e-3 (小模型) | 1e-3 (小) / 3e-4 (BERT) |
学习率查找技巧(LR Range Test):以指数增长的方式尝试学习率,绘制损失曲线,找到损失下降最快的区域。
# 简单实现学习率范围测试
def lr_range_test(model, train_loader, criterion, start_lr=1e-7, end_lr=1, num_steps=100):
optimizer = optim.SGD(model.parameters(), lr=start_lr)
lrs = []
losses = []
beta = (end_lr / start_lr) ** (1/(num_steps-1))
for step in range(num_steps):
lr = start_lr * (beta ** step)
for param_group in optimizer.param_groups:
param_group['lr'] = lr
inputs, labels = next(iter(train_loader))
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
lrs.append(lr)
losses.append(loss.item())
return lrs, losses
# 使用示例(会耗时,仅作参考)
# model = SimpleNet().to(device)
# lrs, losses = lr_range_test(model, train_loader, criterion)
# plt.xscale('log')
# plt.plot(lrs, losses)
# plt.xlabel('Learning Rate')
# plt.ylabel('Loss')
# plt.show()
5.2 动量(momentum)的设定
- 常用值:0.9、0.99、0.95
- 较大的动量(如0.99)适合损失平面平坦的场景;0.9是通用设置。
- 在SGD中,当训练初期损失震荡严重时,可稍微降低动量(如0.8)。
5.3 权重衰减(weight_decay)的选择
权重衰减是L2正则化,目的是防止过拟合。不同优化器对weight_decay的解释不同:
| 优化器 | weight_decay含义 | 推荐初始值 |
|---|---|---|
| SGD | L2正则化(损失函数加λ/2 * ‖w‖²) | 1e-4 ~ 1e-3 |
| Adam | 在梯度上加上 λ * w,不是真正的L2 | 通常0(用其他正则化) |
| AdamW | 真正的解耦权重衰减 | 0.01 ~ 0.1(Transformer常用0.01) |
建议:
- CNN图像分类:SGD+Momentum + weight_decay=1e-4
- Transformer:AdamW + weight_decay=0.01 或 0.1
- 小数据集:适当增大weight_decay;大数据集可以更小
5.4 Batch Size对优化器的影响
更大的batch size会降低梯度估计的噪声,但也会减少随机性带来的正则化效果。经验法则:
- 增加batch size时,学习率也应线性增加(例如batch size翻倍,lr翻倍)
- 同时可能需要增加momentum或调整weight_decay
5.5 优化器选择决策树
是Transformer/BERT类模型吗?
├── 是 → AdamW(lr=3e-5~1e-4, weight_decay=0.01)+ 线性warmup
└── 否 → 是图像分类(CNN)吗?
├── 是 → SGD+Momentum(lr=0.01~0.1, momentum=0.9, weight_decay=1e-4)+ 余弦退火
└── 否 → 小数据集/快速原型 → Adam(lr=1e-3)或 AdamW
六、难点解析:常见问题与陷阱
6.1 损失不下降或下降极慢
可能原因:
- 学习率过小 → 增大学习率
- 梯度消失 → 检查激活函数和网络初始化
- 优化器不适合 → 尝试Adam或SGD+Momentum
6.2 损失震荡剧烈
可能原因:
- 学习率过大 → 降低学习率(如从0.1降到0.01)
- batch size过小 → 增大batch size
- 动量太大 → 减小momentum
6.3 损失变为NaN
可能原因:
- 梯度爆炸 → 梯度裁剪(clip_grad_norm_)
- 学习率过大 → 降低学习率
- 数据包含NaN或inf → 检查数据预处理
- 对数运算中出现log(0) → 使用带eps的损失函数(如CrossEntropyLoss内部已处理)
6.4 Adam和AdamW的权重衰减困惑
很多用户不知道Adam和AdamW的区别。简单说:如果你使用Adam,通常weight_decay=0;如果你使用AdamW,weight_decay非零(0.01是很好的起点)。Hugging Face等主流库已经全部切换到AdamW。
6.5 学习率与优化器的配合:warmup
在Transformer训练中,通常使用学习率预热(warmup):前若干步学习率从0线性增加到设定值。AdamW + 线性warmup是标准配置。
# 使用学习率调度器实现warmup(第10课会详细讲)
from torch.optim.lr_scheduler import LinearLR, SequentialLR
warmup_scheduler = LinearLR(optimizer, start_factor=0.01, end_factor=1.0, total_iters=1000)
main_scheduler = ... # 如CosineAnnealingLR
scheduler = SequentialLR(optimizer, schedulers=[warmup_scheduler, main_scheduler], milestones=[1000])
6.6 多GPU训练时优化器行为
使用nn.DataParallel或DistributedDataParallel时,优化器仍然作用于包装后的模型。需要注意的是,梯度是自动聚合的,优化器更新时每个GPU上的模型副本都会同步更新。代码写法与单GPU完全相同。
七、课后总结
核心优化器速查表
| 优化器 | 核心参数 | 适用任务 | 注意事项 |
|---|---|---|---|
| SGD | lr | 简单任务 | 收敛慢,需仔细调lr |
| SGD+Momentum | lr, momentum=0.9 | CNN图像分类 | 泛化性好,训练稳定 |
| Adam | lr=1e-3, betas=(0.9,0.999) | 快速原型、GAN | weight_decay默认0 |
| AdamW | lr=1e-3~1e-5, weight_decay=0.01 | Transformer、大模型 | 当前最推荐 |
| RMSprop | lr=1e-2, alpha=0.99 | 循环网络 | 较少直接使用 |
参数调优经验值
| 参数 | 常用范围 | 说明 |
|---|---|---|
| 学习率 | 1e-5 ~ 1e-1 | 对数尺度寻找 |
| 动量 | 0.9 ~ 0.99 | 越大惯性越强 |
| weight_decay (SGD) | 1e-5 ~ 1e-3 | 防止过拟合 |
| weight_decay (AdamW) | 0.01 ~ 0.1 | 大模型用0.01 |
| batch_size | 16 ~ 512 | 视显存而定 |
| 梯度裁剪阈值 | 1.0 ~ 5.0 | 防止爆炸 |
检查清单
- 理解了SGD、Momentum、Adam的基本原理
- 能根据任务选择优化器(CV用SGD+Momentum,NLP用AdamW)
- 知道如何设置学习率的初始值,以及何时需要降低学习率
- 会使用梯度裁剪防止梯度爆炸
- 能正确设置weight_decay(区分Adam和AdamW)
- 了解AdamW与Adam的区别,并在实践中优先使用AdamW
- 遇到训练不收敛时,知道从学习率、优化器、梯度裁剪三个方向调试
八、课后作业
作业1:动量作用验证
构造一个简单的二次函数 f(x) = x^2,使用SGD和SGD+Momentum分别优化,迭代步数相同,比较收敛速度和最终到达的点。画出参数更新轨迹。
作业2:学习率对收敛的影响
在CIFAR-10上训练一个简单的CNN(如两层卷积+全连接),固定优化器为SGD+Momentum(momentum=0.9),分别尝试学习率 [0.001, 0.01, 0.1, 0.5]。画出每个学习率下的损失曲线,分析哪个学习率最合适。
作业3:Adam vs SGD泛化对比
使用第11课的手写数字识别代码,分别在Adam(lr=0.001)和SGD+Momentum(lr=0.01, momentum=0.9)下训练相同的网络(5个epoch)。比较训练集和测试集的准确率,分析哪个优化器泛化更好。
作业4:梯度裁剪实验
在RNN或LSTM的序列预测任务中(可简单构造数据),故意将学习率设置得很大导致梯度爆炸(loss变成NaN)。加入梯度裁剪后观察能否稳定训练。
作业5:优化器参数分组实现微调
假设你有一个在ImageNet上预训练的ResNet18,你想微调最后两层(fc层)而冻结前面的层。请编写代码实现:为fc层设置学习率0.01,其余层学习率0;优化器使用SGD,momentum=0.9,weight_decay=1e-4。
九、下一课预告
第10课我们将学习学习率调度策略全面精讲,内容包括:
- 固定学习率的弊端
- 阶梯式衰减(StepLR)、多项式衰减(PolynomialLR)
- 余弦退火(CosineAnnealingLR)及其热重启变体(CosineAnnealingWarmRestarts)
- 学习率预热(LinearLR、ConstantLR)
- 自定义调度器以及学习率与优化器的协同调试
学完第10课,你将能结合优化器和学习率调度器,让你的模型训练达到最佳的收敛速度和泛化性能。
附录:PyTorch优化器API完整列表
| 优化器 | 初始化示例 | 关键参数 |
|---|---|---|
SGD | optim.SGD(params, lr=0.01, momentum=0, weight_decay=0) | lr, momentum, weight_decay |
Adam | optim.Adam(params, lr=1e-3, betas=(0.9,0.999), eps=1e-8, weight_decay=0) | lr, betas, weight_decay |
AdamW | optim.AdamW(params, lr=1e-3, betas=(0.9,0.999), weight_decay=0.01) | lr, weight_decay |
RMSprop | optim.RMSprop(params, lr=0.01, alpha=0.99, momentum=0) | lr, alpha, momentum |
Adagrad | optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0) | lr |
Adamax | optim.Adamax(params, lr=2e-3, betas=(0.9,0.999), weight_decay=0) | lr, betas |
NAdam | optim.NAdam(params, lr=2e-3, betas=(0.9,0.999), weight_decay=0) | lr |
RAdam | optim.RAdam(params, lr=1e-3, betas=(0.9,0.999), weight_decay=0) | lr |
🔗《精讲25课|PyTorch 从入门到精通》系列课程导航
🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~
更多推荐


所有评论(0)