teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

3

書式の修正

2021/12/06 23:39

投稿

heets
heets

スコア0

title CHANGED
File without changes
body CHANGED
@@ -1,6 +1,5 @@
1
1
  ###前提・実現したいこと
2
2
  PyTorchによるSSDを用いた物体検出の訓練について
3
-
4
3
  「作りながら学ぶ PyTorchによる発展ディープラーニング」
5
4
  の第2章 「2-7_SSD_training.ipynb」
6
5
  において net = nn.DataParallel(net)を追加してマルチGPUで学習を実行した際に以下のエラーメッセージが表示されました。
@@ -200,7 +199,8 @@
200
199
  ```
201
200
 
202
201
  ### 試したこと
202
+ シングルGPUでは問題なく動かすことができますが、net = nn.DataParallel(net)を実行すると上記のようなエラー文が出てしまいます。
203
- gpu_id付与してたりましたがうまくいきませんでした
203
+ エラー文インターネットで検索して出てき解決方法は一通行ってみました。
204
204
 
205
205
  ### 補足情報(FW/ツールのバージョンなど)
206
206
 

2

書式の改善

2021/12/06 23:39

投稿

heets
heets

スコア0

title CHANGED
@@ -1,1 +1,1 @@
1
- 作りながら学ぶ!!Pytorch発展ディープラーニング 第2章7節マルチGPUで学習しようとするとき、ギャザー関数がCPUテンソルに含まれていないとエラーが表示される
1
+ SSDでマルチGPUで学習しようとするとき、ギャザー関数がCPUテンソルに含まれていないとエラーが表示される
body CHANGED
File without changes

1

エラーメッセージの不足を追加

2021/12/06 18:16

投稿

heets
heets

スコア0

title CHANGED
File without changes
body CHANGED
@@ -8,120 +8,75 @@
8
8
  ### 発生している問題・エラーメッセージ
9
9
 
10
10
  ```
11
- AssertionError: Gather function not implemented for CPU tensors
11
+ AssertionError Traceback (most recent call last)
12
+ <ipython-input-34-56fa4f8d86af> in <module>
13
+ 1 # 学習・検証を実行する
14
+ 2 num_epochs= 10
15
+ ----> 3 train_model(net, dataloaders_dict, criterion, optimizer, num_epochs=num_epochs)
12
16
 
17
+ <ipython-input-33-645d91cb3a1e> in train_model(net, dataloaders_dict, criterion, optimizer, num_epochs)
18
+ 60 with torch.set_grad_enabled(phase == 'train'):
19
+ 61 # 順伝搬(forward)計算
20
+ ---> 62 outputs = net(images)
13
- ```
21
+ 63
22
+ 64 # 損失の計算
14
23
 
24
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
25
+ 725 result = self._slow_forward(*input, **kwargs)
15
- ### 該当のソースコード
26
+ 726 else:
27
+ --> 727 result = self.forward(*input, **kwargs)
28
+ 728 for hook in itertools.chain(
29
+ 729 _global_forward_hooks.values(),
16
30
 
31
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/data_parallel.py in forward(self, *inputs, **kwargs)
32
+ 160 replicas = self.replicate(self.module, self.device_ids[:len(inputs)])
33
+ 161 outputs = self.parallel_apply(replicas, inputs, kwargs)
34
+ --> 162 return self.gather(outputs, self.output_device)
17
- ```python
35
+ 163
18
- # パッケージのimport
19
- import os.path as osp
36
+ 164 def replicate(self, module, device_ids):
20
- import random
21
- import time
22
37
 
38
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/data_parallel.py in gather(self, outputs, output_device)
23
- import cv2
39
+ 172
24
- import numpy as np
25
- import pandas as pd
26
- import torch
27
- import torch.nn as nn
28
- import torch.nn.init as init
29
- import torch.optim as optim
40
+ 173 def gather(self, outputs, output_device):
30
- import torch.utils.data as data
41
+ --> 174 return gather(outputs, output_device, dim=self.dim)
42
+ 175
43
+ 176
31
44
 
45
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/scatter_gather.py in gather(outputs, target_device, dim)
46
+ 66 # Setting the function to None clears the refcycle.
32
- # 乱数のシードを設定
47
+ 67 try:
48
+ ---> 68 res = gather_map(outputs)
49
+ 69 finally:
33
- torch.manual_seed(1234)
50
+ 70 gather_map = None
34
- np.random.seed(1234)
35
- random.seed(1234)
36
51
 
52
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/scatter_gather.py in gather_map(outputs)
37
- from utils.ssd_model import make_datapath_list, VOCDataset, DataTransform, Anno_xml2list, od_collate_fn
53
+ 61 return type(out)(((k, gather_map([d[k] for d in outputs]))
54
+ 62 for k in out))
55
+ ---> 63 return type(out)(map(gather_map, zip(*outputs)))
56
+ 64
57
+ 65 # Recursive function calls like this create reference cycles.
38
58
 
