PyTorch 权重衰减实战:3 段代码把过拟合压下去
PyTorch 权重衰减实战3 段代码把过拟合压下去【免费下载链接】pytorch-deep-learningMaterials for the Learn PyTorch for Deep Learning: Zero to Mastery course.项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-deep-learning模型的训练损失降到 0.1测试损失却停在 1.8损失曲线的形状就是下面图里中间那张overfitting。多半不是模型架构的问题而是建优化器时没传权重衰减weight decay。这篇文章用 PyTorch 优化器的weight_decay参数分 3 段代码演示怎么把它用起来。读完你改一下自己训练脚本里的优化器就行并且知道衰减系数该往哪个量级试。训练损失蓝远低于测试损失红就是过拟合权重衰减要缩小这个差距出自 04_pytorch_custom_datasets.ipynb 的如何对付过拟合一节30 秒速览就一行代码Adam/SGD 构造时传weight_decay每次optimizer.step()都会顺手把权重罚小一点。默认值有坑PyTorch 的weight_decay默认是 0不传就等于没开权重衰减。推荐区间CNN 和普通 MLP 从 1e-5 ~ 1e-3 起步Transformer 类可以直接上 0.1ViT 论文的配置。bias 和 BatchNorm 参数别衰减传参前先把它们单独拎出来。判断信号训练损失降不下去、两条曲线快贴死八成是衰减开大了先调小再谈其他。为什么管用用大白话讲清楚原理把权重衰减想象成给每个权重收租金权重大每次优化交的租金就多于是优化过程会被逼着维持较小的权重。L_total L_original λ * Σ(w²)翻译成人话就是模型每多用一点容量就得付出代价它只好去找更省的方式去拟合数据学到的是规律而不是训练集里的噪声。λ 就是weight_decay的值租金收得越多模型越抠。训练循环里zero grad → backward → step转起来的时候权重衰减就搭在 step 这班车上下车出自 01_pytorch_workflow.ipynb跟着敲最小可运行示例先用一个两层 MLP 验证机制权重衰减到底是优化器的参数不是损失函数里的东西。import torch model torch.nn.Sequential(torch.nn.Linear(784, 128), torch.nn.ReLU(), torch.nn.Linear(128, 10)) # 两层 MLP 够用 # 给优化器加权重衰减。注意默认是 0不传就等于没开 optimizer torch.optim.Adam(model.parameters(), lr1e-3, weight_decay1e-4) x, y torch.randn(32, 784), torch.randint(0, 10, (32,)) for _ in range(200): optimizer.zero_grad() torch.nn.functional.cross_entropy(model(x), y).backward() optimizer.step() print([round(p.abs().mean().item(), 4) for p in model.parameters()])跑起来你会看到最后一行打印 4 个参数矩阵的平均绝对值都是偏小的数。把weight_decay改成 0 再跑一遍数字会明显大一圈——这就是罚出来的差别。训练循环五步forward、算 loss、zero_grad、backward、step权重衰减藏在最后一步里出自 01_pytorch_workflow.ipynb如果你用的是仓库里的 going_modular 结构改动只发生在优化器定义上训练流程本身不用动。下面这段对应 going_modular/going_modular/train.py 里torch.optim.Adam(model.parameters(), lrLEARNING_RATE)那一行的改法# 只多传一个参数训练流程照旧 optimizer torch.optim.Adam(model.parameters(), lr0.001, weight_decay1e-4) # 小数据集给点衰减压一压 engine.train(modelmodel, train_dataloadertrain_dataloader, test_dataloadertest_dataloader, optimizeroptimizer, loss_fntorch.nn.CrossEntropyLoss(), epochs20, devicedevice)改完train.py里优化器那一行照常python train.py跑就行出自 05_pytorch_going_modular.md跑起来你会看到 engine.py 每个 epoch 打印 train/test 的 loss 和 accuracy两条线的差距会比不衰减时收得更快。想看得直观一点把engine.train返回的 history 丢给 helper_functions.py 里的plot_loss_curves画出来。最后一段是 Transformer 场景。仓库的 08_pytorch_paper_replicating.ipynb 复现 ViT 论文时直接照抄了论文 4.1 节的超参# 复现 ViT 论文超参论文 Table 3 里 ViT-* 用的是 0.3 optimizer torch.optim.Adam(paramsvit.parameters(), lr3e-3, betas(0.9, 0.999), weight_decay0.1) # 0.1 的高衰减论文明确写了的跑起来不会有立竿见影的输出值好不好得等训练完看测试集才知道——这正是论文要把具体数字写下来的原因照抄比瞎猜省时间。踩坑对比错误写法 vs 正确写法坑一以为默认值会帮你❌ 错误写法optimizer torch.optim.Adam(model.parameters(), lr1e-3) # 心想Adam 总自带衰减吧✅ 正确写法optimizer torch.optim.Adam(model.parameters(), lr1e-3, weight_decay1e-4) # 显式写出来别赌默认值一句话解释weight_decay默认是 0忘了传和故意不用是两回事出问题时你分不清自己属于哪种。坑二不加区分地把所有参数一起衰减❌ 错误写法optimizer torch.optim.Adam(model.parameters(), lr1e-3, weight_decay1e-2) # 每层的 bias、BatchNorm 的缩放参数也被按 1e-2 罚✅ 正确写法params [{params: [p for n, p in model.named_parameters() if bias not in n], weight_decay: 1e-2}, {params: [p for n, p in model.named_parameters() if bias in n], weight_decay: 0.0}] # bias 不罚 optimizer torch.optim.Adam(params, lr1e-3)一句话解释bias 和 BN 的缩放参数是偏移量决定的是数值平不平不决定模型复不复杂罚它们只会让拟合变难。进阶参数怎么调、边界在哪weight_decay 取值范围CNN、普通 MLP 从 1e-5 ~ 1e-3 起步从零训 Transformer 或大学习率场景可以上 1e-2 ~ 0.1。理由就一条lr 越大、模型越大权重越容易跑野衰减得跟着抬。⚠️ 别直接往 1 以上填那已经不是衰减是处刑。和学习率怎么搭配两者绑着调Adam 配 lr3e-3 时可以上 0.1 的衰减ViT 的组合但 lr 只有 1e-5 时同样用 0.1权重只减不学。⚠️ 训练损失迟迟不降时先检查衰减是不是相对 lr 太大别急着加 epoch。小数据场景样本量小于 1 万张图时建议 1e-4 ~ 1e-3并且优先配合数据增强一起上。理由样本少模型最容易背题衰减是最便宜的一道保险。⚠️ 如果测试损失高、训练损失也降不下去那是衰减开大了解法是调小不是加训。Adam 还是 AdamW想要解耦权重衰减decoupled weight decay就上torch.optim.AdamW。普通 Adam 的weight_decay本质是 L2 正则化往损失里加一项效果接近但不完全一样。⚠️ 换优化器时别把两边的weight_decay值直接互相搬运。组合拳和其他技术怎么搭配当数据集小、train/test 差距拉得大时优先搭配数据增强04_pytorch_custom_datasets.ipynb 里的transforms.Compose加 1e-4 ~ 1e-3 的衰减增强负责加样本衰减负责压容量两头夹。当微调预训练骨干网络时优先搭配小学习率1e-4 ~ 1e-5加小衰减1e-5 ~ 1e-4预训练权重本来就泛化衰减太猛会把好权重打散。当从零训 Transformer 时优先搭配betas(0.9, 0.999)加 0.1 量级衰减08_pytorch_paper_replicating.ipynb 里的组合Transformer 权重方差大高衰减是稳定性的一部分。速查清单优化器里显式传了weight_decay默认 0 等于没开bias 和 BatchNorm 参数已从衰减范围里剔除按 1e-5 / 1e-4 / 1e-3 / 1e-2 四个档位各试一轮按测试损失选用 helper_functions.py 的plot_loss_curves确认了 train/test 曲线方向训练损失不降且两曲线贴平时先调小衰减而不是加 epoch下次再看到训练曲线漂亮、测试曲线难看的模型先翻出来看看优化器里那行weight_decay写没写、写了多少。写错了调一下没写补上重跑半小时内就能看出方向。延伸阅读08_pytorch_paper_replicating.ipynb看 ViT 论文超参含 weight_decay0.1是怎么一步步落成代码的。going_modular/going_modular/engine.py训练循环的标准模板看懂optimizer.step()在哪就懂了权重衰减在哪生效。04_pytorch_custom_datasets.ipynb如何对付过拟合一节列了能跟权重衰减配合的其他正则化手段。【免费下载链接】pytorch-deep-learningMaterials for the Learn PyTorch for Deep Learning: Zero to Mastery course.项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-deep-learning创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考