Pytorch高版本(1.0)跑程序出现的几个错误

Pytorch高版本1.0跑程序出现的几个错误

  • 错误 output with shape [1, 28, 28] doesn't match the broadcast shape [3, 28, 28]
  • 错误 NotADirectoryError: [WinError 267] 目录名称无效。
  • 错误 Expected object of scalar type Long but got scalar type Int for argument #3 ‘index’
  • 错误 RuntimeError: Expected object of backend CUDA but got backend CPU for argument #2 'other'
  • 错误 IndexError: invalid index of a 0-dim tensor. Use tensor.item() to convert a 0-dim tensor to a Python
  • 选择显卡的问题
  • 错误 RuntimeError: Expected object of scalar type Long but got scalar type Int for argument #2 'other'

跑pytorch的程序,因为源码是python 2.7 + pytorch 0.4的,而我的环境是 python 3.5 + pytorch 1.0
跑起来出现了很多错误,在此进行记录。

错误 output with shape [1, 28, 28] doesn’t match the broadcast shape [3, 28, 28]

解决:https://github.com/udacity/deep-learning-v2-pytorch/pull/151
因为:

transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) will cause below error:
RuntimeError: output with shape [1, 28, 28] doesn’t match the broadcast shape [3, 28, 28]

need change to
transforms.Normalize((0.5,), (0.5,))

存在于 task_generator.py中的 get_data_loader中,如下注释进行改动

def get_data_loader(task, num_per_class=1, split='train',shuffle=True,rotation=0):
    # NOTE: batch size here is # instances PER CLASS
    #normalize = transforms.Normalize(mean=[0.92206, 0.92206, 0.92206], std=[0.08426, 0.08426, 0.08426])
    normalize = transforms.Normalize(mean=[0.92206], std=[0.08426])
    dataset = Omniglot(task,split=split,transform=transforms.Compose([Rotate(rotation),transforms.ToTensor(),normalize]))

    if split == 'train':
        sampler = ClassBalancedSampler(num_per_class, task.num_classes, task.train_num,shuffle=shuffle)
    else:
        sampler = ClassBalancedSampler(num_per_class, task.num_classes, task.test_num,shuffle=shuffle)
    loader = DataLoader(dataset, batch_size=num_per_class*task.num_classes, sampler=sampler)

    return loader

错误 NotADirectoryError: [WinError 267] 目录名称无效。

这个目录名无效困扰我很久,明明目录路径没问题啊,文件也有,为什么报错呢?
原来这个问题是因为只需要path信息,不要写到文件。
https://forums.fast.ai/t/notadirectoryerror-winerror-267-the-directory-name-is-invalid-data-bts-valid-features-npy/19657

错误 Expected object of scalar type Long but got scalar type Int for argument #3 ‘index’

Expected object of scalar type Long but got scalar type Int for argument #3 ‘index’
出现在omniglot_train_one_shot.py中,如注释进行修改

        mse = nn.MSELoss().cuda(GPU)
        one_hot_labels = Variable(torch.zeros(BATCH_NUM_PER_CLASS * CLASS_NUM, CLASS_NUM).scatter_(1,  batch_labels.view(-1, 1).long(),1)).cuda(GPU)
        #one_hot_labels = Variable(torch.zeros(BATCH_NUM_PER_CLASS*CLASS_NUM, CLASS_NUM).scatter_(1, 1, batch_labels.view(-1,1))).cuda(GPU)#看scatter修改
        loss = mse(relations,one_hot_labels)

其实我在网上看到出现了各种类似问题,但是并没有去究其原因,只是想快速解决,反而浪费了半个多小时。
问题出在scatter的函数参数上:第2个(算上self是第3个)参数应该是tensor,且其包含的元素类型应该是Long型,而原来程序内是Int型。
进行类型转换: https://ptorch.com/news/71.html

贴scatter代码:

	def scatter(self, dim, index, source): ...

    @overload
    def scatter_(self, dim: int, index: 'Tensor', src: 'Tensor') -> 'Tensor': ...

    @overload #!!就是这个overload,可以看到index是tensor格式,但是代码要求其内元素为Long
    def scatter_(self, dim: int, index: 'Tensor', value: float) -> 'Tensor': ...