59
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/scatter_gather.py in gather_map(outputs)
60
+ 53 out = outputs[0]
61
+ 54 if isinstance(out, torch.Tensor):
62
+ ---> 55 return Gather.apply(target_device, dim, *outputs)
63
+ 56 if out is None:
64
+ 57 return None
39
65
 
66
+ ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/_functions.py in forward(ctx, target_device, dim, *inputs)
40
- # ファイルパスのリストを取得
67
+ 54 def forward(ctx, target_device, dim, *inputs):
41
- rootpath = "./data/VOCdevkit/VOC2012/"
68
+ 55 assert all(map(lambda i: i.device.type != 'cpu', inputs)), (
42
- train_img_list, train_anno_list, val_img_list, val_anno_list = make_datapath_list(
69
+ ---> 56 'Gather function not implemented for CPU tensors'
43
- rootpath)
70
+ 57 )
71
+ 58 target_device = _get_device_index(target_device, True)
44
72
 
45
- # Datasetを作成
46
- voc_classes = ['aeroplane', 'bicycle', 'bird', 'boat',
47
- 'bottle', 'bus', 'car', 'cat', 'chair',
48
- 'cow', 'diningtable', 'dog', 'horse',
49
- 'motorbike', 'person', 'pottedplant',
73
+ AssertionError: Gather function not implemented for CPU tensors
50
- 'sheep', 'sofa', 'train', 'tvmonitor']
51
- color_mean = (104, 117, 123) # (BGR)の色の平均値
52
- input_size = 300 # 画像のinputサイズを300×300にする
53
74
 
54
- train_dataset = VOCDataset(train_img_list, train_anno_list, phase="train", transform=DataTransform(
55
- input_size, color_mean), transform_anno=Anno_xml2list(voc_classes))
75
+ ```
56
76
 
57
- val_dataset = VOCDataset(val_img_list, val_anno_list, phase="val", transform=DataTransform(
58
- input_size, color_mean), transform_anno=Anno_xml2list(voc_classes))
77
+ ### 該当のソースコード
59
78
 
60
-
61
- # DataLoaderを作成する
62
- batch_size = 64
63
-
64
- train_dataloader = data.DataLoader(
65
- train_dataset, batch_size=batch_size, shuffle=True, collate_fn=od_collate_fn)
66
-
67
- val_dataloader = data.DataLoader(
68
- val_dataset, batch_size=batch_size, shuffle=False, collate_fn=od_collate_fn)
69
-
70
- # 辞書オブジェクトにまとめる
71
- dataloaders_dict = {"train": train_dataloader, "val": val_dataloader}
72
-
73
- from utils.ssd_model import SSD
74
-
75
- # SSD300の設定
76
- ssd_cfg = {
77
- 'num_classes': 21, # 背景クラスを含めた合計クラス数
78
- 'input_size': 300, # 画像の入力サイズ
79
- 'bbox_aspect_num': [4, 6, 6, 6, 4, 4], # 出力するDBoxのアスペクト比の種類
80
- 'feature_maps': [38, 19, 10, 5, 3, 1], # 各sourceの画像サイズ
81
- 'steps': [8, 16, 32, 64, 100, 300], # DBOXの大きさを決める
82
- 'min_sizes': [30, 60, 111, 162, 213, 264], # DBOXの大きさを決める
83
- 'max_sizes': [60, 111, 162, 213, 264, 315], # DBOXの大きさを決める
84
- 'aspect_ratios': [[2], [2, 3], [2, 3], [2, 3], [2], [2]],
85
- }
86
-
87
- # SSDネットワークモデル
88
- net = SSD(phase="train", cfg=ssd_cfg)
89
-
90
- # SSDの初期の重みを設定
91
- # ssdのvgg部分に重みをロードする
92
- vgg_weights = torch.load('./weights/vgg16_reducedfc.pth')
93
- net.vgg.load_state_dict(vgg_weights)
94
-
95
- # ssdのその他のネットワークの重みはHeの初期値で初期化
96
-
97
-
98
- def weights_init(m):
99
- if isinstance(m, nn.Conv2d):
100
- init.kaiming_normal_(m.weight.data)
101
- if m.bias is not None: # バイアス項がある場合
102
- nn.init.constant_(m.bias, 0.0)
103
-
104
-
105
- # Heの初期値を適用
106
- net.extras.apply(weights_init)
107
- net.loc.apply(weights_init)
108
- net.conf.apply(weights_init)
109
-
110
- # GPUが使えるかを確認
111
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
112
- print("使用デバイス:", device)
113
-
114
- print('ネットワーク設定完了:学習済みの重みをロードしました')
115
-
116
- from utils.ssd_model import MultiBoxLoss
117
-
118
- # 損失関数の設定
79
+ ```python
119
- criterion = MultiBoxLoss(jaccard_thresh=0.5, neg_pos=3, device=device)
120
-
121
- # 最適化手法の設定
122
- optimizer = optim.SGD(net.parameters(), lr=1e-3,
123
- momentum=0.9, weight_decay=5e-4)
124
-
125
80
  # モデルを学習させる関数を作成
126
81
 
127
82