前提・実現したいこと
Python 3.7.4
Pytorch 1.4.0
発生している問題・エラーメッセージ
Pytorchで重み学習済みVGG16モデルのfine-tuningを行っているのですが、200epoch学習させたら以下の画像ように
80epochあたりで急激にlossが増加し、accが低下しました。どのような原因が考えられるでしょうか?
該当のソースコード
python
1 # VGG-16モデルのインスタンスを生成 2use_pretrained = True # 学習済みのパラメータを使用 3net = models.vgg16(pretrained=use_pretrained) 4# 1000クラス → 10クラスに変更 5net.classifier[6] = nn.Linear(in_features=4096, out_features=10, bias=True) 6 7 8def do_train(net, dataloader_dict, criterion, optimizer, num_epochs): 9 10 # 初期設定 11 #学習中の指標を保存するリストを作成 12 #1epochのtrainに一応値を入れておく 13 train_acc_list = [0.] 14 train_loss_list = [0.] 15 val_acc_list = [] 16 val_loss_list = [] 17 18 # GPUが使えるかを確認 19 device = "cuda" if torch.cuda.is_available() else "cpu" 20 print("使用デバイス:", device) 21 22 # ネットワークをGPUへ 23 net = net.to(device) 24 if device == 'cuda': 25 net = torch.nn.DataParallel(net) # make parallel 26 27 # ネットワークがある程度固定であれば、高速化させる 28 torch.backends.cudnn.benchmark = True 29 30 # epochのループ 31 for epoch in range(num_epochs): 32 print('Epoch {}/{}'.format(epoch+1, num_epochs)) 33 print('-------------') 34 35 # epochごとの訓練と検証のループ 36 for phase in ['train', 'val']: 37 if phase == 'train': 38 net.train() # モデルを訓練モードに 39 else: 40 net.eval() # モデルを検証モードに 41 42 epoch_loss = 0.0 # epochの損失和 43 epoch_corrects = 0 # epochの正解数 44 45 # 未学習時の検証性能を確かめるため、epoch=0の訓練は省略 46 if (epoch == 0) and (phase == 'train'): 47 continue 48 49 # データローダーからミニバッチを取り出すループ 50 for inputs, labels in tqdm(dataloader_dict[phase]): 51 52 # GPUが使えるならGPUにデータを送る 53 inputs = inputs.to(device) 54 labels = labels.to(device) 55 56 # optimizerを初期化 57 optimizer.zero_grad() 58 59 60 # 順伝搬(forward)計算 61 with torch.set_grad_enabled(phase == 'train'): 62 outputs = net(inputs) 63 loss = criterion(outputs, labels) # 損失を計算 64 _, preds = torch.max(outputs, 1) # ラベルを予測 65 66 # 訓練時はバックプロパゲーション 67 if phase == 'train': 68 loss.backward() 69 optimizer.step() 70 71 # 結果の計算 72 epoch_loss += loss.item() * inputs.size(0) # lossの合計を更新 73 # 正解数の合計を更新 74 epoch_corrects += torch.sum(preds == labels.data) 75 76 # epochごとのlossと正解率を表示 77 epoch_loss = epoch_loss / len(dataloader_dict[phase].dataset) 78 epoch_acc = epoch_corrects.double( 79 ) / len(dataloader_dict[phase].dataset) 80 81 #listにlossとaccを保存 82 if phase == "train": 83 train_acc_list.append(epoch_acc) 84 train_loss_list.append(epoch_loss) 85 else: 86 val_acc_list.append(epoch_acc) 87 val_loss_list.append(epoch_loss) 88 89 print('{} Loss: {:.4f} Acc: {:.4f}'.format( 90 phase, epoch_loss, epoch_acc)) 91 92 # PyTorchのネットワークパラメータの保存 93 save_path = os.path.join(os.getcwd(), "final_weight.pth") 94 torch.save(net, save_path) 95 96 #dictで返す 97 history = {'acc': train_acc_list, 98 'loss': train_loss_list, 99 'val_acc': val_acc_list, 100 'val_loss': val_loss_list} 101 return history 102 103optimizer = optim.Adam(net.parameters()) 104criterion = nn.CrossEntropyLoss() 105 106num_epochs = 200 107hist = do_train(net, dataloader_dict, criterion, optimizer, num_epochs)
試したこと
環境によって起きたエラーかと思ったのでGoogle Colaboratory上でも実行してみましたが同様の結果が得られたので、コードに問題があると思っています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。