PytorchのFashion-MNIST
Fashion-MNISTは、衣類の画像のデータセットです。
画像は、28×28ピクセルで、1チャネル(グレースケール画像)です。
Pytorchのライブラリなので、(データ数, 1チャンネル, 28, 28)のshapeになっている。
- 訓練データが、60,000枚
- テストデータが、10.00枚
- クラス数が、10クラス
ラベルと衣類の対応
ラベル | クラス |
---|---|
0 | Tシャツ |
1 | ズボン |
2 | プルオーバー |
3 | ドレス |
4 | コート |
5 | サンダル |
6 | シャツ |
7 | スニーカー |
8 | 靴 |
9 | アンクルブーツ |
Fashion-MNISTのデータロード
from torch.utils.data import Dataset, DataLoader, TensorDataset from torchvision.datasets import FashionMNIST from torchvision import transforms fashion_mnist_train = FashionMNIST("FashionMNIST", train=True, download=True, transform=transforms.ToTensor()) fashion_mnist_test = FashionMNIST("FashionMNIST", train=False, download=True, transform=transforms.ToTensor()) batch_size = 128 train_loader = DataLoader(fashion_mnist_train, batch_size=batch_size, shuffle=True) test_loader = DataLoader(fashion_mnist_test, batch_size=batch_size, shuffle=True) print(fashion_mnist_train) print(fashion_mnist_test)
Pytorchのサンプルプログラム
import torch from torch import nn, optim from torch.utils.data import Dataset, DataLoader, TensorDataset from torchvision.datasets import FashionMNIST from torchvision import transforms import matplotlib.pyplot as plt %matplotlib inline #データセット fashion_mnist_train = FashionMNIST("FashionMNIST", train=True, download=True, transform=transforms.ToTensor()) fashion_mnist_test = FashionMNIST("FashionMNIST", train=False, download=True, transform=transforms.ToTensor()) batch_size = 128 train_loader = DataLoader(fashion_mnist_train, batch_size=batch_size, shuffle=True) test_loader = DataLoader(fashion_mnist_test, batch_size=batch_size, shuffle=True) print(fashion_mnist_train) print(fashion_mnist_test) #ネットワークの定義 #ネットワークの定義 class net(nn.Module): def __init__(self): super(net,self).__init__() #畳み込み層 self.conv_layers = nn.Sequential( nn.Conv2d(in_channels = 1, out_channels = 16, kernel_size = 5, stride=1, padding=0), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(in_channels = 16, out_channels = 32, kernel_size = 5, stride=1, padding=0), nn.Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride=1, padding=0), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), ) #全結合層 self.dence = nn.Sequential( nn.Linear( 64* 2 *2, 128), nn.Dropout(p=0.2), nn.Linear(128, 128), nn.Linear(128, 64), nn.Dropout(p=0.2), nn.Linear(64, 10), ) #順伝播 def forward(self,x): out = self.conv_layers(x) #Flatten out = out.view(out.size(0), -1) #全結合層 out = self.dence(out) return out #畳み込み層の出力サイズのチェック def check_cnn_size(self, size_check): out = self.conv_layers(size_check) return out #デバイスの選択 device = 'cuda' if torch.cuda.is_available() else 'cpu' net = net().to(device) #全結合層の入力サイズの確認 size_check = torch.FloatTensor(10, 1, 28, 28) size_check = size_check.to(device) print(net.check_cnn_size(size_check).size()) #損失関数 criterion = nn.CrossEntropyLoss() #最適化 optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9, weight_decay=5e-4) num_epochs = 100 train_loss_list = [] train_acc_list = [] val_loss_list = [] val_acc_list = [] import time start = time.time() for epoch in range(num_epochs): train_loss = 0 train_acc = 0 val_loss = 0 val_acc = 0 #train net.train() for i, (images, labels) in enumerate(train_loader): images, labels = images.to(device), labels.to(device) optimizer.zero_grad() outputs = net.forward(images) loss = criterion(outputs, labels) train_loss += loss.item() train_acc += (outputs.max(1)[1] == labels).sum().item() loss.backward() optimizer.step() avg_train_loss = train_loss / len(train_loader.dataset) avg_train_acc = train_acc / len(train_loader.dataset) #val net.eval() with torch.no_grad(): for images, labels in test_loader: images = images.to(device) labels = labels.to(device) outputs = net.forward(images) loss = criterion(outputs, labels) val_loss += loss.item() val_acc += (outputs.max(1)[1] == labels).sum().item() avg_val_loss = val_loss / len(test_loader.dataset) avg_val_acc = val_acc / len(test_loader.dataset) print ('Epoch [{}/{}], Loss: {loss:.4f}, val_loss: {val_loss:.4f}, val_acc: {val_acc:.4f}' .format(epoch+1, num_epochs, i+1, loss=avg_train_loss, val_loss=avg_val_loss, val_acc=avg_val_acc)) train_loss_list.append(avg_train_loss) train_acc_list.append(avg_train_acc) val_loss_list.append(avg_val_loss) val_acc_list.append(avg_val_acc) end = time.time() - start print(end) plt.plot(train_acc_list, color='orange') plt.plot(val_acc_list) plt.legend plt.savefig('acc.png') plt.show
結果
訓練データとテストデータの正解率が乖離していることから、過学習が起こっていることがわかる。