[菜鳥向] 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()運行正常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章