当前位置: 首页 > news >正文

深度学习篇---Adam优化器

Adam 优化器是 PyTorch 中最常用的优化器之一,它结合了 SGD+Momentum 和 RMSprop 的优点,自带自适应学习率调整功能,对初学者非常友好。下面用通俗易懂的方式讲解其原理和用法,并提供详细代码示例。

为什么 Adam 更受欢迎?

可以把各种优化器比作不同的下山方式:

  • 普通 SGD 是 "步行",需要手动控制步长
  • SGD+Momentum 是 "骑车",有惯性但仍需手动控速
  • Adam 是 "自动驾驶汽车":能自动根据路况(梯度变化)调整速度和方向,既快又稳

Adam 的核心优势:

  • 不需要手动精细调整学习率
  • 收敛速度比 SGD 快
  • 对噪声数据更稳健
  • 适合大多数模型(CNN、RNN、Transformer 等)

完整代码示例(对比 Adam 和 SGD)

下面通过图像分类任务,直观展示 Adam 的优势:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy as np# 设置随机种子,保证结果可复现
torch.manual_seed(42)
np.random.seed(42)# 1. 准备数据(使用MNIST手写数字数据集)
# 数据预处理:转为张量并标准化
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))  # MNIST数据集的均值和标准差
])# 加载训练集和测试集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform
)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform
)# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)# 2. 定义模型(简单CNN)
class SimpleCNN(nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)self.pool = nn.MaxPool2d(2, 2)  # 池化层,缩小特征图尺寸self.fc1 = nn.Linear(64 * 7 * 7, 128)  # 全连接层self.fc2 = nn.Linear(128, 10)  # 输出层(10个类别)self.relu = nn.ReLU()def forward(self, x):x = self.pool(self.relu(self.conv1(x)))  # 卷积+激活+池化x = self.pool(self.relu(self.conv2(x)))x = x.view(-1, 64 * 7 * 7)  # 展平特征图x = self.relu(self.fc1(x))x = self.fc2(x)return x# 创建两个相同的模型,分别用Adam和SGD训练
model_adam = SimpleCNN()
model_sgd = SimpleCNN()  # 结构相同,参数独立# 3. 定义损失函数(交叉熵损失,适合分类任务)
criterion = nn.CrossEntropyLoss()# 4. 初始化优化器
# Adam优化器(推荐参数)
optimizer_adam = optim.Adam(model_adam.parameters(),lr=0.001,          # 学习率:Adam默认0.001,通常无需修改betas=(0.9, 0.999),# 动量参数:控制一阶矩和二阶矩的指数衰减率weight_decay=1e-5  # 权重衰减:防止过拟合
)# SGD优化器(作为对比)
optimizer_sgd = optim.SGD(model_sgd.parameters(),lr=0.01,           # SGD通常需要更大的学习率momentum=0.9,weight_decay=1e-5
)# 5. 训练模型
def train(model, optimizer, train_loader, criterion, epochs=10):model.train()  # 切换到训练模式train_losses = []train_accuracies = []for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for i, (inputs, labels) in enumerate(train_loader):# 前向传播outputs = model(inputs)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()  # 清空梯度loss.backward()        # 计算梯度optimizer.step()       # 更新参数# 统计损失和准确率running_loss += loss.item()_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()# 每100批次打印一次信息if i % 100 == 99:print(f'[{epoch+1}, {i+1}] loss: {running_loss/100:.3f}')running_loss = 0.0# 计算本轮的平均损失和准确率epoch_loss = running_loss / len(train_loader)epoch_acc = 100 * correct / totaltrain_losses.append(epoch_loss)train_accuracies.append(epoch_acc)print(f'Epoch {epoch+1} - Loss: {epoch_loss:.4f}, Accuracy: {epoch_acc:.2f}%')return train_losses, train_accuracies# 分别训练两个模型(5轮即可看出差异)
print("===== 用Adam训练 =====")
adam_losses, adam_accs = train(model_adam, optimizer_adam, train_loader, criterion, epochs=5)print("\n===== 用SGD训练 =====")
sgd_losses, sgd_accs = train(model_sgd, optimizer_sgd, train_loader, criterion, epochs=5)# 6. 可视化结果
plt.figure(figsize=(14, 6))# 左图:损失对比
plt.subplot(1, 2, 1)
plt.plot(range(1, 6), adam_losses, 'r-', marker='o', label='Adam')
plt.plot(range(1, 6), sgd_losses, 'b-', marker='s', label='SGD+Momentum')
plt.title('训练损失对比')
plt.xlabel('轮次')
plt.ylabel('损失值')
plt.legend()# 右图:准确率对比
plt.subplot(1, 2, 2)
plt.plot(range(1, 6), adam_accs, 'r-', marker='o', label='Adam')
plt.plot(range(1, 6), sgd_accs, 'b-', marker='s', label='SGD+Momentum')
plt.title('训练准确率对比')
plt.xlabel('轮次')
plt.ylabel('准确率 (%)')
plt.legend()plt.tight_layout()
plt.show()

