Fashion-MNIST时尚物品分类
In [1]:
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
In [2]:
train_data = datasets.FashionMNIST(root='data', train=True, download=True, transform=ToTensor())
test_data = datasets.FashionMNIST(root='data', train=False, download=True, transform=ToTensor())
In [3]:
batch_size = 64
train_dl = DataLoader(train_data, batch_size=batch_size, shuffle=True)
test_dl = DataLoader(test_data, batch_size=batch_size, shuffle=True)
In [4]:
images, labels = next(iter(train_data))
display(images.shape)
labels
torch.Size([1, 28, 28])
Out[4]:
9
In [5]:
plt.imshow(images[0].squeeze())
Out[5]:
<matplotlib.image.AxesImage at 0x1e2673644f0>

In [6]:
class Model(nn.Module):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.linear_selu_stack = nn.Sequential(
nn.Linear(28*28, 512),
nn.SELU(),
nn.Linear(512, 512),
nn.SELU(),
nn.Linear(512, 10)
)
def forward(self, x):
x = self.flatten(x)
return self.linear_selu_stack(x)
In [7]:
model = Model()
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
In [8]:
def train(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
model.train()
for batch, (X, y) in enumerate(dataloader):
pred = model(X)
loss = loss_fn(pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if batch%100 == 0:
loss, current = loss.item(), batch*len(X)
In [9]:
def test(dataloader, model, loss_fn):
size = len(dataloader.dataset)
num_batch = len(dataloader)
model.eval()
test_loss, correct = 0, 0
with torch.no_grad():
for X, y in dataloader:
pred = model(X)
test_loss += loss_fn(pred, y).item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= num_batch
correct /= size
return correct, test_loss
In [10]:
epochs = 10
for t in range(epochs):
train(train_dl, model, loss_fn, optimizer)
correct, test_loss = test(test_dl, model, loss_fn)
print('Epoch:', t+1, ' Accuracy:', round(correct*100, 2), ' Avg Loss:', round(test_loss, 5))
Epoch: 1 Accuracy: 82.49 Avg Loss: 0.46003 Epoch: 2 Accuracy: 84.79 Avg Loss: 0.42927 Epoch: 3 Accuracy: 84.72 Avg Loss: 0.41863 Epoch: 4 Accuracy: 86.33 Avg Loss: 0.38519 Epoch: 5 Accuracy: 84.8 Avg Loss: 0.42816 Epoch: 6 Accuracy: 86.44 Avg Loss: 0.3858 Epoch: 7 Accuracy: 86.78 Avg Loss: 0.37337 Epoch: 8 Accuracy: 87.14 Avg Loss: 0.35727 Epoch: 9 Accuracy: 87.54 Avg Loss: 0.38788 Epoch: 10 Accuracy: 87.98 Avg Loss: 0.36436
In [12]:
# 如上可以看出这是个很简单的问题,不用卷积神经网络也有很好的准确率
classes = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
pred = model(x)
predicted, actual = classes[pred[0].argmax(0)], classes[y]
print(f'Predicted: "{predicted}", Actual: "{actual}"')
Predicted: "Ankle boot", Actual: "Ankle boot"