关于optimizer优化器与scheduler策略调整器

关于optimizer优化器与scheduler策略调整器

optimizer优化器:

optimizer = torch.optim.SGD(model.parameters(),
                       args.lr,
                       momentum=args.momentum, nesterov=args.nesterov,
                       weight_decay=args.weight_decay)

上面是SGD优化器的一个使用实例,经过实例化后,optimizer会产生一个列表param_groups,列表中的每个元素param_group是一个字典,以param_group[‘params’]的形式对应model.parameters()的每一层参数,除此之外,还以param_group[‘lr’]的形式对应上面的args.lr等等。

如下所示:

for name, param in model.named_parameters():
    if 'fc' in name or 'class' in name or 'last_linear' in name or 'ca' in name or 'sa' in name:
        parameters.append({'params': param, 'lr': args.lr * args.lr_fc_times})
    else:
        parameters.append({'params': param, 'lr': args.lr})

optimizer = torch.optim.SGD(parameters,
                            args.lr,
                            momentum=args.momentum, nesterov=args.nesterov,
                            weight_decay=args.weight_decay)

这时,传入的参数parameters已经是一个字典列表,他的每个元素parameter已经包括了parameter[‘lr’]了,这时候实例化SGD时传入的args.lr就不会起作用了(传入的lr只在字典中没有lr键值的时候会创建并传入,当字典已经有键值及对应元素后,会跳过),所以这种情况下,每层参数的学习率实际上已经由之前定好的学习率设定好了,args.lr只是一个摆设,不起实际作用。

上述情况通常发生在,对已有预训练网络进行微调后,网络改动部分往往需要更大的学习率,因此整个网络来说,学习率不是完全一样的,需要针对不同层设计不同的学习率,这时通过初始化SGD时传入初始学习率的一刀切办法就不适用了。

调用optimizer.step()即可实现网络参数的更新

scheduler策略调整器

这里有一篇比较好的博客,介绍的挺好

举个例子,如下:

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)

将optimizer作为参数传递给scheduler,每次通过调用scheduler.step()就会更新optimizer中每一个param_group[‘lr’],具体更新策略是什么呢?对于StepLR策略调整器来说, l r n e w = l r i n i t i a l ∗ g a m m a e p o c h / / s t e p s i z e lr_{new} = lr_{initial} * gamma^{epoch//stepsize} lrnew=lrinitialgammaepoch//stepsize,即每过固定个epoch,学习率会按照gamma倍率进行衰减。

也可以不使用scheduler策略调整器,就实现optimizer的学习率调整,如下:

def adjust_learning_rate(optimizer, epoch, step_size, lr_init, gamma):
    factor = epoch // step_size
    lr = lr_init * (gamma ** factor)
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

相当于手动修改optimizer中的param_group[‘lr’],使用时调用函数如下:

adjust_learning_rate(optimizer, epoch, args.step_size, args.lr, args.gamma)

注意:pytorch1.1之后,scheduler.step()调用需要在optimizer.step()之后

你可能感兴趣的:(关于optimizer优化器与scheduler策略调整器)