Pytorch学习笔记(二)使用Pytorch的常见错误汇总

那些年我们一起踩过的坑!

文章目录

  • 那些年我们一起踩过的坑!
  • Error
    • 标签范围问题
    • 输入图像大小不一的问题
    • 内存连续问题
    • 保存和加载整个模型的问题
    • argument or attribute error
      • nll_loss关键字参数问题
    • 0.4版本带来的Error
      • torch.tensor问题
      • torch.device问题
  • Warning
    • 0.4版本带来的Warning
      • 单值张量的索引问题
      • volatile was removed
      • `Tensor`和`Variable`合并
    • Attention
    • 逗比问题
      • 输入图片未调整维度,导致结果完全不对

Error

标签范围问题

这个错误出现在我参考别人的源码来训练一个车型识别模型,共196类,设置输出num_classes = 196,结果报下面错误,原因是我的输入的标签是1-196,超出索引范围,正确标签范围应该是[0,num_classes)

    _, pred = output.data.cpu().topk(1, dim=1)
RuntimeError: cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/THCTensorCopy.c:70

可参考:Issue #1204 · pytorch/pytorch

输入图像大小不一的问题

数据集图像大小不一,加载训练集时进行了Resize and Crop ,但是在测试时忘记了,因此出现了以下报错信息:

    for batch_idx, (input, target) in enumerate(loader):
  File "/usr/local/lib/python2.7/dist-packages/torch/utils/data/dataloader.py", line 264, in __next__
    batch = self.collate_fn([self.dataset[i] for i in indices])
  File "/usr/local/lib/python2.7/dist-packages/torch/utils/data/dataloader.py", line 138, in default_collate
    return [default_collate(samples) for samples in transposed]
  File "/usr/local/lib/python2.7/dist-packages/torch/utils/data/dataloader.py", line 115, in default_collate
    return torch.stack(batch, 0, out=out)
RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 0. Got 182 and 360 in dimension 2 at /pytorch/aten/src/TH/generic/THTensorMath.c:3586

内存连续问题

# version 0.3.1
x_t = x.transpose(1, 2)
x_t.view(-1, 1, frame_num)
RuntimeError: invalid argument 2: input is not contiguous at /pytorch/torch/lib/THC/generic/THCTensor.c:
  • 原因
    对张量进行转置之后,再对转置后的张量进行view,发生错误,报错原因是输入不连续。要理解这个错误的发生原因主要涉及几个点,第一是torch.Tensornumpy.ndarray一样,由计算机内存的连续一维段组成;第二是transpose操作共享底层储存;第三是view的前提是满足连续性条件。共享底层存储导致x_t并非是按自己的索引方式连续存储,因此在view操作时报错。
  • 解决方案
    view操作之前调用.contiguous()即可。
    实测0.4.1版本会出现更详细的错误提示以及解决指导,大概是真的太容易出错了!
  • 参考资料
    RuntimeError: input is not contiguous - PyTorch Forums

保存和加载整个模型的问题

问题出现在我保存整个模型之后,在另一个项目文件中加载模型报错

AttributeError: Can't get attribute 'Generator' on __main__' from ...

在Error in loading model in PyTorch - Stack Overflow得到了线索,然后去查看文档和手册Saving and Loading Models — PyTorch Tutorials,发现了问题所在!!!
原因: Pytorch保存整个模型的序列化数据绑定到特定类以及保存模型时使用的确切目录结构。因为pickle不保存模型类本身。相反,它会保存包含类的文件的路径,该文件在加载时使用。 因此,当您在其他项目中或在重构之后使用时,代码可能会以各种方式中断,属性错误之类的。

argument or attribute error

nll_loss关键字参数问题

跑个官例手写字体就报错

TypeError: nll_loss() got an unexpected keyword argument 'reduction'

help(F.nll_loss) ,查看文档,确实没有该参数。跑到官方手册查看,有该参数,确认是版本差!
总结: 官例跟随最新的版本,如果自己的是老版本,容易遇到一些argument or attribute error,这时候要根据官方手册排查,确认之后可以选择更新包或者自己recoding。

0.4版本带来的Error

详细原因见下文Attention部分

torch.tensor问题

0.4之前版本无法使用torch.tensor创建张量

# 注意:诸多原因可以造成该错误提示,不能用于定位原因!!!
TypeError: 'module' object is not callable

torch.device问题

AttributeError: module 'torch' has no attribute 'device'

Warning

很多情况下警告都是由于版本更新引起,如果是run别人的源码,一定要注意版本问题!

0.4版本带来的Warning

单值张量的索引问题

UserWarning: invalid index of a 0-dim tensor. This will be an error in PyTorch 0.5. Use tensor.item() to convert a 0-dim tensor to a Python number

0.4版本支持0维(标量)张量,标量可以使用新的torch.tensor函数来创建,可以将它视为numpy.array。索引向量返回一个标量,使用tensor.item()将0维张量转为一个Python数字。

# for Pytorch 0.4+
>>> torch.tensor(3.1416)         # create a scalar directly
tensor(3.1416)
>>> torch.tensor(3.1416).size()  # scalar is 0-dimensional
torch.Size([])
>>> torch.tensor([3]).size()     # compare to a vector of size 1
torch.Size([1])
>>> vector = torch.arange(2, 6)  # this is a vector
>>> vector
tensor([ 2.,  3.,  4.,  5.])
>>> vector.size()
torch.Size([4])
>>> vector[3]                    # indexing into a vector gives a scalar
tensor(5.)
>>> vector[3].item()             # .item() gives the value as a Python number
5.0

以前索引一维Tensor返回一个Python数字,索引一维Variable返回一个大小为1的一维tensor。

# for Pytorch 0.3.1
>>> a = torch.Tensor([1,2,3])
>>> b= torch.autograd.Variable(a)
>>> a[1]
2.0
>>> b[1]
Variable containing:
 2
[torch.FloatTensor of size 1]
>>> a.sum()
6.0
>>> b.sum()
Variable containing:
 6
[torch.FloatTensor of size 1]

volatile was removed

UserWarning: volatile was removed and now has no effect. Use `with torch.no_grad():` instead.
  input_var = torch.autograd.Variable(input.cuda(async=True), volatile=True)

TensorVariable合并

在此之前只有Variable支持backwardVariableTensor的封装。

0.4版本中,torch.autograd.Variabletorch.Tensor将同属一类。更确切地说,torch.Tensor 能够跟踪历史并像旧版本的 Variable 那样运行; Variable 封装仍旧可以像以前一样工作,但返回一个torch.Tensor类型的对象。 这意味着你再也不需要在代码中到处使用Variable 封装。

Attention

关于0.4版本带来的各类问题,我强烈推荐你阅读PyTorch 0.4.0迁移指南

逗比问题

输入图片未调整维度,导致结果完全不对

最近测试一个模型时,结果总是与预期不符。即便拿训练的正样本测试,结果也是乱七八糟的。
问题大概率是在输入数据的处理上,于是对图像处理的每一个步骤进行检查。
最终发现是我没有对输入的图像数据进行转置,即原图H x W x C,Pytorch的Tensor为C X H X W

你可能感兴趣的:(PyTorch)