pytorch loss反向传播出错的解决方案
作者:liguiyuan112 发布时间:2023-04-06 07:20:55
今天在使用pytorch进行训练,在运行 loss.backward() 误差反向传播时出错 :
RuntimeError: grad can be implicitly created only for scalar outputs
File "train.py", line 143, in train
loss.backward()
File "/usr/local/lib/python3.6/dist-packages/torch/tensor.py", line 198, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph)
File "/usr/local/lib/python3.6/dist-packages/torch/autograd/__init__.py", line 94, in backward
grad_tensors = _make_grads(tensors, grad_tensors)
File "/usr/local/lib/python3.6/dist-packages/torch/autograd/__init__.py", line 35, in _make_grads
raise RuntimeError("grad can be implicitly created only for scalar outputs")
RuntimeError: grad can be implicitly created only for scalar outputs
问题分析:
因为我们在执行 loss.backward() 时没带参数,这与 loss.backward(torch.Tensor(1.0)) 是相同的,参数默认就是一个标量。
但是由于自己的loss不是一个标量,而是二维的张量,所以就会报错。
解决办法:
1. 给 loss.backward() 指定传递给后向的参数维度:
loss = criterion(pred, targets)
loss.backward()
# 改为:
loss = criterion(pred, targets)
loss.backward(loss.clone().detach())
2. 修改loss函数的输出维度
把张量的输出修改为标量,比如说多多个维度的loss求和或求均值等。此方法对于某些任务不一定适用,可以尝试自己修改。
criterion = nn.L1Loss(reduction='none')
# 把参数去掉,改为:
criterion = nn.L1Loss()
这里顺便介绍一下pytorch loss函数里面 的reduction 参数
在新的pytorch版本里,使用reduction 参数取代了旧版本的size_average和reduce参数。
reduction 参数有三种选择:
'elementwise_mean':为默认情况,表明对N个样本的loss进行求平均之后返回(相当于reduce=True,size_average=True);
'sum':指对n个样本的loss求和(相当于reduce=True,size_average=False);
'none':表示直接返回n分样本的loss(相当于reduce=False)
补充:在Pytorch下,由于反向传播设置错误导致 loss不下降的原因及解决方案
在Pytorch下,由于反向传播设置错误导致 loss不下降的原因及解决方案
刚刚接触深度学习一段时间,一直在研究计算机视觉方面,现在也在尝试实现自己的idea,从中也遇见了一些问题,这次就专门写一下,自己由于在反向传播(backward)过程中参数没有设置好,而导致的loss不下降的原因。
对于多个网络交替
描述
简单描述一下我的网络结构,我的网络是有上下两路,先对第一路网络进行训练,使用groud truth对这一路的结果进行监督loss_steam1,得到训练好的feature.然后再将得到的feature级联到第二路,通过网络得到最后的结果,再用groud truth进行监督loss。
整个网络基于VGG19网络,在pytorch下搭建,有GPU环境:
出现的情况,loss_steam1不怎么下降
这个问题确实折麽自己一段时间,结果发现自己出现了一个问题,下面将对这个问题进行分析和解答:
PyTorch梯度传递
在PyTorch中,传入网络计算的数据类型必须是Variable类型, Variable包装了一个Tensor,并且保存着梯度和创建这个Variablefunction的引用,换句话说,就是记录网络每层的梯度和网络图,可以实现梯度的反向传递.
则根据最后得到的loss可以逐步递归的求其每层的梯度,并实现权重更新。
在实现梯度反向传递时主要需要三步:
1、初始化梯度值:net.zero_grad() 清除网络状态
2、反向求解梯度:loss.backward() 反向传播求梯度
3、更新参数:optimizer.step() 更新参数
解决方案
自己在写代码的时候,还是没有对自己的代码搞明白。在反向求解梯度时,对第一路没有进行反向传播,这样肯定不能使这一路的更新,所以我就又加了一步:
loss_steam1.backward( retain_graph = True) //因为每次运行一次backward时,如果不加retain_graph = True,运行完后,计算图都会free掉。
loss.backward()
这样就够了么?我当时也是这么认为的结果发现loss_steam1还是没有降,又愁了好久,结果发现梯度有了,不更新参数,怎么可能有用!
optimizer_steam1.step() //这项必须加
optimizer.step()
哈哈!这样就完成了,效果也确实比以前好了很多。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/u012505617/article/details/107530252
猜你喜欢
- 本文实例为大家分享了python多线程分块读取文件的具体代码,供大家参考,具体内容如下# _*_coding:utf-8_*_import
- <% a="福建是中国的一个省|我们美丽中国的武夷山!" b="中国,我们,武夷山,福建,美国,苹果&q
- 目录abspathbasenamedirnameexistsgetatimegetctimegetsizeisabsisdirisfilei
- 如下所示:a, b, c = 1, 2, 3 # 1.常规 if a>b: &nbs
- 前言最近项目中遇到一个用于监控日志文件的Python包pyinotify,结合自己的项目经验和网上的一些资料总结一下,总的原理是利用pyin
- 在scipy.linalg的函数中,往往会提供两种参数,其一是check_finite,当为True时将进行有限检查,另一类是overwri
- Python入门 本系列为Python学习相关笔记整理所得,IT人
- 车牌识别在高速公路中有着广泛的应用,比如我们常见的电子收费(ETC)系统和交通违章车辆的检测,除此之外像小区或地下车库门禁也会用到,基本上凡
- 这篇文章主要介绍了通过实例了解Python str()和repr()的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参
- 你知道世界上有多少种浏览器吗?除了我们熟知的IE, Firefox, Opera, Safari四大浏览器之外,世界上还有近百种浏览器。几天
- 本文实例为大家分享了Python threading模块对单个接口进行并发测试的具体代码,供大家参考,具体内容如下本文知识点通过在threa
- 我就废话不多说了,大家还是直接看代码吧~one = tf.ones_like(label)zero = tf.zeros_like(labe
- 在研究ezSQL的时候就看到了mssql_connect()等一些php提供的连接MSSQL的函数,本以为php这个开源的风靡世界的编程语言
- 在python中。布尔值有 Ture False 两种。Ture等于对,False等于错。要注意在python中对字母的大小写要求非常严格。
- 实例如下所示:u = array([[1,2],[3,4]])m = u.tolist()#转换为listm.remove(m[0])#移除
- python逆序的三位数程序每次读入一个正3位数,然后输出按位逆序的数字。注意:当输入的数字含有结尾的0时,输出不应带有前导的0。比如输入7
- 最近写程序需要从文件中读取数据,并把读取的数据转换成向量。查阅资料之后找到了读取csv文件和txt文件两种方式,下面结合自己的实验过程,做简
- 使用 NetBox 可以方便的将 asp 应用编译成为独立运行的执行程序,完全摆脱 iis 的束缚,在几乎所有的 Windows 版本上面直
- 最近在学习Python网络相关编程,这个代码实现了Telnet自动连接检测root用户密码,密码取自密码本,一个一个检测密码是否匹配,直到匹
- 图片外框特征参数:①dashed:虚线 ②dotted:点虚线 ③solid:实线 ④double:双线 ⑤groove:沟槽状 ⑥ridg