pytorch api文档:torch.optim.AdamW()-AdamW优化器

介绍

PyTorch 中的 torch.optim.AdamW 优化器,它是Adam 优化器的权重衰减改进版,解决了原始 Adam 权重衰减实现的缺陷,是目前深度学习(尤其是大模型、CV/NLP 任务)中最常用的优化器之一,PyTorch 从 1.2.0 版本开始正式支持。

为什么需要 AdamW?

原始 Adam 优化器的权重衰减(L2 正则)是嵌入在梯度更新步骤中的,会和动量(momentum)、自适应学习率相互干扰,导致权重衰减的实际效果远弱于预期。

AdamW 的核心改进是将权重衰减和梯度更新解耦:

  1. 梯度更新仅由 Adam 的自适应学习率+动量逻辑计算;
  2. 权重衰减单独作为独立的步骤直接作用在模型参数上,保证衰减效果精准生效。

简单说:AdamW = 正确实现的权重衰减 + 原始 Adam,在相同超参数下,AdamW 的泛化能力、收敛稳定性通常优于 Adam。

使用

和 PyTorch 其他优化器(SGD、Adam)的使用流程完全一致,核心是定义优化器时传入模型参数+超参数,训练中执行optimizer.step()更新参数、optimizer.zero_grad()清空梯度。

语法

torch.optim.AdamW(
    params,
    lr=0.001,
    betas=(0.9, 0.999),
    eps=1e-08,
    weight_decay=0.01,
    amsgrad=False,
    foreach=None,
    maximize=False,
    capturable=False,
    differentiable=False,
    fused=None
)

参数详解

🔴 必传参数(无默认值,必须指定)
参数 类型 含义
params 迭代器/列表 模型的可训练参数,几乎都是传model.parameters();也可以传参数分组字典(如之前讲的分lr/weight_decay)
🟠 核心可调参数(需根据任务调优,AdamW的关键)
参数 类型 默认值 常用值 核心含义
lr float 0.001(1e-3) 1e-3/CV;1e-4/NLP/大模型 基础学习率,优化器的核心步长
weight_decay float 0.01(1e-2) 1e-2/1e-4/0 权重衰减系数(L2正则),AdamW解耦后的核心,0表示不衰减
  • weight_decay:唯一需要重点调参的新增项,0表示不使用权重衰减;
    • 小模型/简单任务:可设为 1e-4 或 0;
    • 大模型/复杂任务(CV/NLP):常用 1e-2(这是AdamW的经典值)。
  • lr:需和 weight_decay 配合调参,权重衰减越大,学习率通常适当调小。
🟢 默认参数(99%场景直接用默认,无需修改)
参数 类型 默认值 含义 调优说明
betas 元组(float, float) (0.9, 0.999) 一阶动量β₁、二阶动量β₂,控制梯度的指数移动平均 工业界固定值,绝不修改
eps float 1e-08 极小常数,防止自适应学习率的分母为0,避免数值溢出 固定值,绝不修改
amsgrad bool False 是否启用AMSGrad变体,解决Adam的动量偏差问题 效果提升极有限,开启会增加计算量,不用
foreach bool/None None 批量更新参数,提升优化器计算速度 PyTorch2.0+自动适配,None表示框架自动判断
maximize bool False 是否最大化目标函数(而非最小化损失) 常规任务都是最小化损失,保持False
capturable bool False 支持CUDA异步梯度捕获 仅分布式/异步训练、CUDA高性能场景开启
differentiable bool False 是否让优化器步骤支持自动微分 仅高阶优化/元学习场景使用,普通任务关闭
fused bool/None None 融合多个优化步骤为CUDA核函数,大幅加速训练 PyTorch2.0+支持,仅CUDA环境可开启,None自动判断

最常用的极简语法(实际开发90%的场景)

直接使用必传参数+核心参数,默认参数全部省略,是工业界的标准写法:

# CV任务(如分类/检测)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-2)

# NLP/大模型微调(核心调小lr)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-4)

特殊语法:参数分组(不同参数用不同超参)

这是params参数的高级用法,传入字典列表,为模型不同部分(如骨干/分类头、weight/bias)单独设置lr/weight_decay,语法格式如下:

optimizer = torch.optim.AdamW(
    [
        # 分组1:骨干网络参数,小lr+大衰减
        {"params": model.backbone.parameters(), "lr": 1e-4, "weight_decay": 1e-2},
        # 分组2:分类头参数,大lr+小衰减(默认继承外层超参)
        {"params": model.head.parameters(), "lr": 1e-3},
        # 分组3:偏置/BN参数,不衰减(weight_decay=0)
        {"params": no_decay_params, "weight_decay": 0.0}
    ],
    # 外层超参:作为所有分组的「默认值」,分组内指定会覆盖
    lr=1e-3,
    weight_decay=1e-2
)

总结

  1. AdamW基础语法:torch.optim.AdamW(params, lr=1e-3, weight_decay=1e-2),仅需指定必传的params和核心的lr/weight_decay;
  2. 所有默认参数(betas/eps/amsgrad等)无需修改,工业界固定使用框架默认值;
  3. 高级用法通过参数分组实现,params传入字典列表即可为不同参数单独设置超参;
  4. PyTorch2.0+的新参数(foreach/fused)保持None,框架会自动适配硬件(CPU/GPU)做加速。

