質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

PyTorch

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

1回答

2462閲覧

SSDでマルチGPUで学習しようとするとき、ギャザー関数がCPUテンソルに含まれていないとエラーが表示される

heets

総合スコア0

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

PyTorch

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2021/12/06 16:12

編集2021/12/06 23:39

###前提・実現したいこと
PyTorchによるSSDを用いた物体検出の訓練について
「作りながら学ぶ PyTorchによる発展ディープラーニング」
の第2章 「2-7_SSD_training.ipynb」
において net = nn.DataParallel(net)を追加してマルチGPUで学習を実行した際に以下のエラーメッセージが表示されました。

発生している問題・エラーメッセージ

AssertionError Traceback (most recent call last) <ipython-input-34-56fa4f8d86af> in <module> 1 # 学習・検証を実行する 2 num_epochs= 10 ----> 3 train_model(net, dataloaders_dict, criterion, optimizer, num_epochs=num_epochs) <ipython-input-33-645d91cb3a1e> in train_model(net, dataloaders_dict, criterion, optimizer, num_epochs) 60 with torch.set_grad_enabled(phase == 'train'): 61 # 順伝搬(forward)計算 ---> 62 outputs = net(images) 63 64 # 損失の計算 ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs) 725 result = self._slow_forward(*input, **kwargs) 726 else: --> 727 result = self.forward(*input, **kwargs) 728 for hook in itertools.chain( 729 _global_forward_hooks.values(), ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/data_parallel.py in forward(self, *inputs, **kwargs) 160 replicas = self.replicate(self.module, self.device_ids[:len(inputs)]) 161 outputs = self.parallel_apply(replicas, inputs, kwargs) --> 162 return self.gather(outputs, self.output_device) 163 164 def replicate(self, module, device_ids): ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/data_parallel.py in gather(self, outputs, output_device) 172 173 def gather(self, outputs, output_device): --> 174 return gather(outputs, output_device, dim=self.dim) 175 176 ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/scatter_gather.py in gather(outputs, target_device, dim) 66 # Setting the function to None clears the refcycle. 67 try: ---> 68 res = gather_map(outputs) 69 finally: 70 gather_map = None ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/scatter_gather.py in gather_map(outputs) 61 return type(out)(((k, gather_map([d[k] for d in outputs])) 62 for k in out)) ---> 63 return type(out)(map(gather_map, zip(*outputs))) 64 65 # Recursive function calls like this create reference cycles. ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/scatter_gather.py in gather_map(outputs) 53 out = outputs[0] 54 if isinstance(out, torch.Tensor): ---> 55 return Gather.apply(target_device, dim, *outputs) 56 if out is None: 57 return None ~/anaconda3/envs/vgg/lib/python3.6/site-packages/torch/nn/parallel/_functions.py in forward(ctx, target_device, dim, *inputs) 54 def forward(ctx, target_device, dim, *inputs): 55 assert all(map(lambda i: i.device.type != 'cpu', inputs)), ( ---> 56 'Gather function not implemented for CPU tensors' 57 ) 58 target_device = _get_device_index(target_device, True) AssertionError: Gather function not implemented for CPU tensors

該当のソースコード

python

