以下是从这里获取的PyTorch中随机权重平均的一个小型工作代码示例。
loader, optimizer, model, loss_fn = ...swa_model = torch.optim.swa_utils.AveragedModel(model)scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=300)swa_start = 160swa_scheduler = SWALR(optimizer, swa_lr=0.05)for epoch in range(300): for input, target in loader: optimizer.zero_grad() loss_fn(model(input), target).backward() optimizer.step() if epoch > swa_start: swa_model.update_parameters(model) swa_scheduler.step() else: scheduler.step() # 在末尾更新swa_model的bn统计数据 torch.optim.swa_utils.update_bn(loader, swa_model) # 使用swa_model对测试数据进行预测 preds = swa_model(test_input)
在这个代码中,在第160个epoch之后,使用了swa_scheduler
而不是常规的scheduler
。那么swa_lr
代表什么呢?文档中提到,
通常,在SWA中,学习率被设置为一个较高的常数值。SWALR是一种学习率调度器,它将学习率调整到一个固定值,然后保持不变。
- 那么在第160个epoch之后,
optimizer
的学习率会发生什么变化? swa_lr
是否会影响optimizer
的学习率?
假设在代码的开始,optimizer
是用学习率1e-4
初始化的ADAM
。那么上述代码是否意味着在前160个epoch中,训练的学习率将是1e-4
,然后在剩余的epoch中将是swa_lr=0.05
?如果是的话,将swa_lr
也定义为1e-4
是否是一个好主意?
回答:
-
上述代码是否意味着在前160个epoch中,训练的学习率将是
1e-4
不会是
1e-4
,在前160个epoch中,学习率是由第一个调度器scheduler
管理的。这个调度器被初始化为torch.optim.lr_scheduler.CosineAnnealingLR
。学习率将遵循以下曲线:
-
在剩余的epoch中将是
swa_lr=0.05
这部分是对的,在第二部分 – 从第160个epoch开始 – 优化器的学习率将由第二个调度器
swa_scheduler
管理。这个调度器被初始化为torch.optim.swa_utils.SWALR
。您可以在文档页面上阅读到:SWALR是一种学习率调度器,它将学习率调整到一个固定值[
swa_lr
],然后保持不变。默认情况下(参见源代码),调整前的epoch数等于10。因此,从第170个epoch到第300个epoch,学习率将等于
swa_lr
,并将保持不变。第二部分将是:这个完整的配置,即两部分: