有什么区别torch.optim.Adam(weight_decay=0.01)和torch.optim.AdamW(weight_decay=0.01)?
链接到文档:torch.optim
kHa*_*hit 15
是的,Adam 和 AdamW 的权重衰减是不同的。
Hutter 在他们的论文(Decoupled Weight Decay Regularization)中指出,在 Adam 中每个库中实现权重衰减的方式似乎是错误的,并提出了一种简单的方法(他们称之为 AdamW)来修复它。
在 Adam 中,权重衰减通常是通过将wd*w(wd这里是权重衰减)添加到梯度(Ist 情况)来实现的,而不是实际从权重中减去(IInd 情况)。
# 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
Run Code Online (Sandbox Code Playgroud)
这些方法对于普通 SGD 是相同的,但是一旦我们添加动量,或者使用更复杂的优化器(如 Adam),L2 正则化(第一个方程)和权重衰减(第二个方程)就会变得不同。
AdamW 遵循权重衰减的第二个方程。
在亚当
weight_decay (float, optional) – 权重衰减(L2 惩罚)(默认值:0)
在亚当W
weight_decay (float, optional) – 权重衰减系数(默认值:1e-2)
在fastai 博客上阅读更多内容。
在Pytorch中,Adam 和 AdamW 的实现是不同的。在Adam 源代码中,权重衰减实现为
grad = grad.add(param, alpha=weight_decay)
Run Code Online (Sandbox Code Playgroud)
而在AdamW 源代码中,它的实现为
param.mul_(1 - lr * weight_decay)
Run Code Online (Sandbox Code Playgroud)
因此,在每次迭代中,在 Adam 中,梯度都会根据前一次迭代的估计参数(按权重衰减加权)进行更新。另一方面,在 AdamW 中,参数由前一次迭代的参数通过权重衰减加权进行更新。文档中的伪代码清楚地显示了差异(用框表示强调),其中 lambda 是权重衰减。
然而在Keras中,即使默认实现不同,因为 Adam 有weight_decay=None而 AdamW 有weight_decay=0.004(事实上,它不能是 None),如果weight_decay不是 None,Adam 与 AdamW 相同。两者都是子类optimizer.Optimizer,事实上,它们的源代码几乎相同;特别是,每次迭代中更新的变量是相同的。唯一的区别是Adam 的 定义weight_decay被推迟到父类,而AdamW 的 weight_decay定义在 AdamW 类本身中定义。
| 归档时间: |
|
| 查看次数: |
10222 次 |
| 最近记录: |