关键知识点解析

1. Adam 优化器的核心参数

Adam 的参数比 SGD 多,但大部分情况下用默认值即可:

  • lr(学习率)

    • 默认值0.001,这是 Adam 最推荐的初始值
    • 调整逻辑:若损失下降慢,可增大到0.003;若震荡大,可减小到0.0001
    • 注意:Adam 对学习率的敏感度比 SGD 低,不用频繁调整
  • betas

    • 是一个元组(beta1, beta2),默认(0.9, 0.999)
    • beta1:一阶矩(动量)的指数衰减率,类似 SGD 的 momentum
    • beta2:二阶矩的指数衰减率,控制学习率的自适应程度
    • 几乎不需要修改,这组默认值在绝大多数场景都表现优秀
  • weight_decay

    • 权重衰减(L2 正则化),默认0
    • 用法和 SGD 相同:过拟合时增大(1e-5 ~ 1e-3),欠拟合时减小
2. Adam 的工作原理(通俗解释)

Adam 的名字来自 "Adaptive Moment Estimation"(自适应矩估计),它做了两件聪明事:

  1. 动量(Momentum):记住过去的梯度方向,类似滚动的小球,加速收敛
  2. 自适应学习率:对更新频繁的参数(如高频特征)用小学习率,对更新少的参数用大学习率

简单说,Adam 会根据参数的 "历史表现" 动态调整学习策略,不需要人工干预。

3. 代码运行结果分析

从对比图中能明显看到 Adam 的优势:

  • 损失下降更快:前 2 轮就显著低于 SGD
  • 准确率提升更快:5 轮后通常比 SGD 高 5%~10%
  • 训练更稳定:损失曲线波动更小
4. 实际使用技巧
  • 新手首选:不知道用什么优化器时,直接用Adam(lr=0.001),80% 的任务都能跑通
  • 学习率调整:若要调参,优先调整lr,范围通常在1e-4 ~ 1e-3之间
  • 配合调度器:虽然 Adam 自带自适应,但后期用ReduceLROnPlateau调度器仍能提升效果
  • 大模型训练:当训练 BERT 等大模型时,建议用AdamW(Adam 的改进版,权重衰减更合理)
5. 适用场景

Adam 几乎适用于所有深度学习任务,尤其推荐:

  • 初学者入门(调参简单)
  • 复杂模型(如 CNN、RNN、Transformer)
  • 数据量中等或较小的场景
  • 希望快速看到训练效果的场景

通过这个示例,你可以看到 Adam 相比 SGD 的明显优势。在实际项目中,建议优先尝试 Adam 优化器,尤其是当你对调参不太熟悉时,它能帮你节省大量调试时间。

http://www.dtcms.com/a/365319.html

相关文章:

  • 计算机网络模型总概述
  • python抖音弹幕获取方案
  • 考研复习-计算机网络-第二章-物理层
  • 服务器安装vnc服务端
  • 深度学习篇---InceptionNet网络结构
  • Ecovadis评估认证准备期间对于公司员工培训有没有什么技巧?
  • 对轮询的理解
  • 手持式气象观测仪在短期监测项目的作用
  • 深度学习之第六课卷积神经网络 (CNN)如何保存和使用最优模型
  • GOFLY开源客服系统-处理gin框架下的session中间件
  • 【线段树 懒删除堆】P12372 [蓝桥杯 2022 省 Python B] 最优清零方案|普及+
  • 【Python接口自动化】调用飞书机器人
  • TLSF内存算法适配HTOS
  • React实现列表拖拽排序
  • PyTorch实战(6)——模型微调详解
  • 落地页测试case(Android视角)
  • Redis突然挂了,数据丢了多少?就看你用RDB还是AOF
  • SecureCRT v9.5.2 Mac SSH终端操作工具
  • C++从入门到实战(二十一)List迭代器实现
  • 行业分享丨基于SimSolid的大型汽车连续冲压模具刚度分析
  • 【Axure高保真原型】区间缩放柱状图
  • JavaScript箭头函数与普通函数:两种工作方式的深度解析
  • android studio打开Android Device Monitor
  • Java 鲁棒性:支撑企业级应用稳定运行的核心密码
  • websoket使用记录
  • 马斯克砸钱造AI,却败给最low的“让离职员工轻松拷走代码”
  • OpenLayers 入门篇教程 -- 章节三 :掌控地图的视野和交互
  • 《计算机网络安全》实验报告一 现代网络安全挑战 拒绝服务与分布式拒绝服务攻击的演变与防御策略(1)
  • 【全息投影】幻影成像技术在展厅中的创新应用
  • 求单源最短路(Dijkstra 算法-迪杰斯特拉算法,SPFA)