[菜鸟向] Pytorch的模型与变量由CPU模式转GPU模式的操作与debug

1.修改CPU版本的pytorch模型到GPU版本

从github上git下来的CNNs程序需要将分类结果在opencv上显示,图片是采用单帧处理,因此每一帧的图片返回类别与置信度的速度需要加快,于是想到该CPU版本的模型到GPU版本。

在参考网上的文档和博客后,发现只要在模型和参数后加.cuda()即可将模型由cpu上的运算调到gpu上运算。

首先需要确定自己的pytorch版本能否进行gpu计算。

print (torch.cuda.is_available())

如果结果是True,则可以进行gpu计算,如果是False,就需要安装gpu版本的torch或是CUDA了。还可以通过

print (torch.cuda.device_count())

来识别可以使用的gpu个数。

话不多说,找到git下来代码中的模型和参数,然后加.cuda:
原始代码如下:

model = models.__dict__[arch](num_classes=365)#模型
checkpoint = torch.load(model_file, map_location=lambda storage, loc: storage)#模型
...
img = Image.open(img_name)
input_img = V(centre_crop(img).unsqueeze(0))#参数
# forward pass
logit = model.forward(input_img)
h_x = F.softmax(logit, 1).data.squeeze()
probs, idx = h_x.sort(0, True)

得到的分类结果:

resnet18 prediction on 0003.jpeg
0.297 -> field_road
0.196 -> golf_course
0.101 -> pasture
0.077 -> soccer_field
0.070 -> wheat_field
elapse time is 0.11690378189086914

预测类别的时间约为0.11s
加上.cuda()的程序后

model = models.__dict__[arch](num_classes=365).cuda()
checkpoint = torch.load(model_file, map_location=lambda storage, loc: storage.cuda())
...
img = Image.open(img_name)
input_img = V(centre_crop(img).unsqueeze(0)).cuda()
...
# forward pass
logit = model.forward(input_img)
h_x = F.softmax(logit, 1).data.squeeze()
probs, idx = h_x.sort(0, True)

得到的分类结果:

resnet18 prediction on 0003.jpeg
0.297 -> field_road
0.196 -> golf_course
0.101 -> pasture
0.077 -> soccer_field
0.070 -> wheat_field
elapse time is 0.03774833679199219

前向计算时间为0.037748s

计算速度约提升3倍,GPU加速效果明显。

参考资料:
1.pytorch通过torch.cuda使用GPU加速运算且比较GPU与CPU运算效果以及应用场景
2.浅谈将Pytorch模型从CPU转换成GPU
3.pytorch在CPU和GPU上加载模型

2.TypeError:CUDA tensor to numpy

将另一段代码中的weight_softmax = params[-2]data.numpy()改成weight_softmax = params[-2].cuda().data.numpy()时会报错:

TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

参考stackflow上面的回答,如果想把CUDA tensor格式的数据改成numpy时,需要先将其转换成cpu float-tensor随后再转到numpy格式。
即,修改

x.data.numpy()

x.data.cpu().numpy()

即可

因此再修改weight_softmax = params[-2].cuda().data.numpy()
weight_softmax = params[-2].cuda().data.cpu().numpy()运行正常。

你可能感兴趣的:(pytorch)