聊聊pytorch中Optimizer与optimizer.step()的用法_第1页
聊聊pytorch中Optimizer与optimizer.step()的用法_第2页
聊聊pytorch中Optimizer与optimizer.step()的用法_第3页
聊聊pytorch中Optimizer与optimizer.step()的用法_第4页
聊聊pytorch中Optimizer与optimizer.step()的用法_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第聊聊pytorch中Optimizer与optimizer.step()的用法{'params':model.base.parameters()},

{'params':model.classifier.parameters(),'lr':1e-3}

],lr=1e-2,momentum=0.9)

这意味着model.base的参数将会使用1e-2的学习率,model.classifier的参数将会使用1e-3的学习率,并且0.9的momentum将会被用于所有的参数。

进行单次优化

所有的optimizer都实现了step()方法,这个方法会更新所有的参数。它能按两种方式来使用:

optimizer.step()

这是大多数optimizer所支持的简化版本。一旦梯度被如backward()之类的函数计算好后,我们就可以调用这个函数。

forinput,targetindataset:

optimizer.zero_grad()

output=model(input)

loss=loss_fn(output,target)

loss.backward()

optimizer.step()

optimizer.step(closure)

一些优化算法例如ConjugateGradient和LBFGS需要重复多次计算函数,因此你需要传入一个闭包去允许它们重新计算你的模型。这个闭包应当清空梯度,计算损失,然后返回。

forinput,targetindataset:

defclosure():

optimizer.zero_grad()

output=model(input)

loss=loss_fn(output,target)

loss.backward()

returnloss

optimizer.step(closure)

补充:Pytorchoptimizer.step()和loss.backward()和scheduler.step()的关系与区别

首先需要明确optimzier优化器的作用,形象地来说,优化器就是需要根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用,这也是机器学习里面最一般的方法论。

从优化器的作用出发,要使得优化器能够起作用,需要主要两个东西:

1.优化器需要知道当前的网络或者别的什么模型的参数空间

这也就是为什么在训练文件中,正式开始训练之前需要将网络的参数放到优化器里面,比如使用pytorch的话总会出现类似如下的代码:

optimizer_G=Adam(model_G.parameters(),lr=train_c.lr_G)#lr使用的是初始lr

optimizer_D=Adam(model_D.parameters(),lr=train_c.lr_D)

2.需要知道反向传播的梯度信息

我们还是从代码入手,如下所示是Pytorch中SGD优化算法的step()函数具体写法,具体SGD的写法放在参考部分。

defstep(self,closure=None):

"""Performsasingleoptimizationstep.

Arguments:

closure(callable,optional):Aclosurethatreevaluatesthemodel

andreturnstheloss.

loss=None

ifclosureisnotNone:

loss=closure()

forgroupinself.param_groups:

weight_decay=group['weight_decay']

momentum=group['momentum']

dampening=group['dampening']

nesterov=group['nesterov']

forpingroup['params']:

ifp.gradisNone:

continue

d_p=p.grad.data

ifweight_decay!=0:

d_p.add_(weight_decay,p.data)

ifmomentum!=0:

param_state=self.state[p]

if'momentum_buffer'notinparam_state:

buf=param_state['momentum_buffer']=d_p.clone()

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

从上面的代码可以看到step这个函数使用的是参数空间(param_groups)中的grad,也就是当前参数空间对应的梯度,这也就解释了为什么optimzier使用之前需要zero清零一下,因为如果不清零,那么使用的这个grad就得同上一个mini-batch有关,这不是我们需要的结果。

再回过头来看,我们知道optimizer更新参数空间需要基于反向梯度,因此,当调用optimizer.step()的时候应当是loss.backward()的时候,这也就是经常会碰到,如下情况

total_loss.backward()

optimizer_G.step()

loss.backward()在前,然后跟一个step。

那么为什么optimizer.step()需要放在每一个batch训练中,而不是epoch训练中,这是因为现在的mini-batch训练模式是假定每一个训练集就只有mini-batch这样大,因此实际上可以将每一次mini-batch看做是一次训练,一次训练更新一次参数空间,因而optimizer.step()放在这里。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论