1# モデルを学習させる関数を作成 2 3 4def train_model(net, dataloaders_dict, criterion, optimizer, num_epochs): 5 6 # GPUが使えるかを確認 7 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 8 print("使用デバイス:", device) 9 net = nn.DataParallel(net) 10 11 # ネットワークをGPUへ 12 net.to(device) 13 14 # ネットワークがある程度固定であれば、高速化させる 15 torch.backends.cudnn.benchmark = True 16 17 # イテレーションカウンタをセット 18 iteration = 1 19 epoch_train_loss = 0.0 # epochの損失和 20 epoch_val_loss = 0.0 # epochの損失和 21 logs = [] 22 23 # epochのループ 24 for epoch in range(num_epochs+1): 25 26 # 開始時刻を保存 27 t_epoch_start = time.time() 28 t_iter_start = time.time() 29 30 print('-------------') 31 print('Epoch {}/{}'.format(epoch+1, num_epochs)) 32 print('-------------') 33 34 # epochごとの訓練と検証のループ 35 for phase in ['train', 'val']: 36 if phase == 'train': 37 net.train() # モデルを訓練モードに 38 print('(train)') 39 else: 40 if((epoch+1) % 10 == 0): 41 net.eval() # モデルを検証モードに 42 print('-------------') 43 print('(val)') 44 else: 45 # 検証は10回に1回だけ行う 46 continue 47 48 # データローダーからminibatchずつ取り出すループ 49 for images, targets in dataloaders_dict[phase]: 50 51 # GPUが使えるならGPUにデータを送る 52 images = images.to(device) 53 targets = [ann.to(device) 54 for ann in targets] # リストの各要素のテンソルをGPUへ 55 56 # optimizerを初期化 57 optimizer.zero_grad() 58 59 # 順伝搬(forward)計算 60 with torch.set_grad_enabled(phase == 'train'): 61 # 順伝搬(forward)計算 62 outputs = net(images) 63 64 # 損失の計算 65 loss_l, loss_c = criterion(outputs, targets) 66 loss = loss_l + loss_c 67 68 # 訓練時はバックプロパゲーション 69 if phase == 'train': 70 loss.backward() # 勾配の計算 71 72 # 勾配が大きくなりすぎると計算が不安定になるので、clipで最大でも勾配2.0に留める 73 nn.utils.clip_grad_value_( 74 net.parameters(), clip_value=2.0) 75 76 optimizer.step() # パラメータ更新 77 78 if (iteration % 10 == 0): # 10iterに1度、lossを表示 79 t_iter_finish = time.time() 80 duration = t_iter_finish - t_iter_start 81 print('イテレーション {} || Loss: {:.4f} || 10iter: {:.4f} sec.'.format( 82 iteration, loss.item(), duration)) 83 t_iter_start = time.time() 84 85 epoch_train_loss += loss.item() 86 iteration += 1 87 88 # 検証時 89 else: 90 epoch_val_loss += loss.item() 91 92 # epochのphaseごとのloss (Issue158での誤植修正) 93 t_epoch_finish = time.time() 94 print('-------------') 95 print('epoch {} || Epoch_TRAIN_Loss:{:.4f} ||Epoch_VAL_Loss:{:.4f}'.format( 96 epoch+1, epoch_train_loss, epoch_val_loss)) 97 print('timer: {:.4f} sec.'.format(t_epoch_finish - t_epoch_start)) 98 t_epoch_start = time.time() 99 100 # ログを保存 101 log_epoch = {'epoch': epoch+1, 102 'train_loss': epoch_train_loss, 'val_loss': epoch_val_loss} 103 logs.append(log_epoch) 104 df = pd.DataFrame(logs) 105 df.to_csv("log_output.csv") 106 107 epoch_train_loss = 0.0 # epochの損失和 108 epoch_val_loss = 0.0 # epochの損失和 109 110 # ネットワークを保存する 111 if ((epoch+1) % 10 == 0): 112 torch.save(net.state_dict(), 'weights/ssd300_' + 113 str(epoch+1) + '.pth') 114 115 116# 学習・検証を実行する 117num_epochs= 10 118train_model(net, dataloaders_dict, criterion, optimizer, num_epochs=num_epochs) 119 120

試したこと

シングルGPUでは問題なく動かすことができますが、net = nn.DataParallel(net)を実行すると上記のようなエラー文が出てしまいます。
エラー文をインターネットで検索して出てきた解決方法は一通り行ってみました。

補足情報(FW/ツールのバージョンなど)

ubuntu20.04
PyTorchバージョン1.7.0
GEFORCE RTX 3070 ×2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

AssertionError:Gather function not implemented for CPU tensors解决办法と同じ問題なら、解決方法が書かれているのでお読みください。

投稿2021/12/06 22:51

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

heets

2021/12/06 23:36

ppaulさん ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問