使用断点训练 恢复训练 学习率调整策略失效又从头开始了,学习率不再是上一个epoch时的学习率 变成了一开始的学习率.
在PyTorch中,恢复训练时,可以使用以下方法来调整学习率:
1.使用torch.optim.lr_scheduler模块:PyTorch提供了torch.optim.lr_scheduler模块,其中包含了各种学习率调整策略。你可以选择适合你的模型和数据集的学习率调整器,并在每个epoch或一定的步数后更新学习率。
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
# 定义优化器和学习率调整器
optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = StepLR(optimizer, step_size=10, gamma=0.1)
# 训练循环中的每个epoch或一定的步数后更新学习率
for epoch in range(num_epochs):
# 训练模型
...
# 更新学习率
scheduler.step()
在上面的代码中,StepLR调度器会在每个step_size步后将学习率乘以gamma,以实现学习率的衰减。
2.手动调整学习率:如果你对学习率调整策略有更精细的控制需求,你可以在训练循环中手动调整学习率,根据你的需求更新优化器的学习率。
import torch.optim as optim
# 定义优化器和初始学习率
optimizer = optim.SGD(model.parameters(), lr=0.1)
initial_lr = 0.1
# 训练循环中的每个epoch或一定的步数后更新学习率
for epoch in range(num_epochs):
# 训练模型
...
# 根据你的需求更新学习率
lr = initial_lr * 0.1 ** (epoch // 10) # 自定义学习率衰减策略
for param_group in optimizer.param_groups:
param_group['lr'] = lr
在上面的代码中,我们根据自定义的学习率衰减策略,每10个epoch将学习率除以10。
如果以上方法都无效,可能有以下原因:
学习率调整的位置不正确:确保你在每个epoch或一定的步数后调用学习率调整器或手动更新学习率。学习率调整应在每个epoch周期末尾或每个batch结束后进行。
学习率调整器未正确绑定优化器:确保你将学习率调整器与正确的优化器绑定。学习率调整器的构造函数应接受优化器的参数。
不知道你这个问题是否已经解决, 如果还没有解决的话:注意:量化后模型的forward代码稍有改动,需要在模型输入前后安插量化和解量化。如下示例:
class Net(nn.Module):
def __init__(self):
# 对输入数据量化
self.quant = torch.quantization.QuantStub()
# model structure.
layer = self.layer()
# 对输出数据解量化
self.dequant = torch.quantization.DeQuantStub()
def forward(self,input):
x = self.quant(input)
x = self.layer(x)
x = self.dequant(x)
量化和解量化在pose_estimation.py文件34-86行可以看到.
加载int8模型不能和之前加载float32模型一样,需要将模型通过prepare() , convert()操作转成量化模型,然后load_state_dict加载进模型。
# Load int8 model
state_dict = torch.load('./openpose_vgg_quant.pth')
model_fp32 = get_pose_model()
model_fp32.qconfig = torch.quantization.get_default_qconfig('fbgemm')
model_fp32_prepared = torch.quantization.prepare(model_fp32)
model_int8 = torch.quantization.convert(model_fp32_prepared)
model_int8.load_state_dict(state_dict)
model = model_int8
model.eval()
首先,要正确使用断点训练方法,你可以按照以下步骤进行操作:
import torch
import torchvision.models
from torch import nn
model = torchvision.models.resnet50(pretrained=False) # PyTorch提供的网络结构,不加载官方预训练模型(ImageNet)
fc_features = model.fc.in_features # 提取fc层中固定的参数
model.fc = nn.Linear(fc_features, 400) # 修改为自己项目的类别数量(也即预训练模型的类别数)
# 读入自己需要的预训练模型
pthfile = 'tf_model_zoo/tsn2d_kinetics400_rgb_r50_seg3_f1s1-b702e12f.pth' # ResNet50,Kinetics400
pretrained_model = torch.load(pthfile)
model.train()
将模型切换到训练状态,并遍历数据集进行训练。同时,你可以使用optimizer.zero_grad()
清空所有优化过的梯度,然后将当前遍历的数据输入到模型中得到预测的结果,并使用定义的损失函数计算预测结果与真实标签的loss。最后,使用反向传播和优化器的step()
函数进行模型参数更新。具体示例代码如下:def train(args, model, device, train_loader, optimizer, epoch):
# 切换到train状态
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
# 从数据集获取数据以及对应标签
data, target = data.to(device), target.to(device)
# 清空所有优化过的梯度
optimizer.zero_grad()
# 执行模型forward
output = model(data)
# 计算损失
loss = torch.nn.functional.nll_loss(output, target)
# 反向传播
loss.backward()
# 优化模型参数
optimizer.step()
接下来,解决学习率调整策略失效的问题,你可以按照以下步骤进行操作:
torch.optim.SGD
)并设置合适的学习率和其他超参数。例如,你可以使用torch.optim.lr_scheduler
来设置学习率调整策略,如torch.optim.lr_scheduler.StepLR
或torch.optim.lr_scheduler.MultiStepLR
等。示例代码如下:import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = StepLR(optimizer, step_size=10, gamma=0.1) # 每10个epoch将学习率减小为原来的0.1倍
optimizer.load_state_dict()
加载优化器状态,使用scheduler.load_state_dict()
加载学习率调整策略的状态。示例代码如下:# 恢复模型训练前保存的优化器和学习率调整策略状态
optimizer.load_state_dict(torch.load('optimizer.pt'))
scheduler.load_state_dict(torch.load('scheduler.pt'))
通过以上步骤,你应该可以正确使用断点训练方法,并解决学习率调整策略失效的问题。