質問編集履歴

1 エラー全文の追記

Yhaya

Yhaya score 398

2020/09/01 23:39  投稿

PyTorch のモデルを GPU に配置できない
Pytorch を使ってモデルを構築しようとしています。最初の段階で、Backboneモデルから中間層を3つ取り出すモジュールを書いていたのですが、これを GPU 上に配置出来なくて困っています。
```python
import torch.nn as nn
import torchvision.models as models
class Backbone(nn.Module):
   def __init__(self, backbone_type="ResNet50"):
       super(Backbone, self).__init__()
       self.backbone_type = backbone_type
   def forward(self, x):
       if self.backbone_type == "ResNet50":
           model = models._utils.IntermediateLayerGetter(
               models.resnet50(), {"layer1": 2, "layer2": 3, "layer3": 4}
           )
           return model(x)
```
テストコードとして以下のようなコードを書いています。
```python
import numpy as np
import pytest
import torch
from src.model import Backbone
@pytest.mark.skipif(not torch.cuda.is_available(), reason="There is no GPU")
def test_run_backbone_on_gpu():
   back = Backbone()
   dummy_input = torch.from_numpy(np.random.random((1, 3, 224, 224))).to(
       "cuda", dtype=torch.float
   )
   back = back.cuda()
   dummy_output = back(dummy_input)
   assert dummy_output[2].size() == torch.Size([1, 256, 56, 56])
   assert dummy_output[3].size() == torch.Size([1, 512, 28, 28])
   assert dummy_output[4].size() == torch.Size([1, 1024, 14, 14])
```
このテストを実行すると以下のような Runtime Error が出ます。
```bash
================================================================================================ FAILURES =================================================================================================  
________________________________________________________________________________________ test_run_backbone_on_gpu _________________________________________________________________________________________  
 
   @pytest.mark.skipif(not torch.cuda.is_available(), reason="There is no GPU")  
   def test_run_backbone_on_gpu():  
       back = Backbone()  
       dummy_input = torch.from_numpy(np.random.random((1, 3, 224, 224))).to(  
           "cuda", dtype=torch.float  
       )  
       back = back.cuda()  
>      dummy_output = back(dummy_input)  
 
tests/test_model.py:43:  
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  
.venv/lib/python3.8/site-packages/torch/nn/modules/module.py:722: in _call_impl  
   result = self.forward(*input, **kwargs)  
src/model.py:16: in forward  
   return model(x)  
.venv/lib/python3.8/site-packages/torch/nn/modules/module.py:722: in _call_impl  
   result = self.forward(*input, **kwargs)  
.venv/lib/python3.8/site-packages/torchvision/models/_utils.py:63: in forward  
   x = module(x)  
.venv/lib/python3.8/site-packages/torch/nn/modules/module.py:722: in _call_impl  
   result = self.forward(*input, **kwargs)  
.venv/lib/python3.8/site-packages/torch/nn/modules/conv.py:419: in forward  
   return self._conv_forward(input, self.weight)  
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  
 
self = Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)  
input = tensor([[[[0.1313, 0.0234, 0.7552, ..., 0.3833, 0.4139, 0.8594],  
         [0.1304, 0.7056, 0.5246, ..., 0.4825, 0.6..., 0.3003, 0.3479, 0.5493],  
         [0.3813, 0.9502, 0.2774, ..., 0.6596, 0.5868, 0.9608]]]],  
      device='cuda:0')  
weight = Parameter containing:  
tensor([[[[-4.6613e-02, -9.6919e-04, 8.5332e-03, ..., 2.0174e-02,  
           9.1100e-03, -4....[-2.4699e-02, 1.7219e-02, -1.9792e-02, ..., -7.8135e-03,  
          -3.0772e-02, -1.7609e-02]]]], requires_grad=True)  
 
   def _conv_forward(self, input, weight):  
       if self.padding_mode != 'zeros':  
           return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),  
                           weight, self.bias, self.stride,  
                           _pair(0), self.dilation, self.groups)  
>      return F.conv2d(input, weight, self.bias, self.stride,  
                       self.padding, self.dilation, self.groups)  
E      RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same  
 
.venv/lib/python3.8/site-packages/torch/nn/modules/conv.py:415: RuntimeError  
========================================================================================= short test summary info =========================================================================================  
FAILED tests/test_model.py::test_run_backbone_on_gpu - RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same
 
```
このエラーは、入力値は GPU 上にあるけど モデル(重みパラメータ)が GPU 上にないということを言っているのだと思いますが、これをどのように解決すればいいのかわかりません。
よろしくお願いいたします。
  • Python 3.x

    18861 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • PyTorch

    520 questions

    PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る