diff --git a/ebus_movie_classify.py b/ebus_movie_classify.py index 2477ce3..a86e22c 100644 --- a/ebus_movie_classify.py +++ b/ebus_movie_classify.py @@ -13,6 +13,7 @@ import torchvision from torchvision import models, transforms import sys +import datetime # 入力画像の前処理クラス # 訓練時と推論時で処理を変える @@ -75,7 +76,7 @@ データへのパスを格納したリスト """ - rootpath = "/mnt/d/usr/DL/EBUS/" + rootpath = "/data2/EBUS/EBUS動画20220124/ExtractedFrames/" target_path = osp.join(rootpath + phase + "/" + label + '/**/*.png') # print(target_path) # print(len(glob.glob(target_path, recursive=True))) @@ -137,18 +138,13 @@ net.to(device) # ネットワークがある程度固定なら高速化 torch.backends.cudnn.benchmark = True - - # ログ出力 - f = open('result.csv', 'w') - writer = csv.writer(f, lineterminator='\n') - writer.writerow(['epoch', 'train_loss', 'train_acc', 'val_loss', 'val_acc']) + training_result = [] # epochのループ for epoch in range(num_epochs): - csvitems = [] - csvitems.append(epoch+1) print('') print('Epoch {}/{}'.format(epoch+1, num_epochs)) + epoch_result = [epoch + 1] # epochごとの学習と検証のループ for phase in ['train', 'val']: @@ -162,8 +158,7 @@ # 未学習時の性能を確かめるため epoch=0 の訓練は省略 if (epoch == 0) and (phase == 'train'): - csvitems.append(0) - csvitems.append(0) + epoch_result.extend([0, 0]) continue # データローダーからミニバッチを取り出すループ @@ -196,15 +191,12 @@ epoch_loss = epoch_loss / len(dataloaders_dict[phase].dataset) epoch_acc = epoch_corrects.double() / len(dataloaders_dict[phase].dataset) - print('{} Loss: {:.4f} Acc: {:.4f}'.format( - phase, epoch_loss, epoch_acc)) - csvitems.append('{:.4f}'.format(epoch_loss)) - csvitems.append('{:.4f}'.format(epoch_acc)) + print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc)) + epoch_result.extend([epoch_loss, float(epoch_acc)]) - writer.writerow(csvitems) - - f.close() + training_result.append(epoch_result) + return training_result if __name__ == "__main__": @@ -225,7 +217,7 @@ val_malignant_list = make_datapath_list(phase="val", label="Malignant") print("Dataset(orig): train benign:%d malignant:%d val benign:%d malignant:%d" % (len(train_benign_list), len(train_malignant_list), len(val_benign_list), len(val_malignant_list) )) - num_traindata = 200 + num_traindata = 1000 num_valdata = 100 train_benign_list = random.sample(train_benign_list, num_traindata) train_malignant_list = random.sample(train_malignant_list, num_traindata) @@ -256,16 +248,23 @@ use_pretrained = True # ResNet18 - # net = models.resnet18(pretrained=use_pretrained) - # net.fc = nn.Linear(in_features=512, out_features=2, bias=True) - net = models.resnet101(pretrained=use_pretrained) - net.fc = nn.Linear(in_features=2048, out_features=2, bias=True) + net = models.resnet18(pretrained=use_pretrained) + model_name = "ResNet18" + net.fc = nn.Linear(in_features=512, out_features=2, bias=True) + # net = models.resnet101(pretrained=use_pretrained) + # model_name = "ResNet101" + # net.fc = nn.Linear(in_features=2048, out_features=2, bias=True) # print(net) # sys.exit() - update_param_names = ["fc.weight", "fc.bias"] # 学習させるパラメータ名 + # 学習するレイヤーの指定 + update_param_names = [name for name, param in net.named_parameters() if "fc." in name] + update_layer = "FC" + # update_param_names = [name for name, param in net.named_parameters() if "fc." in name or "layer4" in name] + # update_layer = "FC and Layer4" # VGG16 # net = models.vgg16(pretrained=use_pretrained) + # model_name = "VGG16" # net.classifier[6] = nn.Linear(in_features=4096, out_features=2) # update_param_names = ["classifier.3.weight", "classifier.3.bias", "classifier.6.weight", "classifier.6.bias"] # update_param_names = ["classifier.6.weight", "classifier.6.bias"] @@ -300,9 +299,34 @@ # print(params_to_update) # 最適化手法の設定 - optimizer = optim.SGD(params=params_to_update, lr=0.001, momentum=0.9) + learning_rate = 0.001 + optimizer = optim.SGD(params=params_to_update, lr=learning_rate, momentum=0.9) # 学習・検証を実行する - num_epochs = 50 - train_model(net, dataloaders_dict, criterion, optimizer, num_epochs=num_epochs) + num_epochs = 10 + training_result = train_model(net, dataloaders_dict, criterion, optimizer, num_epochs) + + # 学習カーブを解析 + result_max = np.amax(training_result, axis=0)[1:] + result_min = np.amin(training_result, axis=0)[1:] + result_median = np.median(training_result, axis=0)[1:] + + # ログ出力 + f = open("{0:result%Y%m%d_%H%M%S.csv}".format(datetime.datetime.now()), 'w') + writer = csv.writer(f, lineterminator='\n') + writer.writerow(['Model','Update Layer','#Training','#Validation','Batch Size','Learning Rate','#Epoch','ValAccMax','ValAccMedian']) + writer.writerow([model_name, update_layer, num_traindata, num_valdata, batch_size, learning_rate, num_epochs, result_max[3], result_median[3]]) + writer.writerow([]) + writer.writerow(['epoch', 'train_loss', 'train_acc', 'val_loss', 'val_acc']) + np.savetxt(f, training_result, fmt=['%.0f', '%.4f', '%.4f', '%.4f', '%.4f'], delimiter=',', newline='\n') + writer.writerow([]) + f.write('max,') + np.savetxt(f, result_max.reshape((1, 4)), fmt='%.4f', delimiter=',', newline='\n') + f.write('min,') + np.savetxt(f, result_min.reshape((1, 4)), fmt='%.4f', delimiter=',', newline='\n') + f.write('median,') + np.savetxt(f, result_median.reshape((1, 4)), fmt='%.4f', delimiter=',', newline='\n') + + # 終了処理 + f.close() print('done.')