4.16:优化器和学习率调整策略

  • checkpoint要存的东西如下:但为啥TransENet中还存了loss,查看所有.pt文件
    在这里插入图片描述
  • optimizer中存的参数是啥

选择优化器设置学习率调整策略的直接实现
4.16:优化器和学习率调整策略_第1张图片

那为什么要重写optimizerscheduler呢,如下所示:

def make_optimizer(args, my_model):
    trainable = filter(lambda x: x.requires_grad, my_model.parameters())

    if args.optimizer == 'SGD':
        optimizer_function = optim.SGD
        kwargs = {'momentum': args.momentum}
    elif args.optimizer == 'ADAM':
        optimizer_function = optim.Adam
        kwargs = {
            'betas': (args.beta1, args.beta2),
            'eps': args.epsilon
        }
    elif args.optimizer == 'RMSprop':
        optimizer_function = optim.RMSprop
        kwargs = {'eps': args.epsilon}

    kwargs['lr'] = args.lr
    kwargs['weight_decay'] = args.weight_decay

    return optimizer_function(trainable, **kwargs)


def make_scheduler(args, my_optimizer):
    if args.decay_type == 'step':
        scheduler = lrs.StepLR(
            my_optimizer,
            step_size=args.lr_decay,
            gamma=args.gamma
        )
    elif args.decay_type.find('step') >= 0:
        milestones = args.decay_type.split('_')
        milestones.pop(0)
        milestones = list(map(lambda x: int(x), milestones))
        scheduler = lrs.MultiStepLR(
            my_optimizer,
            milestones=milestones,
            gamma=args.gamma
        )

    return scheduler

然后在训练的时候调用

self.optimizer = utils.make_optimizer(args, self.model)  # 选择优化器 
self.scheduler = utils.make_scheduler(args, self.optimizer)  # 设置学习率调整策略

当然是因为想要实现更多的功能,比如:
1.在迁移学习时需要冻结部分网络层的参数,

trainable = filter(lambda x: x.requires_grad, my_model.parameters())

这一句就可以选择只给requires_grad=TRUE的参数设置优化器
2.很多参数希望用更方便的argparse传入,那就需要把可选的优化器、对应的初始化参数、学习策略相关参数等等,用args.*的形式设置为选项。自然需要重新一个函数进行包装。

Pytorch的优化器:

管理并更新模型中可学习参数的值, 使得模型输出更接近真实标签。

Pytorch里面优化器的基本属性:
4.16:优化器和学习率调整策略_第2张图片

defaults: 优化器超参数,里面会存储一些学习了, momentum的值,衰减系数等
state: 参数的缓存, 如momentum的缓存(使用前几次梯度进行平均)
param_groups: 管理的参数组, 这是个列表,每一个元素是一个字典,在字典中有key,key里面的值才是我们真正
的参数(这个很重要, 进行参数管理)
_step_count: 记录更新次数, 学习率调整中使用, 比如迭代100次之后更新学习率的时候,就得记录这里的100.

优化器里面的基本方法:

zero_grad(): 清空所管理参数的梯度, 这里注意Pytorch有一个特性就是张量梯度不自动清零
step(): 执行一步更新
add_param_group(): 添加参数组, 我们知道优化器管理很多参数,这些参数是可以分组的,我们对不同组的参数
可以设置不同的超参数, 比如模型finetune中,我们希望前面特征提取的那些层学习率小一些,
而后面我们新加的层学习率大一些更新快一点,就可以用这个方法。

state_dict(): 获取优化器当前状态信息字典
load_state_dict(): 加载状态信息字典,这两个方法用于模型断点的一个续训练, 所以我们在模型训练的时候,
一般多少个epoch之后就要保存当前的状态信息。

Pytorch的学习率调整策略:

在学习学习率调整策略之前,得先学习一个基类_LRScheduler, 因为后面的六种学习率调整策略都是继承于这个类的,所以得先明白这个类的原理:

主要属性:

optimizer: 关联的优化器, 得需要先关联一个优化器,然后再去改动学习率
last_epoch: 记录epoch数, 学习率调整以epoch为周期
base_lrs: 记录初始学习率

主要方法:

step(): 更新下一个epoch的学习率, 这个是和用户对接
get_lr(): 虚函数, 计算下一个epoch的学习率, 这是更新过程中的一个步骤

pytorch的六种学习率调整策略小结一下:

有序调整:Step、MultiStep、 Exponential和CosineAnnealing, 这些得事先知道学习率大体需要在多少个epoch之后调整的时候用
自适应调整: ReduceLROnPleateau, 这个非常实用,可以监控某个参数,根据参数的变化情况自适应调整
自定义调整:Lambda, 这个在模型的迁移中或者多个参数组不同学习策略的时候实用

总结

我们需要先知道一个复杂函数中的核心语句,其次是对它进行重写包装的目的。

小tip

断点续存可以把所有要存的放进一个字典(eg:pytorch学习笔记中的示例)也可以分别存多个.pt文件(eg:TransENet参考代码)

你可能感兴趣的:(超分辨率重建学习笔记,python)