pytorch的优化器optimizer使用方法,主要介绍如何更改学习率,查看参数,若学会将有利于我们可使用模型调整学习策略等
使用 torch.optim
创建一个optim 对象,这个对象会一直保持当前状态或根据计算的梯度更新参数。
也是模型搭建模块梯度走向,是模型迭代至关重要一部分。因此,本文为每个模块自由设计学习率等参数问题进行探讨。
本文首先给出探讨问题及结论,然后分别解释探讨问题,具体如下:
一、探究问题:
①分模块设计不同参数
②优化器如何自由添加自己参数与保留重要信息
③整体模型如何设计
结果:若设置模块,则按照模块参数更新此模块,若未设置模块,则按照总体参数更新。
二、定义介绍
基本定义:torch.optim
是一个实现了各种优化算法的库。大部分常用的方法得到支持,并且接口具备足够的通用性,使得未来能够集成更加复杂的方法。
构建优化器:构建优化器可选择optim自定义的方法,一般也是调用其中的,如下可构建:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001) # [var1, var2] 可理解为优化的变量 lr = 0.0001为梯度下降的学习率,其它未设置表示默认
三、模块自由设计参数
深度理解:若你构建了网络模型model,若你想给不同模块设置不同学习率,将可以采取以下方法:
optimizer = optim.SGD([ {'params': model.base.parameters()}, {'params': model.classifier.parameters(), 'lr': 1e-3} ], lr=1e-2, momentum=0.9)
以上optim.SGD()中的列表就是构建每个参数的学习率,若没有设置,则默认使用最外如:model.base.parameters()参数使用lr=1e-2 momentum=0.9
四、自由添加或更改参数
添加个人需要的变量:
若你想添加个人变量保存optimizer中,可使用:
for b in optimizer.param_groups:
b.setdefault('init_lr', 0.02)
此时类似optimizer = optim.SGD([ {'params': model.base.parameters()}, {'params': model.classifier.parameters(), 'lr': 1e-3} ],init_lr=0.02, lr=1e-2, momentum=0.9)
若你想更改学习率,可使用:
for b in optimizer.param_groups:
b.setdefault('init_lr', 0.00005)
此时类似将optimizer = optim.SGD([ model.base.parameters(), lr=0.02, momentum=0.9) 变成
optimizer = optim.SGD([model.base.parameters(), lr=0.00005, momentum=0.9)
注:可理解optimezer已经保存了模型model需要使用的学习率参数。
五、优化器查看方法
查看优化器参数:
optimizer.param_groups[0]: 长度为6的字典,包括[‘amsgrad’, ‘params’, ‘lr’, ‘betas’, ‘weight_decay’, ‘eps’]这6个参数;
optimizer.param_groups[1]: 好像是表示优化器的状态的一个字典;
六、模型使用优化器方法
模型训练优化器一般方法使用:
大多数optimizer所支持的简化版本。一旦梯度被如backward()
之类的函数计算好后,我们就可以调用这个函数
for input, target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
深入用法:
optimizer.step(closure)
一些优化算法例如Conjugate Gradient和LBFGS需要重复多次计算函数,因此你需要传入一个闭包去允许它们重新计算你的模型。这个闭包应当清空梯度, 计算损失,然后返回。
for input, target in dataset:
def closure():
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
return loss optimizer.step(closure)
七 、模型设置参数方法
2022年02月28日新增模型自由设置参数函数代码
import torch.nn as nn
import torch
class module(nn.Module):
def __init__(self):
super(module, self).__init__()
self.features = nn.Conv2d(in_channels=3, out_channels=64, stride=1, kernel_size=3, padding=1,bias=False)
self.classifiter = nn.Conv2d(in_channels=64, out_channels=128, stride=1, kernel_size=3, padding=1,bias=True)
self.relu = nn.ReLU()
def forward(self, x):
x = self.features(x)
x = self.classifiter(x)
return self.relu(x)
if __name__ == '__main__':
net=module()
optimizer = torch.optim.SGD([{'params': net.features.weight, 'lr': 0.1},
# {'params': net.features.bias, 'lr': 0.3},
{'params': net.classifiter.weight},
{'params': net.classifiter.bias,'lr':0.9}
], lr=0.5)
print(optimizer)
2022年02月28日新增模型不同模块的学习相关参数设定代码,如学习率lr
def sgd_optimizer(cfg, resrep_config:ResRepConfig, model, no_l2_keywords, use_nesterov, keyword_to_lr_mult):
params = []
for key, value in model.named_parameters():
if not value.requires_grad:
continue
lr = cfg.base_lr
weight_decay = cfg.weight_decay
if "bias" in key or "bn" in key or "BN" in key:
weight_decay = cfg.weight_decay_bias
print('set weight_decay_bias={} for {}'.format(weight_decay, key))
for kw in no_l2_keywords:
if kw in key:
weight_decay = 0
print('NOTICE! weight decay = 0 for ', key, 'because {} in {}'.format(kw, key))
break
if 'bias' in key:
apply_lr = 2 * lr
else:
apply_lr = lr
if keyword_to_lr_mult is not None:
for keyword, mult in keyword_to_lr_mult.items():
if keyword in key:
apply_lr *= mult
print('multiply lr of {} by {}'.format(key, mult))
break
if 'compactor' in key:
use_momentum = resrep_config.compactor_momentum
print('momentum {} for {}'.format(use_momentum, key))
else:
use_momentum = cfg.momentum
params += [{"params": [value], "lr": apply_lr, "weight_decay": weight_decay, "momentum": use_momentum}] # 每一层使用不同的参数
optimizer = torch.optim.SGD(params, lr, momentum=cfg.momentum, nesterov=use_nesterov)
return optimizer