从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上加载模型
将另一段代码中的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()
运行正常。