学习笔记——关于学习率、权值保存加载

首先感谢网上的诸位大佬写的博客,让我能够较快的获取到所需要的知识!

深度学习相关————学习笔记(1)

关于学习率(lr)调整的问题

#首先进行模型的定义
model  =  XXNet()

#学习率(learing rate)
lr = 1e-4
#优化器(optimizer)
optimizer = torch.optim.Aadm(model.parameters(),lr)
#torch.optim.lr_scheduler 提供了使得学习率(lr)能够随着训练的代数变化而变化的几种方法

#1.StepLR : 每经过step_size个epoch,做一次更新
lr_scheduler = optim.lr_scheduler.StepLR(optimizer,step_size=1,gamma=0.95)

#2.LambdaLR : new_lr=λ×initial_lr; 
# initial_lr 是初始的学习率,λ是通过参数lr_lambda(function or list)和epoch得到的。
lr_scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1)

#3.MultiStepLR : 
lr_scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1)

#4.CosineAnnealingLR
lr_scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1)
参数:last_epoch=-1
last_epoch (int):最后一个epoch的index,如果是训练了很多个epoch后中断了,继续训练,这个值就等于加载的模型的epoch。
默认为-1表示从头开始训练,即从epoch=1开始。

note:

在将optimizer传给scheduler后,在shcduler类的__init__方法中会给optimizer.param_groups列表中的那个元素(字典)增加一个key = "initial_lr"的元素表示初始学习率,等于optimizer.defaults['lr']。

param_groups:Optimizer类在实例化时会在构造函数中创建一个param_groups列表,列表中有num_groups个长度为6的param_group字典(num_groups取决于你定义optimizer时传入了几组参数),每个param_group包含了 ['params', 'lr', 'momentum', 'dampening', 'weight_decay', 'nesterov'] 这6组键值对。

于是就可以通过

optimizer.param_groups[0]['lr']

得到当前的学习率。

对于StepLR :

其中new_lr是得到的新的学习率,initial_lr是初始的学习率,step_size是参数step_size,γ 是参数gamma。

eg: 
lr_scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=0.95, last_epoch=-1)

对于MultiStepLR:

其中new_lr是得到的新的学习率,initial_lr是初始的学习率,γ 是参数gamma,bisect_right(milestones,epoch)就是bisect模块中的bisect_right函数,返回值是把epoch插入排序好的列表milestones式的位置。

eg:
lr_scheduler  = optim.lr_scheduler.MultiStepLR(optimizer, milestones=[round(config['training']['epochs'] * x) for x in [0.8, 0.9]])

对于CosineAnnealingLR

其中new_lr是得到的新的学习率,initial_lr是初始的学习率,eta_min是参数eta_min表示最小学习率,T_max是参数T_max表示cos的周期的1/4。

效果如下图所示:

#训练模板:
for epoch in range(0,epochs):
    train()
    val()
    lr_scheduler.step() #调整

def train():
    net.train()
    for i, (image, label) in enumerate(train_dataloader):
        if cuda:
            image = image.cuda()
            label = label.cuda()
        optimizer.zero_grad()#梯度归零
        
        output = net(image)
        loss = Loss(outputs, label)
        
        loss.backward()#反向传播计算得到的每个参数的梯度值
        optimizer.step()#通过梯度下降执行一步参数更新
        ......
def val():
    net.eval()
    for i, (image, label) in enumerate(val_dataloader):
        if cuda:
            image = image.cuda()
            label = label.cuda()
        loss = Loss()
        output = net(image)
        loss = Loss(outputs, label)
        ......
   

with torch.no_grad()

torch.no_grad() 是一个上下文管理器,被该语句 wrap (包)起来的部分将不会track 梯度。但是计算依旧正常计算。

权值文件保存问题

[pytorch官方教程](([Saving and Loading Models — PyTorch Tutorials 1.9.0+cu102 documentation)(https://pytorch.org/tutorials/beginner/saving_loading_models.html))

torch.save()

保存:

torch.save(state, filename)
#state 是一个字典 {}
#filename 是存储地址,可以是绝对路径也可以是相对路径  'xxx.pth'

eg:
torch.save({
			'epoch':epoch,
             'model_state_dict':model.state_dict(),
             'optimizer_state_dict':optimizer.state_dict(),
             'best_pred':new_pred,
			},filename)

#保存最新模型与最佳模型
def save_checkpoint(self, state, is_best, filename='checkpoint.pth.tar'):
	filename = os.path.join(path, filename)
	torch.save(state, filename) #保存最新模型
    with open(os.path.join(path, 'best_pred.txt'), 'w') as f:
                f.write(str(best_pred))   #记录最佳指标
	if is_best:
		best_pred = state['best_pred']  #在分割里 这个可以是mIoU
		copy_filename = os.path.join(path, "copy/", str(state['epoch']) + 'checkpoint_best.pth.tar')
        torch.save(state, copy_filename)
    #或者
    if is_best:
        shutil.copyfile(filename, 'model_best.pth.tar')

torch.load()

加载:

#恢复训练前置条件:
#1. model  = net()
#2. optimizer = torch.optim.Adam(model.parameters(),lr)
#3. lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,step_size=1,gamma=0.95)

#接下来:
checkpoint = torch.load(filename)
continue_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
BEST_miou = checkpoint['best_pred']
end_epoch = continue_epoch + 30  #eg

for epoch in range(continue_epoch, end_epoch):
    train()
    val()
    lr_scheduler.step()

需要注意的是:

PyTorch报错:XXX is a zip archive(did you mean to use torch.jit.load()?)

从torch版本1.6.0之后,训练模型的保存都是默认使用zip文件来保存权重文件,这导致这些权重文件无法直接被1.5及以下的pytorch加载。

解决办法:

在PyTorch1.6或更高版本的PyTorch下,运行一下代码,来转换模型

state_dict = torch.load("xxx.pth")
torch.save(state_dict, "xxx.pth", _use_new_zipfile_serialization=False)

对于'xxx.pth.tar' , 加载的时候报这个错误是一样的处理办法。

posted @ 2021-07-06 20:56  不怕路远  阅读(872)  评论(0)    收藏  举报