当前所在位置: 主页 > 耀世新闻 > 公司新闻

pytorch报错消息及其解决纪录

前言: 本文主要记载在pytorch使用过程中遇到的一些报错以及解决方案等,在以前的文章[1]中,主要涉及的是比较容易出现的原理上的,或者难以发现的bug,而这里的主要是系统抛出的error或者warning的解决方法,其各有侧重,欢迎各位贡献idea。如有谬误,请联系指出,如需转载,请注明出处,谢谢。


\
abla 联系方式:

e-mail: FesianXu@gmail.com

QQ: 973926198

github: github.com/FesianXu


trained_vars=list(model.submodel_1.parameters()) + \\
               list(model.submodel_2.parameters())
opt=torch.optim.SGD(trained_vars, lr=...)

注意到此时的trained_vars是一个可迭代的list,其中每个元素都是一个参数组。


class model(nn.Module):
 def __init__(self):
  super().__init__()
  self.convs=[
   nn.Conv2d(...),
   nn.Conv2d(...)
  ]

m=model().cuda()

此时convs因为只是个list而不是集成了nn.Module的对象,因此是不会被迭代地放置到GPU中的,model().cuda()这种方式只会对model类中的__init__()方法中定义的继承了nn.Module的类的实例有效。 解决方法

self.convs=[
 nn.Conv2d(...),
 nn.Conv2d(...)
]
self.convs=nn.ModuleList(self.convs)

inputv=inputv.float()
model(inputv)
c=x+b
x +=1

compute_gradient(ys=c, xs=x)

如果此时cx对梯度,而x的值已经在后续的计算中发生了in-place的变化,那么就会导致出错[5]

解决方案:将x +=1改成x=x+1即可解决。

补充: x +=1pytorch中是一个in-place操作,所谓in-place就是进行了该操作是对该变量直接进行处理后返回的,也就是说该变量的地址是不会改变的,只是值变了而已;而非in-place操作就是,在内存中另外开辟了一个空间存放新的值,然后将指针指向那个新的地址,在这种情况下,该变量的地址是会改变的。下面是一个例子:

In[1]: import torch
In[2]: a=torch.tensor(5)
In[3]: a
Out[3]: tensor(5)
In[4]: id(a)
Out[4]: 139636046877104
In[5]: a +=8
In[6]: a
Out[6]: tensor(13)
In[7]: id(a)
Out[7]: 139636046877104  # inplace操作,其地址不变

In[1]: import torch
In[2]: a=torch.tensor(6)
In[3]: id(a)
Out[3]: 139938915856816
In[4]: a=a+1
In[5]: a
Out[5]: tensor(7)
In[6]: id(a)
Out[6]: 139938915829584 # 非in-place操作,地址不同了

在pytorch中,计算梯度的时候有时候要求前面的相关变量不能被in-place操作改变,不然将会导致梯度计算问题,从而报错。


import torch
torch.backends.cudnn.enabled=False

# your code here
import torch
import your_extension

[1]. 用pytorch踩过的坑[2]. discuss.pytorch.org/t/g[3]. pytorch.org/docs/stable[4]. blog.csdn.net/LoseInVai[5]. discuss.pytorch.org/t/e[6]. discuss.pytorch.org/t/c[7]. github.com/pytorch/exte[8]. towardsdatascience.com/[9]. github.com/pytorch/pyto


平台注册入口