PyTorchでCNNを実装し、画像認識をしようとしています。
Tutrialと同じCNNモデルを使用しています。
ですが、結果がおかしく、いつも、どれか一つの結果が100%でそのほかの結果は0%になってしまいます。どの部分が間違っているのか分かりません。
データロードの部分だけがtutrialと異なっている部分なので、そこがおかしいのかもしれません。おかしい箇所と直し方を教えていただけると幸いです。
PyTrochを使うのもDeep Learingを実装するのも初めてです。どうか優しく教えていただけると幸いです。よろしくお願いします。
試したこと:
モデルの数値の変更
モデル用のデータ自体を変更
Python3
1import os 2import csv 3from glob import glob 4from PIL import Image 5 6 7import pandas as pd 8import numpy as np 9import torch 10import torch.utils.data 11from torchvision import models, transforms, datasets, utils 12import matplotlib.pyplot as plt 13 14mean = np.array([0.4914, 0.4822, 0.4465]) 15std = np.array([0.2470, 0.2435, 0.2616]) 16 17transform = transforms.Compose([ 18 transforms.Resize(32), 19 transforms.CenterCrop(32), 20 transforms.ToTensor(), 21 transforms.Normalize(mean, std) 22 ]) 23data = datasets.ImageFolder(root='./traindata/', transform=transform) 24traindata, testdata = torch.utils.data.random_split(data, [20, 4]) 25trainloader = torch.utils.data.DataLoader(traindata, batch_size=4) 26 27classes = ("blue", "painting") 28 29# functions to show an image 30 31def imshow(img): 32 img = img / 2 + 0.5 # unnormalize 33 npimg = img.numpy() 34 plt.imshow(np.transpose(npimg, (1, 2, 0))) 35 plt.show() 36 37 38# get some random training images 39dataiter = iter(trainloader) 40images, labels = dataiter.next() 41 42# show images 43imshow(utils.make_grid(images)) 44# print labels 45print(' '.join('%5s' % classes[labels[j]] for j in range(4))) 46 47# defina a cnn 48import torch.nn as nn 49import torch.nn.functional as F 50 51class Net(nn.Module): 52 def __init__(self): 53 super(Net, self).__init__() 54 self.conv1 = nn.Conv2d(3, 6, 5) 55 self.pool = nn.MaxPool2d(2, 2) 56 self.conv2 = nn.Conv2d(6, 16, 5) 57 self.fc1 = nn.Linear(16 * 5 * 5, 120) 58 self.fc2 = nn.Linear(120, 84) 59 self.fc3 = nn.Linear(84, 2) 60 61 def forward(self, x): 62 x = self.pool(F.relu(self.conv1(x))) 63 x = self.pool(F.relu(self.conv2(x))) 64 x = x.view(-1, 16 * 5 * 5) 65 x = F.relu(self.fc1(x)) 66 x = F.relu(self.fc2(x)) 67 x = self.fc3(x) 68 return x 69 70net = Net() 71 72import torch.optim as optim 73 74criterion = nn.CrossEntropyLoss() 75optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) 76 77for epoch in range(2): # loop over the dataset multiple times 78 79 running_loss = 0.0 80 for i, data in enumerate(trainloader, 0): 81 # get hte inputs; data is a list of [inputs, labels] 82 inputs, labels = data 83 84 # zero the parameter gradients 85 optimizer.zero_grad() 86 87 # forward + backward + optimize 88 outputs = net(inputs) 89 loss = criterion(outputs, labels) 90 loss.backward() 91 optimizer.step() 92 93 # print statistics 94 running_loss += loss.item() 95 if i % 2000 == 1999: # print every 2000 mini-batches 96 print('[%d, %5d] loss: %.3f' % 97 (epoch + 1, i + 1, running_loss / 2000)) 98 running_loss = 0.0 99 100print('Finished Training') 101 102PATH = './test.pth' 103torch.save(net.state_dict(), PATH) 104 105# data = datasets.ImageFolder(root='./testdata/', transform=transform) 106testloader = torch.utils.data.DataLoader(testdata, batch_size=4) 107 108dataiter = iter(testloader) 109images, labels = dataiter.next() 110print(len(images)) 111 112# print images 113imshow(utils.make_grid(images)) 114print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4))) 115 116net = Net() 117net.load_state_dict(torch.load(PATH)) 118 119outputs = net(images) 120 121_, predicted = torch.max(outputs, 1) 122 123print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] 124 for j in range(4))) 125 126correct = 0 127total = 0 128with torch.no_grad(): 129 for data in testloader: 130 images, labels = data 131 outputs = net(images) 132 _, predicted = torch.max(outputs.data, 1) 133 total += labels.size(0) 134 correct += (predicted == labels).sum().item() 135 136print('Accuracy of the network on the 10000 test images: %d %%' % ( 137 100 * correct / total)) 138 139class_correct = list(0. for i in range(2)) 140class_total = list(0. for i in range(2)) 141with torch.no_grad(): 142 for data in testloader: 143 images, labels = data 144 outputs = net(images) 145 print(outputs) 146 i, predicted = torch.max(outputs, 1) 147 print("i", i) 148 print('predict', predicted) 149 print('labels', labels) 150 c = (predicted == labels).squeeze() 151 for i in range(2): 152 try: 153 label = labels[i] 154 class_correct[label] += c[i].item() 155 class_total[label] += 1 156 except: 157 break 158 159for i in range(2): 160 print(class_total[i]) 161 print('Accuracy of %5s : %2d %%' % ( 162 classes[i], 100 * class_correct[i] / class_total[i])) 163 164
参考にしたチュートリアルの URL を追記できますでしょうか?
> 結果がおかしく、いつも、どれか一つの結果が100%でそのほかの結果は0%になってしまいます
これは、訓練(学習)中のことでしょうか。それとも、推論時でしょうか。
https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py
これがチュートリアルのurlです。よろしくお願いします。
推論の結果です。
コードでは最後のprint文の結果になります。