|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "# Classifying Fashion-MNIST\n", |
| 8 | + "\n", |
| 9 | + "Now it's your turn to build and train a neural network. You'll be using the [Fashion-MNIST dataset](https://github.com/zalandoresearch/fashion-mnist), a drop-in replacement for the MNIST dataset. MNIST is actually quite trivial with neural networks where you can easily achieve better than 97% accuracy. Fashion-MNIST is a set of 28x28 greyscale images of clothes. It's more complex than MNIST, so it's a better representation of the actual performance of your network, and a better representation of datasets you'll use in the real world.\n", |
| 10 | + "\n", |
| 11 | + "<img src='assets/fashion-mnist-sprite.png' width=500px>\n", |
| 12 | + "\n", |
| 13 | + "In this notebook, you'll build your own neural network. For the most part, you could just copy and paste the code from Part 3, but you wouldn't be learning. It's important for you to write the code yourself and get it to work. Feel free to consult the previous notebook though as you work through this.\n", |
| 14 | + "\n", |
| 15 | + "First off, let's load the dataset through torchvision." |
| 16 | + ] |
| 17 | + }, |
| 18 | + { |
| 19 | + "cell_type": "code", |
| 20 | + "execution_count": null, |
| 21 | + "metadata": {}, |
| 22 | + "outputs": [], |
| 23 | + "source": [ |
| 24 | + "import torch\n", |
| 25 | + "from torchvision import datasets, transforms\n", |
| 26 | + "import helper\n", |
| 27 | + "\n", |
| 28 | + "# Define a transform to normalize the data\n", |
| 29 | + "transform = transforms.Compose([transforms.ToTensor(),\n", |
| 30 | + " transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n", |
| 31 | + "# Download and load the training data\n", |
| 32 | + "trainset = datasets.FashionMNIST('F_MNIST_data/', download=True, train=True, transform=transform)\n", |
| 33 | + "trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)\n", |
| 34 | + "\n", |
| 35 | + "# Download and load the test data\n", |
| 36 | + "testset = datasets.FashionMNIST('F_MNIST_data/', download=True, train=False, transform=transform)\n", |
| 37 | + "testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=True)" |
| 38 | + ] |
| 39 | + }, |
| 40 | + { |
| 41 | + "cell_type": "markdown", |
| 42 | + "metadata": {}, |
| 43 | + "source": [ |
| 44 | + "Here we can see one of the images." |
| 45 | + ] |
| 46 | + }, |
| 47 | + { |
| 48 | + "cell_type": "code", |
| 49 | + "execution_count": null, |
| 50 | + "metadata": {}, |
| 51 | + "outputs": [], |
| 52 | + "source": [ |
| 53 | + "image, label = next(iter(trainloader))\n", |
| 54 | + "helper.imshow(image[0,:]);" |
| 55 | + ] |
| 56 | + }, |
| 57 | + { |
| 58 | + "cell_type": "markdown", |
| 59 | + "metadata": {}, |
| 60 | + "source": [ |
| 61 | + "With the data loaded, it's time to import the necessary packages." |
| 62 | + ] |
| 63 | + }, |
| 64 | + { |
| 65 | + "cell_type": "code", |
| 66 | + "execution_count": 1, |
| 67 | + "metadata": {}, |
| 68 | + "outputs": [], |
| 69 | + "source": [ |
| 70 | + "%matplotlib inline\n", |
| 71 | + "%config InlineBackend.figure_format = 'retina'\n", |
| 72 | + "\n", |
| 73 | + "import matplotlib.pyplot as plt\n", |
| 74 | + "import numpy as np\n", |
| 75 | + "import time\n", |
| 76 | + "\n", |
| 77 | + "import torch\n", |
| 78 | + "from torch import nn\n", |
| 79 | + "from torch import optim\n", |
| 80 | + "import torch.nn.functional as F\n", |
| 81 | + "from torchvision import datasets, transforms\n", |
| 82 | + "\n", |
| 83 | + "import helper" |
| 84 | + ] |
| 85 | + }, |
| 86 | + { |
| 87 | + "cell_type": "markdown", |
| 88 | + "metadata": {}, |
| 89 | + "source": [ |
| 90 | + "## Building the network\n", |
| 91 | + "\n", |
| 92 | + "Here you should define your network. As with MNIST, each image is 28x28 which is a total of 784 pixels, and there are 10 classes. You should include at least one hidden layer. We suggest you use ReLU activations for the layers and to return the logits from the forward pass. It's up to you how many layers you add and the size of those layers." |
| 93 | + ] |
| 94 | + }, |
| 95 | + { |
| 96 | + "cell_type": "code", |
| 97 | + "execution_count": null, |
| 98 | + "metadata": {}, |
| 99 | + "outputs": [], |
| 100 | + "source": [ |
| 101 | + "# TODO: Define your network architecture here" |
| 102 | + ] |
| 103 | + }, |
| 104 | + { |
| 105 | + "cell_type": "markdown", |
| 106 | + "metadata": {}, |
| 107 | + "source": [ |
| 108 | + "# Train the network\n", |
| 109 | + "\n", |
| 110 | + "Now you should create your network and train it. First you'll want to define [the criterion](http://pytorch.org/docs/master/nn.html#loss-functions) ( something like `nn.CrossEntropyLoss`) and [the optimizer](http://pytorch.org/docs/master/optim.html) (typically `optim.SGD` or `optim.Adam`).\n", |
| 111 | + "\n", |
| 112 | + "Then write the training code. Remember the training pass is a fairly straightforward process:\n", |
| 113 | + "\n", |
| 114 | + "* Make a forward pass through the network to get the logits \n", |
| 115 | + "* Use the logits to calculate the loss\n", |
| 116 | + "* Perform a backward pass through the network with `loss.backward()` to calculate the gradients\n", |
| 117 | + "* Take a step with the optimizer to update the weights\n", |
| 118 | + "\n", |
| 119 | + "By adjusting the hyperparameters (hidden units, learning rate, etc), you should be able to get the training loss below 0.4." |
| 120 | + ] |
| 121 | + }, |
| 122 | + { |
| 123 | + "cell_type": "code", |
| 124 | + "execution_count": null, |
| 125 | + "metadata": {}, |
| 126 | + "outputs": [], |
| 127 | + "source": [ |
| 128 | + "# TODO: Create the network, define the criterion and optimizer\n" |
| 129 | + ] |
| 130 | + }, |
| 131 | + { |
| 132 | + "cell_type": "code", |
| 133 | + "execution_count": null, |
| 134 | + "metadata": {}, |
| 135 | + "outputs": [], |
| 136 | + "source": [ |
| 137 | + "# TODO: Train the network here\n" |
| 138 | + ] |
| 139 | + }, |
| 140 | + { |
| 141 | + "cell_type": "code", |
| 142 | + "execution_count": null, |
| 143 | + "metadata": {}, |
| 144 | + "outputs": [], |
| 145 | + "source": [ |
| 146 | + "# Test out your network!\n", |
| 147 | + "\n", |
| 148 | + "dataiter = iter(testloader)\n", |
| 149 | + "images, labels = dataiter.next()\n", |
| 150 | + "img = images[0]\n", |
| 151 | + "# Convert 2D image to 1D vector\n", |
| 152 | + "img = img.resize_(1, 784)\n", |
| 153 | + "\n", |
| 154 | + "# TODO: Calculate the class probabilities (softmax) for img\n", |
| 155 | + "ps = \n", |
| 156 | + "\n", |
| 157 | + "# Plot the image and probabilities\n", |
| 158 | + "helper.view_classify(img.resize_(1, 28, 28), ps, version='Fashion')" |
| 159 | + ] |
| 160 | + }, |
| 161 | + { |
| 162 | + "cell_type": "markdown", |
| 163 | + "metadata": {}, |
| 164 | + "source": [ |
| 165 | + "Now that your network is trained, you'll want to save it to disk so you can load it later instead of training it again. Obviously, it's impractical to train a network every time you need one. In practice, you'll train it once, save the model, then reload it for further training or making predictions. In the next part, I'll show you how to save and load trained models." |
| 166 | + ] |
| 167 | + } |
| 168 | + ], |
| 169 | + "metadata": { |
| 170 | + "kernelspec": { |
| 171 | + "display_name": "Python 3", |
| 172 | + "language": "python", |
| 173 | + "name": "python3" |
| 174 | + }, |
| 175 | + "language_info": { |
| 176 | + "codemirror_mode": { |
| 177 | + "name": "ipython", |
| 178 | + "version": 3 |
| 179 | + }, |
| 180 | + "file_extension": ".py", |
| 181 | + "mimetype": "text/x-python", |
| 182 | + "name": "python", |
| 183 | + "nbconvert_exporter": "python", |
| 184 | + "pygments_lexer": "ipython3", |
| 185 | + "version": "3.6.4" |
| 186 | + } |
| 187 | + }, |
| 188 | + "nbformat": 4, |
| 189 | + "nbformat_minor": 2 |
| 190 | +} |
0 commit comments