错误 RuntimeError: Expected object of backend CUDA but got backend CPU for argument #2 ‘other’

这个跟上一个长得很像,有很强的迷惑性。
Pytorch高版本(1.0)跑程序出现的几个错误_第1张图片
问题出在:

rewards = [1 if predict_labels[j]==test_labels[j] else 0 for j in range(CLASS_NUM)]

这里的predict_labels 和 test_labels有问题,调试时查看他们的值,分别为:

predict_labels[j] =tensor([4, 0, 3, 1, 2], device='cuda:0')
test_labels[j] = tensor([4, 0, 3, 1, 2], dtype=torch.int32)

两者并不相等,即使前面的值相等,后面也不等。最气人的是一个有device 一个有dtype,我需要把他们都统一起来。
原因:0.4.0以后就改了增加了device-agnostic的概念(即设备无关,可以理解为无论什么设备都可以运行您编写的代码。)
以前版本的PyTorch编写device-agnostic代码非常困难(即,在不修改代码的情况下在CUDA可以使用或者只能使用CPU的设备上运行)。

PyTorch 0.4.0通过两种方法使代码兼容变得非常容易:

1、张量的device属性为所有张量提供了torch.device设备。(注意:get_device仅适用于CUDA张量)

2、to方法Tensors和Modules可用于容易地将对象移动到不同的设备(代替以前的cpu()或cuda()方法)
这里我使用了to方法。
在问题语句前增加:

predict_labels = predict_labels.to(device,dtype=torch.int32) #添加
test_labels = test_labels.to(device) #添加	

问题解决。
参考:
https://ptorch.com/news/189.html
https://discuss.pytorch.org/t/expected-object-of-scalar-type-long-but-got-scalar-type-float-for-argument-2-target/33102/2

错误 IndexError: invalid index of a 0-dim tensor. Use tensor.item() to convert a 0-dim tensor to a Python

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
  train_loss += loss.data[0]

将pytorch更新到0.4.0最新版后对0.3.1版本代码会有如上警告,它在提醒用户下个版本这将成为一个错误(我这里是1.0就已经成为错误了)
转自 https://blog.csdn.net/martinue/article/details/80342461
解决:

#原语句:
train_loss+=loss.data[0]
#修改后:
train_loss+=loss.item()
#bingo

选择显卡的问题

用pytorch选择显卡。
我在服务器上准备跑程序,但是第0块显卡被占用了,我指定了.cuda(1),但是pytorch依然强行要用成第0块显卡跑程序,真是倔强。。
最后发现问题:应该算个bug
见 https://www.cnblogs.com/jisongxie/p/10276742.html
使用CUDA_VISIBLE_DEVICES限制一下使用的GPU。

错误 RuntimeError: Expected object of scalar type Long but got scalar type Int for argument #2 ‘other’

这个问题折磨了我快一天时间,pytorch里的tensor会指定cpu还是gpu,甚至是第几块gpu。
一直弹error:

    rewards = [1 if predict_labels[j]==test_labels[j] else 0 for j in range(CLASS_NUM)]
RuntimeError: Expected object of scalar type Long but got scalar type Int for argument #2 'other'

感觉跟之前的问题很相近,但是无从下手,查资料也没有查到
如下尝试给tensor加上对应的GPU,但是仍然不行

 test_labels = test_labels.to(device)
 predict_labels = predict_labels.to(device)

最后愤怒的我选择强制转换成numpy格式进行比较 predict_labels[j]==test_labels[j],成功了。

predict_labels =  predict_labels.cpu().numpy()
test_labels = test_labels.cpu().numpy()
rewards = [1 if predict_labels[j]==test_labels[j] else 0 for j in range(CLASS_NUM)]

磨人的错误啊

ps pycharm中传入命令行参数
Run/Debug Configurations->Configurations->Script Parames
https://www.cnblogs.com/darkknightzh/p/5670821.html

你可能感兴趣的:(Pytorch,Pytorch)