这个错误出现在我参考别人的源码来训练一个车型识别模型,共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.Tensor
和numpy.ndarray
一样,由计算机内存的连续一维段组成;第二是transpose
操作共享底层储存;第三是view
的前提是满足连续性条件。共享底层存储导致x_t
并非是按自己的索引方式连续存储,因此在view
操作时报错。view
操作之前调用.contiguous()
即可。问题出现在我保存整个模型之后,在另一个项目文件中加载模型报错
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不保存模型类本身。相反,它会保存包含类的文件的路径,该文件在加载时使用。 因此,当您在其他项目中或在重构之后使用时,代码可能会以各种方式中断,属性错误之类的。
跑个官例手写字体就报错
TypeError: nll_loss() got an unexpected keyword argument 'reduction'
help(F.nll_loss)
,查看文档,确实没有该参数。跑到官方手册查看,有该参数,确认是版本差!
总结: 官例跟随最新的版本,如果自己的是老版本,容易遇到一些argument or attribute error
,这时候要根据官方手册排查,确认之后可以选择更新包或者自己recoding。
详细原因见下文Attention部分
0.4之前版本无法使用torch.tensor
创建张量
# 注意:诸多原因可以造成该错误提示,不能用于定位原因!!!
TypeError: 'module' object is not callable
AttributeError: module 'torch' has no attribute 'device'
很多情况下警告都是由于版本更新引起,如果是run别人的源码,一定要注意版本问题!
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]
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)
Tensor
和Variable
合并在此之前只有Variable
支持backward
,Variable
是Tensor
的封装。
0.4版本中,torch.autograd.Variable
和torch.Tensor
将同属一类。更确切地说,torch.Tensor
能够跟踪历史并像旧版本的 Variable
那样运行; Variable
封装仍旧可以像以前一样工作,但返回一个torch.Tensor类型的对象。 这意味着你再也不需要在代码中到处使用Variable
封装。
关于0.4版本带来的各类问题,我强烈推荐你阅读PyTorch 0.4.0迁移指南
最近测试一个模型时,结果总是与预期不符。即便拿训练的正样本测试,结果也是乱七八糟的。
问题大概率是在输入数据的处理上,于是对图像处理的每一个步骤进行检查。
最终发现是我没有对输入的图像数据进行转置,即原图H x W x C
,Pytorch的Tensor为C X H X W
。