目录

  • 前言
  • 一、optimizer.zero_grad()
  • 二、 loss.backward()
  • 三、optimizer.step()

前言

在用pytorch训练模型时,通常会在遍历epochs的过程中依次用到 optimizer.zero_grad(), loss.backward()optimizer.step() 三个函数,如下所示:

model = MyModel()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-4)for epoch in range(1, epochs):for i, (inputs, labels) in enumerate(train_loader):output= model(inputs)loss = criterion(output, labels)# compute gradient and do SGD stepoptimizer.zero_grad()loss.backward()optimizer.step()

总得来说,这三个函数的作用是先将梯度归零(optimizer.zero_grad()),然后反向传播计算得到每个参数的梯度(loss.backward()),最后通过梯度下降执行一步参数更新(optimizer.step())

接下来将通过源码分别理解这三个函数的具体实现过程。在此之前,先简要说明一下函数中常用到的参数变量:

param_groups: Optimizer类在实例化时会在构造函数中创建一个param_groups列表,列表中有num_groups个长度为6的param_group字典,包含了 [‘params’, ‘lr’, ‘momentum’, ‘dampening’, ‘weight_decay’, ‘nesterov’] 这6组键值对。

param_group[‘params’]: 由模型参数组成的列表,模型参数即为实例化Optimizer类时传入的model.parameters(),每个参数是一个torch.nn.parameter.Parameter对象。

一、optimizer.zero_grad()

代码如下(示例):

def zero_grad(self):r"""Clears the gradients of all optimized :class:`torch.Tensor` s."""for group in self.param_groups:for p in group['params']:if p.grad is not None:p.grad.detach_()p.grad.zero_()

optimizer.zero_grad()函数会遍历模型的所有参数,通过p.grad.detach_()方法截断反向传播的梯度流,再通过p.grad.zero_()函数将每个参数的梯度值设为0,即上一次的梯度记录被清空。

因为训练的过程通常使用mini-batch方法,调用backward()函数之前都要将梯度清零,因为如果梯度不清零,pytorch中会将上次计算的梯度和本次计算的梯度累加。

这样逻辑的好处是:当我们的硬件限制不能使用更大的bachsize时,使用多次计算较小的bachsize的梯度平均值来代替,更方便。

坏处当然是:每次都要清零梯度总结就是进来一个batch的数据,计算一次梯度,更新一次网络。

总结:

  1. 常规情况下,每个batch需要调用一次optimizer.zero_grad()函数,把参数的梯度清零;
  2. 也可以多个batch只调用一次optimizer.zero_grad()函数,这样相当于增大了batch_size。

二、 loss.backward()

PyTorch的反向传播(即tensor.backward())是通过autograd包来实现的,autograd包会根据tensor进行过的数学运算来自动计算其对应的梯度。

具体来说,torch.tensor是autograd包的基础类,如果你设置tensor的requires_grads为True,就会开始跟踪这个tensor上面的所有运算。如果你做完运算后使用tensor.backward(),所有的梯度就会自动运算,tensor的梯度将会累加到它的.grad属性里面去。因此,如果没有进行tensor.backward()的话,梯度值将会是None,因此loss.backward()要写在optimizer.step()之前。

三、optimizer.step()

以SGD为例,torch.optim.SGD().step()源码如下::

def step(self, closure=None):"""Performs a single optimization step.Arguments:closure (callable, optional): A closure that reevaluates the modeland returns the loss."""loss = Noneif closure is not None:loss = closure()for group in self.param_groups:weight_decay = group['weight_decay']momentum = group['momentum']dampening = group['dampening']nesterov = group['nesterov']for p in group['params']:if p.grad is None:continued_p = p.grad.dataif weight_decay != 0:d_p.add_(weight_decay, p.data)if momentum != 0:param_state = self.state[p]if 'momentum_buffer' not in param_state:buf = param_state['momentum_buffer'] = torch.clone(d_p).detach()else:buf = param_state['momentum_buffer']buf.mul_(momentum).add_(1 - dampening, d_p)if nesterov:d_p = d_p.add(momentum, buf)else:d_p = bufp.data.add_(-group['lr'], d_p)return loss

step()函数的作用是执行一次优化步骤,通过梯度下降法来更新参数的值。因为梯度下降是基于梯度的,所以 在执行optimizer.step()函数前应先执行loss.backward()函数来计算梯度。


