やりたいこと
もともとやろうとしていることは、pytorchを用いた犬と猫の分類問題となっていて、
画像データは256x256x3である。
以下のディレクトリ構成で格納されている。
├─animal_dataset ├─train │ ├─cat(70枚くらい) │ └─dog(70枚くらい) └─val ├─cat(30枚くらい) └─dog(30枚くらい)
学習用データセット(train)と評価用データセット(valid)をdatasetの実装の際に作成した。
それらをもとにモデルを作成し、その後損失関数の収束させるのを確認した、それらをもとに学習後のモデルパラメータを今回のソースコードに埋め込んで評価をしたつもりです。
これらから、validatioの正解率とtrainの正解率を見比べて確かめたい
確かめる方法としては、validとtrainの同時にグラフに起こして、確認できると好ましいのでそれらを同時にグラフにするコードの書き方が知りたい。(epochごとなのかな...)
ただ、そもそも手打ちで精度を見たところtrainが100%ってどういうこと??って状態です....
ソースコード(eval.py)
実行ファイルです。
推論をするためのファイルです。
eval.py
1import torch 2import torch.nn as nn 3import torch.nn.functional as F 4 5import torch.optim as optim 6import model,dataset 7from model import * 8 9from tqdm import tqdm 10from torch.autograd import Variable 11 12 13import numpy as np 14from matplotlib import pyplot as plt 15 16 17device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 18 19if __name__ == "__main__": 20 # modelの定義 21 model = model.Net().to(device) 22 # 推論モード 23 model.eval() 24 25 # optimizerの定義 26 optimizer = torch.optim.SGD( 27 model.parameters(), lr=0.0001, momentum=0.9, weight_decay=0.0001) 28 #パラメータの読み込み 29 model.load_state_dict(torch.load("model_cpu.pth", map_location=device)) 30 31 # training 32 train_dataset = dataset.MyDatasets( 33 root_dir="./animal_dataset", 34 key="train", 35 ) 36 train_loader = torch.utils.data.DataLoader( 37 dataset=train_dataset, 38 batch_size=4, 39 shuffle= True 40 ) 41 42 # validationのデータセット 43 valid_dataset = dataset.MyDatasets( 44 root_dir="./animal_dataset", 45 key="val", 46 ) 47 48 valid_loader = torch.utils.data.DataLoader( 49 dataset=valid_dataset, 50 batch_size=4, 51 shuffle= True 52 ) 53 # 評価関数の作成 54 55 56 57 acc = [] 58 num_epoch = 100 59 for epoch in range(num_epoch): 60 correct = 0 #val_acc 61 total = 0 62 with torch.no_grad(): 63 for data in valid_loader: 64 inputs, labels = data[0].to(device), data[1].to(device) 65 # print("label={}".format(labels)) 66 # print("inputs={}".format(inputs)) 67 68 outputs = model(inputs).to(device) 69 70 # 確率 71 _, predicted = torch.max(outputs.data, 1) 72 total += labels.size(0) 73 correct += (predicted == labels).sum().item() 74 acc.append(float(correct/total)) 75 76 print("Accuracy of the network on the 100 test images: %d/%d = %.1f" % (correct, total, 100*correct/len(valid_loader.dataset))) 77 78 79 80 81 plt.figure() 82 plt.plot(range(num_epoch), acc, color='blue',linestyle='-',label='acc') 83 plt.legend() 84 plt.xlabel('epoch') 85 plt.ylabel('acc') 86 plt.grid() 87 plt.savefig("acc.png") 88 89
実行結果
一応、グラフを作ってみました。(追記)
以下の部分をvalid_loader(評価用)でループを回したとき
with torch.no_grad(): for data in valid_loader:
かなり精度はあれですが、こんな感じです。
Accuracy of the network on the 100 test images: 30/54 = 55.6
以下の部分をtrain_loader(評価用)でループを回したとき
with torch.no_grad(): for data in train_loader:
100%っておかしくないか....
Accuracy of the network on the 100 test images: 129/129 = 100.0
追記
前処理を行っているdataset.pyの添付ファイルをのせます。
import glob import os from PIL import Image from torch.utils import data as data from torchvision import transforms as transforms transform = transforms.Compose([ transforms.Resize((256, 256)), transforms.ToTensor(), transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)), # transforms.RandomHorizontalFlip(), # transforms.RandomVerticalFlip(), # transforms.RandomRotation(degrees=30) ]) class MyDatasets(data.Dataset): def __init__(self, root_dir, key): self.transform = transform self.data = [] self.labels = [] name_to_label = {"cat": 0, "dog": 1} target_dir = os.path.join(root_dir, key, "**/*") for path in glob.glob(target_dir): name = os.path.basename(os.path.dirname(path)) label = name_to_label[name] self.data.append(path) self.labels.append(label) def __len__(self): return len(self.data) def __getitem__(self, index): img_path = self.data[index] label = self.labels[index] img = Image.open(img_path).convert("RGB") img = self.transform(img) return img, label if __name__ == "__main__": train_dataset = MyDatasets("./animal_dataset", "train") train_dataloader = data.DataLoader(train_dataset, batch_size=4, shuffle= True) for data, labels in train_dataloader: print(data.shape, labels.shape) datas, labels = iter(train_dataloader).next() # print(datas[0].shape) s=10 pic = transforms.ToPILImage(mode='RGB')(datas[s]) pic.save('./result.jpg') if labels[s].numpy() == 0: print("label: cat") else: print("label: dog")
なんかしっかり前処理できているか不安になりました。
最後に
このような結果になってしまい、動作の正しさを確認したいと思っています。
もしかしたら、ソースコードが間違っているのであれば修正点を教えていただけるとありがたいです。
また、可能でありましたらepochごとのtrainとvalidの精度(accuracy)をグラフに起こした処理の書き方も知れたらうれしいです。
参考にしたソースコードはどれもphase==train or validのようなものだったり、lossと同時に行っていて精度だけを確認できるコードが見つかりません。
もし不足している情報や説明に足り部分がありましたらご指摘くださると感謝します。
どうかよろしくお願いします。
あなたの回答
tips
プレビュー