<jupyter_start><jupyter_text>The Image Classification Dataset:label:`sec_fashion_mnist`One of the widely used dataset for image classification is the  MNIST dataset :cite:`LeCun.Bottou.Bengio.ea.1998`.While it had a good run as a benchmark dataset,even simple models by today's standards achieve classification accuracy over 95%,making it unsuitable for distinguishing between stronger models and weaker ones.Today, MNIST serves as more of sanity checks than as a benchmark.To up the ante just a bit, we will focus our discussion in the coming sectionson the qualitatively similar, but comparatively complex Fashion-MNISTdataset :cite:`Xiao.Rasul.Vollgraf.2017`, which was released in 2017.<jupyter_code>%matplotlib inline
from d2l import torch as d2l
import torch
import torchvision
from torchvision import transforms
from torch.utils import data

d2l.use_svg_display()<jupyter_output><empty_output><jupyter_text>Reading the DatasetWe can download and read the Fashion-MNIST dataset into memory via the build-in functions in the framework.<jupyter_code># `ToTensor` converts the image data from PIL type to 32-bit floating point
# tensors. It divides all numbers by 255 so that all pixel values are between
# 0 and 1
trans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(
    root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(
    root="../data", train=False, transform=trans, download=True)<jupyter_output><empty_output><jupyter_text>Fashion-MNIST consists of images from 10 categories, each representedby 6000 images in the training dataset and by 1000 in the test dataset.A *test dataset* (or *test set*) is used for evaluating  model performance and not for training.Consequently the training set and the test setcontain 60000 and 10000 images, respectively.<jupyter_code>len(mnist_train), len(mnist_test)<jupyter_output><empty_output><jupyter_text>The height and width of each input image are both 28 pixels.Note that the dataset consists of grayscale images, whose number of channels is 1.For brevity, throughout this bookwe store the shape of any image with height $h$ width $w$ pixels as $h \times w$ or ($h$, $w$).<jupyter_code>mnist_train[0][0].shape<jupyter_output><empty_output><jupyter_text>The images in Fashion-MNIST are associated with the following categories:t-shirt, trousers, pullover, dress, coat, sandal, shirt, sneaker, bag, and ankle boot.The following function converts between numeric label indices and their names in text.<jupyter_code>def get_fashion_mnist_labels(labels):  #@save
    """Return text labels for the Fashion-MNIST dataset."""
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]<jupyter_output><empty_output><jupyter_text>We can now create a function to visualize these examples.<jupyter_code>def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
    """Plot a list of images."""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        if torch.is_tensor(img):
            # Tensor Image
            ax.imshow(img.numpy())
        else:
            # PIL Image
            ax.imshow(img)
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            ax.set_title(titles[i])
    return axes<jupyter_output><empty_output><jupyter_text>Here are the images and their corresponding labels (in text)for the first few examples in the training dataset.<jupyter_code>X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));<jupyter_output><empty_output><jupyter_text>Reading a MinibatchTo make our life easier when reading from the training and test sets,we use the built-in data iterator rather than creating one from scratch.Recall that at each iteration, a data loaderreads a minibatch of data with size `batch_size` each time.We also randomly shuffle the examples for the training data iterator.<jupyter_code>batch_size = 256

def get_dataloader_workers():  #@save
    """Use 4 processes to read the data."""
    return 4

train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,
                             num_workers=get_dataloader_workers())<jupyter_output><empty_output><jupyter_text>Let us look at the time it takes to read the training data.<jupyter_code>timer = d2l.Timer()
for X, y in train_iter:
    continue
f'{timer.stop():.2f} sec'<jupyter_output><empty_output><jupyter_text>Putting All Things TogetherNow we define the `load_data_fashion_mnist` functionthat obtains and reads the Fashion-MNIST dataset.It returns the data iterators for both the training set and validation set.In addition, it accepts an optional argument to resize images to another shape.<jupyter_code>def load_data_fashion_mnist(batch_size, resize=None):  #@save
    """Download the Fashion-MNIST dataset and then load it into memory."""
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root="../data", train=True, transform=trans, download=True)
    mnist_test = torchvision.datasets.FashionMNIST(
        root="../data", train=False, transform=trans, download=True)
    return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                            num_workers=get_dataloader_workers()),
            data.DataLoader(mnist_test, batch_size, shuffle=False,
                            num_workers=get_dataloader_workers()))<jupyter_output><empty_output><jupyter_text>Below we test the image resizing feature of the `load_data_fashion_mnist` functionby specifying the `resize` argument.<jupyter_code>train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break<jupyter_output>torch.Size([32, 1, 64, 64]) torch.float32 torch.Size([32]) torch.int64
{'fraction_non_alphanumeric': 0.09186771049688448, 'fraction_numerical': 0.01389998402300687, 'mean_word_length': 4.823255813953488, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '18027', 'license': 'MIT', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1857, 'n_words': 604, 'path': 'd2l-en/pytorch/chapter_linear-networks/image-classification-dataset.ipynb', 'repo_name': 'gr8khan/d2lai', 'size': '6259'}