前提・実現したいこと
CNN(ResNet18)を用いて、正常品か欠損品かを0,1で判断したい。
モデル学習後、未知データに対して推論を行うと推論結果が全て同じになる(全て0 or 全て1)
testデータ推論時に、正常品1,欠陥品0と出力されるようにしたい。
ハイパラメータの設定が上手くいっていないため出力がおかしなことになっていると考えている。
(学習率、モーメンタムなど、)
発生している問題・エラーメッセージ
filename,pred 1009937.jpeg,0 109996.jpeg,0 119892.jpeg,0 129893.jpeg,0 139981.jpeg,0 149997.jpeg,0 ....... ....... ....... 289969.jpeg,0 29934.jpeg,0 299953.jpeg,0 309928.jpeg,0 319945.jpeg,0 329953.jpeg,0
該当のソースコード
python
1# 事前学習無のResNet18作成 2from torchvision import models 3model_ft = models.resnet18(pretrained=False) 4 5# out_feature 書き換え 6import torch.nn as nn 7model_ft.fc = nn.Linear(in_features=512, out_features=2, bias=True) 8 9 10# 推論用データ整理 <-----------ここのハイパラメータの調整が上手くいっていないからと考えている。 11import torch.optim as optim 12model_ft = get_model(target_num=TARGET_NUM,isPretrained=False) 13optimizer = optim.SGD(model_ft.parameters(),lr=0.001, momentum=0.9) 14criterion = nn.CrossEntropyLoss() 15 16 17 18# モデル学習 19import torch 20import torch.nn as nn 21import torch.optim as optim 22from torch.utils.data import Dataset 23from torchvision import datasets, models, transforms 24from PIL import Image, ImageFilter 25# モデル訓練用関数 26def train_model(model, dataset_sizes, criterion, optimizer, num_epochs,is_saved = False): 27 best_acc = 0.0 28 # エポック数だけ下記工程の繰り返し 29 for epoch in range(num_epochs): 30 for phase in ['train', 'val']: 31 print('{}:フェイズ'.format(phase)) 32 # 訓練フェイズと検証フェイズの切り替え 33 if phase == 'train': 34 model.train() 35 else: 36 model.eval() 37 running_loss = 0.0 38 running_corrects = 0 39 # dataloadersからバッチサイズだけデータ取り出し、下記工程(1−5)の繰り返し 40 for i,(inputs, labels) in enumerate(image_dataloaders[phase]): 41 inputs = inputs.to(DEVICE) 42 labels = labels.to(DEVICE) 43 # 1. optimizerの勾配初期化 44 optimizer.zero_grad() 45 # 2.モデルに入力データをinputし、outputを取り出す 46 outputs = model(inputs) 47 _, preds = torch.max(outputs, 1) 48 # 3. outputと正解ラベルから、lossを算出 49 loss = criterion(outputs, labels) 50 print(' loaders:{}回目'.format(i+1) ,' loss:{}'.format(loss)) 51 if phase == 'train': 52 # 4. 誤差逆伝播法により勾配の算出 53 loss.backward() 54 # 5. optimizerのパラメータ更新 55 optimizer.step() 56 running_loss += loss.item() * inputs.size(0) 57 running_corrects += torch.sum(preds == labels.data) 58 59 #平均のlossを算出 60 epoch_loss = running_loss / len(dataset_sizes[phase].dataset) 61 #どれだけ正解していたのかAccuracyを求めている 62 epoch_acc = running_corrects.double() / len(dataset_sizes[phase].dataset) 63 print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc)) 64 # C. 今までのエポックでの精度よりも高い場合はモデルの保存 65 if phase == 'val' and epoch_acc > best_acc: 66 best_acc = epoch_acc 67 if(is_saved): 68 torch.save(model.state_dict(), './original_model_{}.pth'.format(epoch)) 69 print('Best val Acc: {:4f}'.format(best_acc)) 70 print('./original_model_{}.pth'.format(epoch)) 71 72 73 74# 未知データ推論、取り出し <------------------------この過程の前に,推論用データの前処理等は行っている。 75DEVICE='cpu' 76pred = [] 77for i,(inputs,labels) in enumerate(test_dataloader): 78 inputs = inputs.to(DEVICE) 79 # 学習済みモデルを推論モードに設定 80 loaded_model.eval() 81 # 学習済みモデルにデータをインプットし、推論をさせる 82 outputs = loaded_model(inputs) 83 # アウトプットから推定されたラベルを取得 84 _, preds = torch.max(outputs, 1) 85 # 事前に用意したリストに推論結果(0 or 1)を格納 86 pred.append(preds.item()) 87df_test['pred'] = pred
追加コード
python
1#train_Dataloader 2import torch 3image_dataloaders = { 4 'train': torch.utils.data.DataLoader(image_datasets['train'], batch_size=4,shuffle=True, num_workers=0, drop_last=True), 5 'val': torch.utils.data.DataLoader(image_datasets['val'], batch_size=4,shuffle=False, num_workers=0, drop_last=True), 6} 7train_dataloader = torch.utils.data.DataLoader(image_datasets['train'], 8 batch_size=4, 9 shuffle=True, 10 num_workers=0, 11 drop_last=True) 12val_dataloader = torch.utils.data.DataLoader(image_datasets['val'], 13 batch_size=4, 14 shuffle=False, 15 num_workers=0, 16 drop_last=True) 17 18 19#train_model呼び出し 20dataset_sizes = {'train':train_dataloader, 'val':val_dataloader} 21train_model(model_ft,dataset_sizes,criterion,optimizer,40,False) 22 23 24#学習済みmodelのロード,loaded_modelの定義 25import pickle 26import torch.nn as nn 27import torch 28from torchvision import datasets, models, transforms 29 30DEVICE= "cpu" 31def get_model(target_num,isPretrained=False): 32 model_ft = models.resnet18(pretrained=isPretrained) 33 model_ft.fc = nn.Linear(512, target_num) 34 model_ft = model_ft.to(DEVICE) 35 return model_ft 36best_model = get_model(target_num=2) 37# モデルを保存する 38modelname = './original_model_39.pth' 39pickle.dump(best_model, open(modelname, 'wb')) 40# 保存したモデルをロードする 41loaded_model = pickle.load(open(modelname, 'rb')) 42 43 44 45
回答1件
あなたの回答
tips
プレビュー