Adam AdamW
Adam核心计算流程
-
初始化参数
- 初始化一阶矩(动量)向量 和二阶矩(梯度平方的指数平均)向量 。
- 设定超参数:学习率 (默认0.001)、动量衰减因子 (默认0.9)、二阶矩衰减因子 (默认0.999)、数值稳定常数 (默认1e-8)
-
计算当前梯度
在时间步 ,计算损失函数对参数 的梯度 -
更新一阶矩(动量项)
对梯度进行指数加权移动平均,模拟动量效果: -
更新二阶矩(梯度平方的指数平均)
计算梯度平方的移动平均,用于自适应调整学习率: -
偏差校正(Bias Correction)
因初始时刻 和 偏向0,需通过时间步 修正: -
参数更新
结合修正后的矩估计调整学习率,更新参数
class AdamOptimizer:
def __init__(self, learning_rate=0.01, beta1=0.9, beta2=0.999, epsilon=1e-8):
self.lr = learning_rate
self.beta1 = beta1
self.beta2 = beta2
self.epsilon = epsilon
self.m = 0
self.v = 0
self.t = 0
def update(self, params, grads):
self.t += 1
for param, grad in zip(params, grads):
self.m[param] = self.beta1 * self.m[param] + (1 - self.beta1) * grad
self.v[param] = self.beta2 * self.v[param] + (1 - self.beta2) * grad**2
m_hat = self.m[param] / (1 - self.beta1**self.t)
v_hat = self.v[param] / (1 - self.beta2**self.t)
param = param - self.lr * m_hat / (np.sqrt(v_hat) + self.epsilon)
return params
weight decay
权重衰减,本质上希望对权重进行惩罚,权重绝对值越大越不好
w = w - lr * w.grad - lr * weight_decay * w
L2正则化,表示对权重的衰减比例和权重绝对值的平方成正比
final_loss = loss + wd * all_weights.pow(2).sum() / 2
Adam在实现L2正则化的时候是直接修改梯度,随后梯度会参与动量的计算,导致L2正则化的梯度就会被抵消掉,导致效果不佳
grad_w = grad_w + weight_decay * w
AdamW
AdamW 的实现方法与传统的 L2 正则化不同,它直接对权重进行衰减,而不是将其加到损失函数上(改变grad_w)
grad_w = grad_w
# update step
w = w - learning_rate * grad_w - learning_rate * weight_decay * w
No Comments