炼丹师养成计划 Pytorch+DeepLearning遇见的各种报错与踩坑避坑记录(一)

850 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情

问题1: load() missing 1 required positional argument: 'Loader'

问题原因:该报错原因提示为load函数缺少必填的Loader参数

解决方案1:使用safe_load()函数代替 load()

import yaml
    with open(filename, 'r') as f:
        yaml_cfg = edict(yaml.safe_load(f))

解决方案2:添加参数 Loader=yaml.FullLoader

import yaml
    with open(filename, 'r') as f:
        yaml_cfg = edict(yaml.load(f,Loader=yaml.FullLoader))

解决方案3:降级pyyaml 版本(亲测有效) pip install pyyaml==5.4.1

问题2:ModuleNotFoundError: No module named 'dateutil'

问题原因:pip install dateutil失败,因为该模块非常坑,他叫 python-dateutil 解决方案: pip3 install python-dateuti

问题3:RuntimeError: Expected object of backend CPU but got backend CUDA for argument #4 'mat1'

问题原因:期望的对象是在后端CPU,但参数在后端CUDA上面,直白来说,就是模型没有放到cuda上面,但是模型需要的参数或者模型的部分模块被放到了cuda上面。

解决方案:将模型也放到cuda上

# 进行可用设备检测, 有GPU的话将优先使用GPU
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = model.to(device) 或 model = model.cuda(device)

问题4:ValueError: not enough values to unpack (expected 3, got 2)

问题原因:期望有三个返回值,但其实函数只有两个返回值

解决方案:定位到错误,检查函数和接收函数返回值的参数个数

问题5:Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same

问题原因:输入的数据类型为torch.cuda.FloatTensor,说明输入数据在GPU中 模型参数的数据类型为torch.FloatTensor,说明模型还在CPU

解决方案:将对应的模型参数放入cuda 如:

proj = nn.Conv2d(3, 3, 3, 4, 0)
imgs[i] = proj(imgs[i])

出错,说明img[i]在gpu上面,而我们的proj还在cpu上,所以要把proj放到cuda上面去:

proj = nn.Conv2d(3, 3, 3, 4, 0)
proj = proj.cuda()
imgs[i] = proj(imgs[i])

问题6:pytorch下,如何对多维tensor进行缩放

问题原因:有的时候想要把得到图像的尺寸过大过小,想要对生成的tensor张量进行缩放,同时要保持原有图像等比例。如现在有一个tensor,他的大小是:[64,3,256,256],64代表batch size,3表示通道数,256代表长和宽,想要将其缩小为32*32的尺寸。

解决方案:我们可以使用transform.resize(),但在试过后,发现使用torch.nn.functional.interpolate会更好用

首先说明其参数:torch.nn.functional.interpolate(input, size=None, scale_factor=None, mode='nearest', align_corners=None)

  1. input是我们的输入张量(Tensor)
  2. size是输出大小
  3. scale_factor (float or Tuple[float]) 指定输出为输入的多少倍数
  4. mode是上采样算法的选择:有’nearest’, ‘linear’, ‘bilinear’, ‘bicubic’ , ‘trilinear’和’area’,其中默认是’nearest’
  5. align_corners (bool, optional) 如果设置为True,则输入和输出张量由其角像素的中心点对齐,从而保留角像素处的值。如果设置为False,则输入和输出张量由它们的角像素的角点对齐,插值使用边界外值的边值填充

使用样例:

print(train_mask.size())
# train_mask尺寸本来是[64,3,256,256]
train_mask = torch.nn.functional.interpolate(train_mask, scale_factor=1 / 4, mode='bilinear',align_corners=False)
#变换之后,train_mask尺寸变为[64,3,64,64]
print(train_mask.size())