The Brief, and Looking at the Data
A dataset the course has not used, and the splits that keep the answer honest
Seventeen weeks of techniques, each measured on a problem chosen to show it working. This week is one problem worked end to end, on a dataset none of the earlier weeks used, so nothing here has been tuned in advance to make the course look good.
Fashion-MNIST is ten classes of clothing, the same shape and size as the digits, and considerably harder. It is a fair test of whether the habits transferred.
Look at the data before writing a model
import numpy as np
import torch
from torch import nn
from torch.utils.data import DataLoader, TensorDataset
from torchvision import datasets, transforms
# A dataset no earlier week used, so nothing here is tuned to it.
tf_ = transforms.ToTensor()
train_all = datasets.FashionMNIST('data', train=True, download=True,
transform=tf_)
test_all = datasets.FashionMNIST('data', train=False, download=True,
transform=tf_)
CLASSES = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
'sandal', 'shirt', 'sneaker', 'bag', 'boot']
def stack(ds, n, start=0):
xs = torch.stack([ds[i][0] for i in range(start, start + n)])
ys = torch.tensor([ds[i][1] for i in range(start, start + n)])
return xs, ys
xtr, ytr = stack(train_all, 12000)
xva, yva = stack(train_all, 3000, start=12000)
xte, yte = stack(test_all, 3000)
print('train %s val %s test %s'
% (tuple(xtr.shape), tuple(xva.shape), tuple(xte.shape)))
counts = torch.bincount(ytr, minlength=10)
print()
print('%-10s %8s' % ('class', 'count'))
for i, c in enumerate(CLASSES):
print('%-10s %8d' % (c, counts[i]))
print()
print('most common class is %.4f of the data'
% (counts.max().item() / len(ytr)))
class count
t-shirt 1122
trouser 1220
pullover 1201
dress 1212
coat 1181
sandal 1204
shirt 1244
sneaker 1192
bag 1195
boot 1229
most common class is 0.1037 of the data
Balanced, which means accuracy is a reasonable metric and the majority-class baseline will be about a tenth. If it had come back ninety percent one class, everything downstream would have needed to change, which is why this is the first thing to run rather than an afterthought.
Three splits, and the middle one is not optional
Training, validation and test. The validation set chooses the model and the epoch. The test set is looked at once, at the end. Every number in this week that says val was used to make a decision, and every number that says test was not.
Selecting on the test set is the most common way a reported result turns out to be optimistic, and it does not feel like cheating while you are doing it. It feels like iterating.
The brief
- Classify a garment image into one of ten categories.
- Twelve thousand labelled examples, which is few enough that generalisation is a real concern.
- The result has to be servable: exportable, and fast enough that a request is not noticeably waiting on it.
- Every claimed improvement has to survive the check that week 3 insisted on.