在 PyTorch 中,学习率调度器(scheduler)用于动态调整优化器的学习率。调度器的状态文件保存了在训练过程中与学习率调度相关的信息。具体来说,学习率调度器保留了以下类型的参数:
1. 当前学习率
- 调度器保存了当前的学习率值,这对恢复训练时继续使用相同的学习率非常重要。不同的调度器可能会以不同的方式存储这个值,但通常它是与优化器一起保存的。
2. 调度器的步数
- 调度器保存了已经进行的步数或周期数。这是用来确定调度器当前处于什么状态,以便在恢复训练时从上一次中断的地方继续调整学习率。
3. 学习率调度器的状态
- StepLR:保存当前的步数。
- ExponentialLR 和 CosineAnnealingLR 等:保存调度器的当前状态,这包括用于计算学习率变化的内部参数。
- ReduceLROnPlateau:保存监控的指标(例如验证损失)以及内部的状态,用于确定何时减少学习率。
4. 内部参数
- 一些调度器有额外的内部参数,例如:
- StepLR 和 MultiStepLR:保存每个步长的调整信息。
- CosineAnnealingLR:保存余弦退火周期的开始时间和状态。
- CyclicLR:保存周期的起始和结束状态。
5. 其他调度器特定的状态
- 例如,
ReduceLROnPlateau
需要保存指标的最优值以及最近的评估值,以决定是否调整学习率。
示例
假设你使用了 StepLR
调度器,调度器保存的状态可能包括:
python
{
'last_epoch': 5, # 上一个已完成的 epoch
'base_lrs': [0.01], # 初始学习率
'step_size': 10, # 每隔多少步调整学习率
'gamma': 0.1 # 学习率衰减因子
}
对于 ReduceLROnPlateau
,状态可能包括:
python
{
'last_epoch': 5, # 上一个已完成的 epoch
'best': 0.1, # 最佳验证损失
'mode': 'min', # 监控模式('min' 或 'max')
'factor': 0.1, # 学习率减少因子
'patience': 10, # 等待多少个 epoch 后减少学习率
'cooldown': 0, # 学习率减少后的冷却期
'verbose': False # 是否打印日志
}
总结
学习率调度器的状态文件包含了用于恢复训练时必要的所有信息,以确保学习率的调整可以从中断点继续。保存这些状态信息可以使训练过程更加稳定,并避免从头开始调整学习率。
示例
当然,下面是一个关于如何保存和恢复 PyTorch 学习率调度器状态的示例:
示例代码
假设我们正在训练一个简单的模型,并使用 StepLR
学习率调度器。在训练过程中,我们会保存模型和调度器的状态,并在恢复训练时重新加载它们。
1. 保存模型和调度器的状态
python
import torch
import torch.optim as optim
import torch.nn as nn
import torch.optim.lr_scheduler as lr_scheduler
# 创建模型和优化器
model = nn.Linear(10, 1)
optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
# 模拟训练过程
for epoch in range(20):
# 模拟一次训练
optimizer.step()
scheduler.step()
# 保存模型和调度器的状态
torch.save({
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'scheduler_state_dict': scheduler.state_dict(),
}, 'checkpoint.pth')
2. 恢复模型和调度器的状态
python
import torch
import torch.optim as optim
import torch.nn as nn
import torch.optim.lr_scheduler as lr_scheduler
# 创建模型和优化器
model = nn.Linear(10, 1)
optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
# 加载保存的状态
checkpoint = torch.load('checkpoint.pth')
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
scheduler.load_state_dict(checkpoint['scheduler_state_dict'])
# 恢复训练时的 epoch
epoch = checkpoint['epoch']
# 继续训练
for epoch in range(epoch, epoch + 20):
# 模拟一次训练
optimizer.step()
scheduler.step()
解释
-
保存状态
torch.save
保存了模型、优化器和调度器的状态,包括学习率调度器的状态(如step_size
和gamma
)。scheduler.state_dict()
保存了调度器的内部状态,比如当前的步数和其他参数。
-
恢复状态
torch.load
加载了之前保存的状态字典。model.load_state_dict
,optimizer.load_state_dict
, 和scheduler.load_state_dict
恢复了模型、优化器和调度器的状态。- 恢复后的调度器可以继续从之前的状态中调整学习率。
这样做可以确保在恢复训练时,调度器的学习率调整策略和状态保持一致,从而避免训练中断对学习率调整的影响。