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
結果
訓練データとテストデータの正解率が乖離していることから、過学習が起こっていることがわかる。
