num_epochs = 10
dataloaders_dict = {"train": train_dataloader, "val": val_dataloader}
train_loss_list, val_loss_list = train_model(net, dataloaders_dict, criterion, scheduler, optimizer, num_epochs)
を実行すると以下のエラーが出ます。
クラスを2に指定して、二値分類のセグメンテーションを行うことが目標です。
参考にした Webページの内容より、可能性の一つはクラス数とネットワークモデルの入出力の不一致とありましたが、その方は大丈夫でした。
エラー文より、損失関数の計算の箇所で問題がありそうです。
対処の仕方がわからず困っています。解決のヒントをお願いします。
loss = criterion(outputs, anno_class_imges.long()) / batch_multiplier
Python
1RuntimeError Traceback (most recent call last) 2Input In [15], in <cell line: 3>() 3 1 num_epochs = 10 4 2 dataloaders_dict = {"train": train_dataloader, "val": val_dataloader} 5----> 3 train_loss_list, val_loss_list = train_model(net, dataloaders_dict, criterion, scheduler, optimizer, num_epochs) 6 7Input In [14], in train_model(net, dataloaders_dict, criterion, scheduler, optimizer, num_epochs) 8 72 with torch.set_grad_enabled(phase == 'train'): 9 73 outputs = net(imges) 10---> 74 loss = criterion(outputs, anno_class_imges.long()) / batch_multiplier 11 76 # 訓練時はバックプロパゲーション 12 77 if phase == 'train': 13 14File ~\anaconda3\envs\copy38\lib\site-packages\torch\nn\modules\module.py:1110, in Module._call_impl(self, *input, **kwargs) 15 1106 # If we don't have any hooks, we want to skip the rest of the logic in 16 1107 # this function, and just call forward. 17 1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks 18 1109 or _global_forward_hooks or _global_forward_pre_hooks): 19-> 1110 return forward_call(*input, **kwargs) 20 1111 # Do not call functions when jit is used 21 1112 full_backward_hooks, non_full_backward_hooks = [], [] 22 23Input In [12], in PSPLoss.forward(self, outputs, targets) 24 8 def forward(self, outputs, targets): 25 9 """ 26 10 損失関数の計算。 27 11 28 (...) 29 23 損失の値 30 24 """ 31---> 26 loss = F.cross_entropy(outputs[0], targets, reduction='mean') 32 27 loss_aux = F.cross_entropy(outputs[1], targets, reduction='mean') 33 29 return loss+self.aux_weight*loss_aux 34 35File ~\anaconda3\envs\copy38\lib\site-packages\torch\nn\functional.py:2996, in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction, label_smoothing) 36 2994 if size_average is not None or reduce is not None: 37 2995 reduction = _Reduction.legacy_get_string(size_average, reduce) 38-> 2996 return torch._C._nn.cross_entropy_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index, label_smoothing) 39 40 41 42 43RuntimeError: CUDA error: device-side assert triggered 44
使用したコードの一部を貼ります
Python
1#損失関数 2class PSPLoss(nn.Module): 3 4 5 def __init__(self, aux_weight=0.4): 6 super(PSPLoss, self).__init__() 7 self.aux_weight = aux_weight # aux_lossの重み 8 9 def forward(self, outputs, targets): 10 11 loss = F.cross_entropy(outputs[0], targets, reduction='mean') 12 loss_aux = F.cross_entropy(outputs[1], targets, reduction='mean') 13 14 return loss+self.aux_weight*loss_aux 15 16 17criterion = PSPLoss(aux_weight=0.4) 18
Python
1def train_model(net, dataloaders_dict, criterion, scheduler, optimizer, num_epochs): 2 3 train_loss_list = [] 4 val_loss_list = [] 5 # GPUが使えるかを確認 6 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 7 print("使用デバイス:", device) 8 9 # ネットワークをGPUへ 10 net.to(device) 11 12 # ネットワークがある程度固定であれば、高速化させる 13 torch.backends.cudnn.benchmark = True 14 15 # 画像の枚数 16 num_train_imgs = 100 17 num_val_imgs = 30 18 batch_size = 4 19 20 # イテレーションカウンタをセット 21 iteration = 1 22 logs = [] 23 24 # multiple minibatch 25 batch_multiplier = 3 26 27 # epochのループ 28 for epoch in range(num_epochs): 29 30 # 開始時刻を保存 31 t_epoch_start = time.time() 32 t_iter_start = time.time() 33 epoch_train_loss = 0.0 # epochの損失和 34 epoch_val_loss = 0.0 # epochの損失和 35 36 print('-------------') 37 print('Epoch {}/{}'.format(epoch+1, num_epochs)) 38 print('-------------') 39 40 # epochごとの訓練と検証のループ 41 for phase in ['train', 'val']: 42 if phase == 'train': 43 net.train() # モデルを訓練モードに 44 scheduler.step() # 最適化schedulerの更新 45 optimizer.zero_grad() 46 print('(train)') 47 48 else: 49 net.eval() # モデルを検証モードに 50 print('-------------') 51 print('(val)') 52 53 # データローダーからminibatchずつ取り出すループ 54 count = 0 # multiple minibatch 55 for imges, anno_class_imges in dataloaders_dict[phase]: 56 # ミニバッチがサイズが1だと、バッチノーマライゼーションでエラーになるのでさける 57 if imges.size()[0] == 1: 58 continue 59 60 # GPUが使えるならGPUにデータを送る 61 imges = imges.to(device, dtype=torch.float) 62 anno_class_imges = anno_class_imges.to(device, dtype=torch.float) 63 64 65 # multiple minibatchでのパラメータの更新 66 if (phase == 'train') and (count == 0): 67 optimizer.step() 68 optimizer.zero_grad() 69 count = batch_multiplier 70 71 # 順伝搬(forward)計算 72 with torch.set_grad_enabled(phase == 'train'): 73 outputs = net(imges) 74 loss = criterion(outputs, anno_class_imges.long()) / batch_multiplier 75 76 # 訓練時はバックプロパゲーション 77 if phase == 'train': 78 loss.backward() # 勾配の計算 79 count -= 1 # multiple minibatch 80 81 if (iteration % 10 == 0): # 10iterに1度、lossを表示 82 t_iter_finish = time.time() 83 duration = t_iter_finish - t_iter_start 84 print('Iteration {} || Loss: {:.4f} || 10iter: {:.4f} sec.'.format( 85 iteration, loss.item()/batch_size*batch_multiplier, duration)) 86 t_iter_start = time.time() 87 88 epoch_train_loss += loss.item() * batch_multiplier 89 iteration += 1 90 91 # 検証時 92 else: 93 epoch_val_loss += loss.item() * batch_multiplier 94 95 # epochのphaseごとのlossと正解率 96 t_epoch_finish = time.time() 97 print('-------------') 98 print('epoch {} || Epoch_TRAIN_Loss:{:.4f} ||Epoch_VAL_Loss:{:.4f}'.format( 99 epoch+1, epoch_train_loss/num_train_imgs, epoch_val_loss/num_val_imgs)) 100 print('timer: {:.4f} sec.'.format(t_epoch_finish - t_epoch_start)) 101 t_epoch_start = time.time() 102 103 #lossの可視化のリスト 104 train_loss_list.append(epoch_train_loss/num_train_imgs) 105 val_loss_list.append(epoch_val_loss/num_val_imgs) 106 if ((epoch+1) % 5 == 0): 107 torch.save(net.state_dict(), 'weights/pspnet50_' + str(epoch+1) + '.pth') 108 # ログを保存 109 110 log_epoch = {'epoch': epoch+1, 'train_loss': epoch_train_loss / 111 num_train_imgs, 'val_loss': epoch_val_loss/num_val_imgs} 112 logs.append(log_epoch) 113 df = pd.DataFrame(logs) 114 df.to_csv("log_output.csv") 115 116 # 最後のネットワークを保存する 117 torch.save(net.state_dict(), 'weights/pspnet50_' + 118 str(epoch+1) + '.pth') 119 return train_loss_list, val_loss_list
GPUの処理は非同期なので、現状で「Traceback」以降に表示されてることがエラーの原因ではないかもしれません
そこで、下記のようにする方がいいようです
・GPUを使わずCPUのみでの実行でもエラーになるなら、その時の「Traceback」以降に表示されてることを参照する
・CPUのみの実行ではエラーにならないなら、コードの一番最初に下記を追加してからGPUを使って実行して、その時の「Traceback」以降に表示されてることを参照する
import os
os.environ['CUDA_LAUNCH_BLOCKING'] = "1"
参考
https://torch.classcat.com/2018/05/25/pytorch-docs-notes-cuda/
の「非同期実行」
https://lernapparat.de/debug-device-assert/
https://discuss.pytorch.org/t/runtimeerror-cuda-runtime-error-710-device-side-assert-triggered-at-pytorch-aten-src-thc-generic-thctensormath-cu-26/73167
のptrblckさんの最初のコメント
> 参考にした Webページの内容より、可能性の一つはクラス数とネットワークモデルの入出力の不一致とありましたが、その方は大丈夫でした。
とは、下記に書かれてる「アノテーションデータのラベル」のことでしょうか?
https://github.com/YutaroOgawa/pytorch_advanced/issues/182
ありがとうございます。アノテーションラベルが0、1になっておらずにエラーが出ていました。
for i in range(len(y_train_files)):
im = Image.open(y_train_files[i])
im_list = np.asarray(im)
X = im_list
Y = np.where(X>1,1,X)
pil_img = Image.fromarray(Y)
pil_img.save(y_train_files[i])
コードを追加して動きました。
> コードを追加して動きました。
この質問の内容は解決したのでしょうか?
解決しました。

> CUDA error: device-side assert triggered
今後の参考までに。
【PyTorch】「CUDA error: device-side assert triggered」 解決の手引き(https://yuiga.dev/blog/posts/pytorchcuda_error_device-side_assert_triggered_%E8%A7%A3%E6%B1%BA%E3%81%AE%E6%89%8B%E5%BC%95%E3%81%8D/)
