诚信为本,市场在变,诚信永远不变...
  咨询电话:400-123-4567

行业新闻

AdamW 优化器

? ? ? Adam 优化器于 2014 年推出,其思想:既然知道某些参数移动得更快、更远,则每个参数不需要遵循相同的学习率,因为最近梯度的平方代表每一个权重可以得到多少信号,可以除以这个,确保即使是最迟钝的权重也有机会起作用。Adam 在收敛性证方面有明显问题,需要调整参数。

L2 正则化是减少过拟合的经典方法,会向损失函数添加由模型所有权重的平方和组成的惩罚项,并乘上特定的超参数以控制惩罚力度,pytorch表示:loss + wd * weights.pow(2).sum()/2;wd 为超参数,控制惩罚力度,称为权重衰减,当运用原版 SGD 时,等价于使用如下方程式更新权重:w = w - lr * w.grad - lr * wd * w,lr 为学习率、w.grad 表示损失函数对 w 的导数,wd * w 表示惩罚项对 w 的求导结果。每一次更新都会减去一小部分权重,这就是「衰减」的来源。

? ? ? ? 通常实现库都使用第一种形式,通过梯度 wd*w 而实现算法,而不是真正地改变损失函数。因为不希望增加额外的计算量来修正损失。当添加动量或使用如 Adam 那样复杂的最优化方法,L2 正则化(第一个方程)和权重衰减(第二个方程)会有很大的不同。在本文其余的部分中,我们讨论权重衰减指的都是第二个方程式,而讨论 L2 正则化都是讨论第一个经典方式。

如下在带动量的 SGD 中,L2 正则化与权重衰减是不等价的。L2 正则化会将 wd*w 添加到梯度中,但现在权重并不是直接减去梯度。首先需要计算移动均值:moving_avg = alpha * moving_avg + (1 - alpha) * (w.grad + wd * w);之后权重通过减去乘上了学习率的移动均值更新。w 更新中涉及到的正则化为 lr * (1 - alpha) * wd * w 加上已经在 moving_avg 中前面权重的组合。权重衰减的更新方式可以表示为:

moving_avg = alpha * moving_avg + (1 - alpha) * w.grad

w = w - lr * moving_avg - lr * wd * w

从 w 中减去有关正则化的部分在两种方法中是不同的。使用 Adam 优化器时,权重衰减的部分可能相差更大,因为 Adam 中的 L2 正则化需要添加 wd * w 到梯度中,分别计算梯度及其平方的移动均值,再更新权重;而权重衰减方法只是简单地更新权重,并每次从权重中减去一点。显然这是两种不同的方法,实验验证应该在 Adam 算法中使用权重衰减方法(AdamW),而不是经典深度学习库中实现的 L2 正则化。

? ? ? ? 使用?fastai 库时,在使用 fit 函数时添加参数 use_wd_sched=True 就能实现:model.fit(lr, 1, wds=1e-4, use_wd_sched=True)。

在优化器中的阶梯函数,只需要使用梯度修正参数,不使用参数本身的值(权重衰减在外部处理),然后在最优化器之前实现权重衰减,但仍需要在计算梯度后完成,否则会影响梯度值。所以在训练循环中,必须确定计算权重衰减的位置,loss.backward(),optimizer.step(),在optimizer step 处做权重衰减,最优化器应该设定 wd=0,否则其还会做一些 L2 正则化。现在在权重衰减的位置中可以在所有参数上写一个循环语句,并依次采用权重衰减的更新。参数应该存储在优化器的字典 param_groups 中,循环如下:

loss.backward()
for group in optimizer.param_groups():
    for param in group['params']:
        param.data = param.data.add(-wd * group['lr'], param.data)
optimizer.step()

参考:

当前训练神经网络最快的方式:AdamW优化算法+超级收敛 - 知乎

平台注册入口