PyTorch 优化器:带有权重衰减的 AdamW 和 Adam

问题描述 投票:0回答:2

torch.optim.Adam(weight_decay=0.01)
torch.optim.AdamW(weight_decay=0.01)
有什么区别吗?

文档链接:torch.optim

python machine-learning pytorch
2个回答
63
投票

是的,Adam 和 AdamW 权重衰减是不同的。

Hutter 在他们的论文(解耦权重衰减正则化)中指出,每个库中 Adam 实现权重衰减的方式似乎是错误的,并提出了一种简单的方法(他们称之为 AdamW)来修复它。

在 Adam 中,权重衰减通常是通过在梯度中添加

wd*w
wd
是权重衰减)来实现(第一种情况),而不是实际从权重中减去(第二种情况)。

# Ist: Adam weight decay implementation (L2 regularization)
final_loss = loss + wd * all_weights.pow(2).sum() / 2
# IInd: equivalent to this in SGD
w = w - lr * w.grad - lr * wd * w

这些方法对于普通 SGD 来说是相同的,但是一旦我们添加动量,或者使用 Adam 等更复杂的优化器,L2 正则化(第一个方程)和权重衰减(第二个方程)就会变得不同。

AdamW 遵循第二个权重衰减方程。

在亚当

weight_decay (float, 可选) – 权重衰减(L2 惩罚)(默认值:0)

在亚当W

weight_decay (float, 可选) – 权重衰减系数(默认: 1e-2)

fastai博客上阅读更多内容。


18
投票

Pytorch中,Adam 和 AdamW 的实现是不同的。在 Adam 源代码中,权重衰减实现为

grad = grad.add(param, alpha=weight_decay)

而在AdamW源代码中,它的实现为

param.mul_(1 - lr * weight_decay)

因此,在 Adam 中,每次迭代中,梯度 都会根据前一次迭代的估计参数(按权重衰减加权)进行更新。另一方面,在 AdamW 中,parameters 由之前迭代的参数进行更新,并通过权重衰减进行加权。文档中的伪代码清楚地显示了差异(框出以强调),其中 lambda 是权重衰减。

pseudocode


但是在 Keras 中,即使默认实现不同,因为 Adam 有

weight_decay=None
而 AdamW 有
weight_decay=0.004
(事实上,它不能为 None),如果
weight_decay
不是 None,Adam 与 AdamW 相同。两者都是
optimizer.Optimizer
的子类,事实上,它们的源代码几乎相同;特别是,每次迭代中更新的变量是相同的。唯一的区别是 Adam's
weight_decay
的定义被推迟到父类,而 AdamW's
weight_decay
则在 AdamW 类本身中定义。

© www.soinside.com 2019 - 2024. All rights reserved.