例子

import torch
import torch.nn as nn
import torch.optim as optim

# 1. 定义简单模型(示例)
model = nn.Linear(10, 2)  # 输入10维,输出2维的全连接层
# 2. 定义AdamW优化器(核心步骤)
optimizer = optim.AdamW(
    model.parameters(),  # 必须传入模型的可训练参数
    lr=1e-3,             # 学习率(核心超参数,常用1e-3/1e-4)
    weight_decay=1e-2    # 权重衰减系数(核心超参数,常用1e-2/1e-4)
)

# 3. 训练流程(标准步骤)
for epoch in range(10):
    optimizer.zero_grad()  # 每次迭代前清空梯度(避免累加)
    output = model(torch.randn(32, 10))  # 前向传播:32个样本
    loss = output.sum()  # 示例损失(实际任务替换为真实损失)
    loss.backward()      # 反向传播:计算梯度
    optimizer.step()     # 优化器更新参数(AdamW核心逻辑)

AdamW 与 Adam 的区别

特性 Adam AdamW
权重衰减实现 嵌入梯度更新,与动量干扰 独立步骤,直接衰减参数,无干扰
实际衰减效果 弱于设定值,效果打折扣 等于设定值,精准生效
超参数 weight_decay 常用0(因效果差) 核心超参数,常用1e-2/1e-4
泛化能力 中等,易过拟合 更强,过拟合抑制效果更好
适用场景 小模型/简单任务 所有场景(尤其大模型/CV/NLP)

结论:新项目优先使用 AdamW,完全替代 Adam,仅在极特殊的小模型场景下可考虑Adam。

实用技巧(工业界常用)

  1. 学习率调度(必备):AdamW 单独使用固定学习率易收敛到局部最优,需配合学习率调度器(如余弦退火、步长衰减),示例:

    # 定义AdamW + 余弦退火调度器(最常用)
    optimizer = optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-2)
    scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)  # T_max为迭代轮数
    
    # 训练中新增scheduler.step()
    loss.backward()
    optimizer.step()
    scheduler.step()  # 每次迭代更新学习率
    
  2. 参数分组优化:对模型不同部分(如骨干网络/分类头、冻结层/训练层)设置不同的lr和weight_decay,示例(分类任务常用):

    # 骨干网络(如ResNet)用小学习率+大权重衰减,分类头用大学习率+小衰减
    backbone_params = list(model.backbone.parameters())
    head_params = list(model.head.parameters())
    
    optimizer = optim.AdamW(
        [
            {"params": backbone_params, "lr": 1e-4, "weight_decay": 1e-2},
            {"params": head_params, "lr": 1e-3, "weight_decay": 1e-4}
        ]
    )
    
  3. 权重衰减排除偏置/批归一化(BN)参数:偏置(bias)和 BN 层的weight/bias通常不做权重衰减(会导致模型表达能力下降),这是工业界标准操作,示例:

    def get_optimizer(model):
        # 分组:需要衰减的参数(weight)、无需衰减的参数(bias/BN)
        decay_params = []
        no_decay_params = []
        for name, param in model.named_parameters():
            if not param.requires_grad:
                continue  # 跳过冻结的参数
            # 偏置/BN的weight/bias:不衰减
            if name.endswith("bias") or ("bn" in name and name.endswith("weight")):
                no_decay_params.append(param)
            else:
                decay_params.append(param)
        # 定义AdamW,对两组参数分别设置weight_decay
        optimizer = optim.AdamW(
            [
                {"params": decay_params, "weight_decay": 1e-2},
                {"params": no_decay_params, "weight_decay": 0.0}
            ],
            lr=1e-3
        )
        return optimizer
    
    # 使用
    optimizer = get_optimizer(model)
    
  4. 梯度裁剪(Gradient Clipping):配合 AdamW 使用,解决梯度爆炸问题(尤其NLP/大模型),示例:
    loss.backward()
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)  # 裁剪梯度到最大范数1.0
    optimizer.step()
    

六、适用场景

AdamW 是通用型优化器,几乎适配所有深度学习任务,尤其在以下场景表现最优:

  1. 计算机视觉(CV):分类、检测、分割、生成(GAN/Stable Diffusion);
  2. 自然语言处理(NLP):大模型(LLaMA/Transformer)、文本分类、翻译、问答;
  3. 大模型训练/微调:是目前大模型微调的标配优化器;
  4. 复杂模型/高维数据:相比SGD,收敛速度更快,相比Adam,泛化能力更强。

总结

  1. torch.optim.AdamW 是 Adam 的改进版,核心是解耦权重衰减和梯度更新,让权重衰减精准生效;
  2. 用法和其他PyTorch优化器一致,核心超参数为lr(1e-3/1e-4)和weight_decay(1e-2/1e-4),其余超参数用默认值;
  3. 工业界标配用法:AdamW + 学习率调度器 + 排除bias/BN的权重衰减 + 可选梯度裁剪;
  4. 优先替代原始Adam,是目前CV/NLP/大模型等任务的首选优化器。

原文出处:/show_1GW2gabxtURm.html