关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)
torch.optim的灵活使用详解
1.基本用法:
要构建一个优化器Optimizer,必须给它一个包含参数的迭代器来优化,然后,我们可以指定特定的优化选项,
例如学习速率,重量衰减值等。
注:如果要把model放在GPU中,需要在构建一个Optimizer之前就执行model.cuda(),确保优化器里面的参数也是在GPU中。
例子:
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.9)
2.灵活的设置各层的学习率
将model中需要进行BP的层的参数送到torch.optim中,这些层不一定是连续的。
这个时候,Optimizer的参数不是一个可迭代的变量,而是一个可迭代的字典
(字典的key必须包含'params'(查看源码可以得知optimizer通过'params'访问parameters),
其他的key就是optimizer可以接受的,比如说'lr','weight_decay'),可以将这些字典构成一个list,
这样就是一个可迭代的字典了。
注:这个时候,可以在optimizer设置选项作为关键字参数传递,这时它们将被认为是默认值(当字典里面没有这个关键字参数key-value对时,就使用这个默认的参数)
Thisisusefulwhenyouonlywanttovaryasingleoption,whilekeepingallothersconsistentbetweenparametergroups.
例子:
optimizer=SGD([ {'params':model.features12.parameters(),'lr':1e-2}, {'params':model.features22.parameters()}, {'params':model.features32.parameters()}, {'params':model.features42.parameters()}, {'params':model.features52.parameters()}, ],weight_decay1=5e-4,lr=1e-1,momentum=0.9)
上面创建的optim.SGD类型的Optimizer,lr默认值为1e-1,momentum默认值为0.9。features12的参数学习率为1e-2。
灵活更改各层的学习率
torch.optim.optimizer.Optimizer的初始化函数如下:
__init__(self,params,lr=
,momentum=0,dampening=0,weight_decay=0,nesterov=False)
params(iterable):iterableofparameterstooptimizeordictsdefiningparametergroups(params可以是可迭代的参数,或者一个定义参数组的字典,如上所示,字典的键值包括:params,lr,momentum,dampening,weight_decay,nesterov)
想要改变各层的学习率,可以访问optimizer的param_groups属性。type(optimizer.param_groups)->list
optimizer.param_groups[0].keys() Out[21]:['dampening','nesterov','params','lr','weight_decay','momentum']
因此,想要更改某层参数的学习率,可以访问optimizer.param_groups,指定某个索引更改'lr'参数就可以。
defadjust_learning_rate(optimizer,decay_rate=0.9): forparainoptimizer.param_groups: para['lr']=para['lr']*decay_rate
重写torch.optim,加上L1正则
查看torch.optim.SGD等Optimizer的源码,发现没有L1正则的选项,而L1正则更容易得到稀疏解。
这个时候,可以更改/home/smiles/anaconda2/lib/python2.7/site-packages/torch/optim/sgd.py文件,模拟L2正则化的操作。
L1正则化求导如下:
dw=1*sign(w)
更改后的sgd.py如下:
importtorch fromtorch.optim.optimizerimportOptimizer,required classSGD(Optimizer): def__init__(self,params,lr=required,momentum=0,dampening=0, weight_decay1=0,weight_decay2=0,nesterov=False): defaults=dict(lr=lr,momentum=momentum,dampening=dampening, weight_decay1=weight_decay1,weight_decay2=weight_decay2,nesterov=nesterov) ifnesterovand(momentum<=0ordampening!=0): raiseValueError("Nesterovmomentumrequiresamomentumandzerodampening") super(SGD,self).__init__(params,defaults) def__setstate__(self,state): super(SGD,self).__setstate__(state) forgroupinself.param_groups: group.setdefault('nesterov',False) defstep(self,closure=None): """Performsasingleoptimizationstep. Arguments: closure(callable,optional):Aclosurethatreevaluatesthemodel andreturnstheloss. """ loss=None ifclosureisnotNone: loss=closure() forgroupinself.param_groups: weight_decay1=group['weight_decay1'] weight_decay2=group['weight_decay2'] momentum=group['momentum'] dampening=group['dampening'] nesterov=group['nesterov'] forpingroup['params']: ifp.gradisNone: continue d_p=p.grad.data ifweight_decay1!=0: d_p.add_(weight_decay1,torch.sign(p.data)) ifweight_decay2!=0: d_p.add_(weight_decay2,p.data) ifmomentum!=0: param_state=self.state[p] if'momentum_buffer'notinparam_state: buf=param_state['momentum_buffer']=torch.zeros_like(p.data) buf.mul_(momentum).add_(d_p) else: buf=param_state['momentum_buffer'] buf.mul_(momentum).add_(1-dampening,d_p) ifnesterov: d_p=d_p.add(momentum,buf) else: d_p=buf p.data.add_(-group['lr'],d_p) returnloss
一个使用的例子:
optimizer=SGD([ {'params':model.features12.parameters()}, {'params':model.features22.parameters()}, {'params':model.features32.parameters()}, {'params':model.features42.parameters()}, {'params':model.features52.parameters()}, ],weight_decay1=5e-4,lr=1e-1,momentum=0.9)
以上这篇关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。