pytorch使用恢复训练方法,学习率调整策略失效

使用断点训练 恢复训练 学习率调整策略失效又从头开始了,学习率不再是上一个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结束后进行。

学习率调整器未正确绑定优化器:确保你将学习率调整器与正确的优化器绑定。学习率调整器的构造函数应接受优化器的参数。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7510155
  • 这篇博客你也可以参考下:Pytorch中,动态调整学习率、不同层设置不同学习率和固定某些层训练的方法
  • 同时,你还可以查看手册:pytorch 学习基础知识 中的内容
  • 除此之外, 这篇博客: PyTorch模型训练完毕后静态量化、保存、加载int8量化模型中的 4. 量化模型加载进行推理 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    注意:量化后模型的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()
  • 您还可以看一下 日月光华老师的PyTorch深度学习简明教程课程中的 收入数据集读取与观察小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    首先,要正确使用断点训练方法,你可以按照以下步骤进行操作:

    1. 定义网络模型及读入预训练模型: 你可以使用PyTorch提供的网络定义模型的backbone,然后根据你的任务设置backbone最后一层的参数。同时,读入你自己任务需要的预训练模型。代码示例如下:
    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)
    
    1. 加载数据集并定义训练过程: 在断点训练中,通常需要使用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()
    

    接下来,解决学习率调整策略失效的问题,你可以按照以下步骤进行操作:

    1. 确保学习率调整策略正确设置: 要调整学习率,你可以使用PyTorch提供的优化器(如torch.optim.SGD)并设置合适的学习率和其他超参数。例如,你可以使用torch.optim.lr_scheduler来设置学习率调整策略,如torch.optim.lr_scheduler.StepLRtorch.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倍
    
    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'))
    

    通过以上步骤,你应该可以正确使用断点训练方法,并解决学习率调整策略失效的问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^