optimizer.zero_grad(),loss.backward(),optimizer.step()的作用原理相关推荐

  1. 理解optimizer.zero_grad(), loss.backward(), optimizer.step()的作用及原理

    在用pytorch训练模型时,通常会在遍历epochs的过程中依次用到optimizer.zero_grad(),loss.backward()和optimizer.step()三个函数,如下所示: ...

  2. optimizer.zero_grad(), loss.backward(), optimizer.step()的理解及使用

    optimizer.zero_grad,loss.backward,optimizer.step 用法介绍 optimizer.zero_grad(): loss.backward(): optimi ...

  3. 梯度值与参数更新optimizer.zero_grad(),loss.backward、和optimizer.step()、lr_scheduler.step原理解析

    在用pytorch训练模型时,通常会在遍历epochs的过程中依次用到optimizer.zero_grad(),loss.backward.和optimizer.step().lr_schedule ...

  4. Pytorch:optim.zero_grad()、pred=model(input)、loss=criterion(pred,tgt)、loss.backward()、optim.step()的作用

    在用pytorch训练模型时,通常会在遍历epochs的每一轮batach的过程中依次用到以下三个函数 optimizer.zero_grad(): loss.backward(): optimize ...

  5. Loss.backward()

    若只有一个loss outputs = model(inputs) loss = criterrion(outputs,target)optimizer.zero_grad() loss.backwa ...

  6. pytorch-->optimizer.zero_grad()、loss.backward()、optimizer.step()和scheduler.step()

    优化器optimizer的作用 优化器就是需要根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数值的作用. 一般来说,以下三个函数的使用顺序如下: # compute gradient ...

  7. loss.backward(),scheduler(), optimizer.step()的作用

    在用pytorch训练模型时(pytorch1.1及以上版本),通常会在遍历epochs的过程中依次用到optimizer.zero_grad(),loss.backward()和optimizer. ...

  8. Pytorch中的optimizer.zero_grad和loss和net.backward和optimizer.step的理解

    引言 一般训练神经网络,总是逃不开optimizer.zero_grad之后是loss(后面有的时候还会写forward,看你网络怎么写了)之后是是net.backward之后是optimizer.s ...

  9. model.train()、model.eval()、optimizer.zero_grad()、loss.backward()、optimizer.step作用及原理详解【Pytorch入门手册】

    1. model.train() model.train()的作用是启用 Batch Normalization 和 Dropout. 如果模型中有BN层(Batch Normalization)和D ...

最新文章

  1. webpy + nginx + fastcgi 构建python应用
  2. hibernate延迟加载(get和load的区别)
  3. oracle:ORA-01940无法删除当前已连接用户的解决方案
  4. 【数据结构与算法】之深入解析“H指数II”的求解思路与算法示例
  5. 桌面快速启动软件AltRun----赶快使得你的桌面变整洁吧
  6. 算法分析设计--递归算法
  7. a76比a73强多少_arm的a73和a72同上10nm,谁强?
  8. 常见的 HTTP 状态代码及原因
  9. Windows下使用VS2008+CUDA3.0开发的详细配置 (Setup CUDA 3.0 on VS2008 in Windows)
  10. 遇到不可重现问题怎么办
  11. 关于hadoop2.4.1伪分布式系统的搭建
  12. 控制器发生异常 eofexception_关于气动薄膜调节阀常发生的故障你可能还不知道...
  13. 基于Scikit-Learn进行命名实体识别和分类
  14. 【字幕制作】生肉资源的字幕问题解决经验分享 入门科普/一键机翻/在线识别/内嵌封装
  15. 三年经验前端vue面试记录
  16. 华为MateBook14s更换固态(系统无缝衔接,等价于官方镜像)
  17. 微信的9个隐藏功能,我不允许还有人不知道!
  18. ubutnu18.04 华硕天选2060 未发现WIFI适配器(问题尚未解决)
  19. oracle yum配置本地源,oel 7 本地yum源配置
  20. kafka-eagle-2.0.1安装及使用(超详细)

热门文章

  1. 【提升技能必备】这几本Android高级进阶的好书值得一看
  2. FPGA基本逻辑单元
  3. CTFHub技能树之密码口令
  4. [vue]8-vue组件1
  5. 【多元】多元正态分布,聚类分析
  6. ORB特征提取和匹配
  7. 联想Y7000、R720系列蓝屏死机解决方案
  8. MathType怎么设置下一章公式编号?MathType怎么按章节对公式编号?
  9. 用Python来看3天破10亿的《我不是药神》到底神在哪?
  10. 迷宫问题-DFS-BFS