AdamW算法
·
AdamW算法是优化算法Adam的一个变体,它在深度学习中广泛应用。AdamW的主要改进在于它正则化方法的改变,即通过权重衰减(weight decay)而不是L2正则化,来控制模型参数的大小,从而提升了训练的稳定性和效果。
背景
- Adam优化器结合了动量(Momentum)和RMSProp的优点,能够在各种神经网络结构中实现高效的训练。然而,Adam算法中的L2正则化实现存在一些问题,特别是在实际实现中,L2正则化被融合到了梯度更新中,这可能导致不稳定的权重更新。
- AdamW通过将权重衰减(weight decay)从梯度更新过程中分离出来,解决了这些问题。具体来说,AdamW将权重衰减直接应用到权重更新步骤中,而不是将其作为损失函数的一部分进行梯度计算。
公式
AdamW的更新公式与Adam类似,但引入了显式的权重衰减项。以下是AdamW的核心公式:
-
偏移修正的动量估计:
mt=β1mt−1+(1−β1)gt m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_tmt=β1mt−1+(1−β1)gt vt=β2vt−1+(1−β2)gt2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2vt=β2vt−1+(1−β2)gt2 -
偏移修正:
m^t=mt1−β1t \hat{m}_t = \frac{m_t}{1 - \beta_1^t}m^t=1−β1tmt v^t=vt1−β2t\hat{v}_t = \frac{v_t}{1 - \beta_2^t}v^t=1−β2tvt -
参数更新:
θt=θt−1−ηm^tv^t+ϵ−ηλθt−1 \theta_t = \theta_{t-1} - \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} - \eta \lambda \theta_{t-1} θt=θt−1−ηv^t+ϵm^t−ηλθt−1
其中:
- θt\theta_tθt 是参数。
- gtg_tgt 是梯度。
- mtm_tmt 和vtv_tvt是一阶和二阶动量估计。
- η\etaη 是学习率。
- β1\beta_1β1 和β2\beta_2β2分别是动量项的指数衰减率。
- ϵ\epsilonϵ是防止除零的小常数。
- λ\lambdaλ 是权重衰减系数。
优点
- 更稳定的权重更新:权重衰减独立于梯度计算,使得权重更新更稳定。
- 更好的正则化效果:权重衰减可以更有效地防止模型过拟合。
- 适用于广泛的模型:AdamW在各种深度学习模型中表现优异,尤其是在大规模神经网络中。
实现
import torch
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# 定义数据集和数据加载器
data = torch.randn(1000, 10) # 假设有1000个样本,每个样本有10个特征
labels = torch.randint(0, 2, (1000,)) # 假设二分类任务
dataset = TensorDataset(data, labels)
data_loader = DataLoader(dataset, batch_size=32, shuffle=True)
# 定义模型
model = torch.nn.Linear(10, 2)
criterion = torch.nn.CrossEntropyLoss()
# 创建AdamW优化器
optimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=0.01)
# 训练循环
num_epochs = 100
for epoch in range(num_epochs):
for batch_data, batch_labels in data_loader:
optimizer.zero_grad()
outputs = model(batch_data)
loss = criterion(outputs, batch_labels)
loss.backward()
optimizer.step()
# 打印每个epoch的损失
print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')
更多推荐

所有评论(0)