记PyTorch踩过的坑~

记PyTorch踩过的坑~
与阳光共进早餐

2018.01.19 阅读 563 评论 0 喜欢 0

像认真记录生活一样记录Bug.

1. 从autograd.Variable中取Tensor

  • BUG:
    RuntimeError: copy from Variable to torch.FloatTensor isn't implemented
    这个错误比较简单,就不给完整报错信息了。
  • 问题分析:
    错误语句:new_output[:,:,i,:,:]=temp2D_output
    这里的new_output是Tensor类型,temp2D_output是Variable类型。
    所以问题就变成了怎么样从autograd.Variable中取到Tensor
  • 解决方法:
    上图:

    这是autograd.Variable的结构图,忘记了可以看看这个
    PyTorch入门学习(二):Autogard之自动求梯度
    所以直接用Variable.data属性即可。

2. Pytorch的计算类型不匹配问题

  • BUG:
    Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'weight'
  • 完整报错信息:
Traceback (most recent call last):
  File "p3d_model.py", line 425, in <module>
    out=model(data)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "p3d_model.py", line 299, in forward
    x = self.maxpool_2(self.layer1(x))  #  Part Res2
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/container.py", line 67, in forward
    input = module(input)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "p3d_model.py", line 166, in forward
    out=self.ST_A(out)
  File "p3d_model.py", line 120, in ST_A
    x = self.bn2(x)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/batchnorm.py", line 37, in forward
    self.training, self.momentum, self.eps)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/functional.py", line 1013, in batch_norm
    return f(input, weight, bias)
RuntimeError: Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'weight'

从报错信息来看应该是:需要的输入参数类型为torch.FloatTensor,但实际上给定是torch.cuda.FloatTensor

  • 错误历程
    可以看到出错的语句为:self.bn2(x)
    一开始一直以为是自己传入的x类型不符合要求,
    def conv2_fyq(self,x):
        deep=x.shape[2] 
        temp2D_output=self.conv2(x[:,:,0,:,:])
        new_output=torch.Tensor(temp2D_output.shape[0],temp2D_output.shape[1],deep,temp2D_output.shape[2],temp2D_output.shape[3])
        for i in range(deep):
            temp2D_input=x[:,:,i,:,:]
            temp2D_output=self.conv2(temp2D_input)
            print (temp2D_output.shape)      # (10, ,160,160)
            new_output[:,:,i,:,:]=temp2D_output.data
        print (new_output.shape)                  # (10, ,16,160,160)  
        # print (new_output)
        result=new_output.type(torch.FloatTensor)
        # print (result)
        result=Variable(result)
        return result

   x = self.conv2_fyq(x)
   x = self.bn2(x)                    #error

所以一直在修改函数conv2_fyq()函数的返回值,希望从torch.cuda.FloatTensor类型转为torch.FloatTensor,试过很多方法,比如:

  1. result=result.cpu()
  2. 借用numpy array类型作为中转
  3. 使用类型转换 result=new_output.type(torch.FloatTensor)
  • 解决方法
    首先可以肯定的是由于张量类型不一致导致的;
    查了很多资料发现本质是由于两个张量不在同一个空间例如一个在cpu中,而另一个在gpu中因此会引发错误。
    print result发现为torch.FloatTensor类型,由此想到出现问题的是nn.BatchNorm3d中其他的参数类型为torch.cuda.FloatTensor.
    所以最后的解决方案:将result转为torch.cuda.FloatTensor类型
    result=new_output.type(torch.cuda.FloatTensor)

  • 参考文献
    torch.Tensor类型的构建与相互转换
    expected CPU tensor (got CUDA tensor)
    PyTorch遇到令人迷人的BUG与记录

这一个小bug的解决也花了近2小时了~
虽然没有直接在参考文献中找到答案,但还是深受启发~
自己解决一个木有现成答案的问题还是挺有意思的哈哈哈哈,心里话是开心都是骗人的,过程最折磨人。

生活 转载请联系作者,并注明出处。

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

春光支付宝

支付宝

春光微信

微信


喜欢  |  0

0条评论