{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LEARNING APPLICATIONS\n",
    "\n",
    "In this notebook we will take a look at some indicative applications of machine learning techniques. We will cover content from [`learning.py`](https://github.com/aimacode/aima-python/blob/master/learning.py), for chapter 18 from Stuart Russel's and Peter Norvig's book [*Artificial Intelligence: A Modern Approach*](http://aima.cs.berkeley.edu/). Execute the cell below to get started:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [],
   "source": [
    "from learning import *\n",
    "from notebook import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CONTENTS\n",
    "\n",
    "* MNIST Handwritten Digits\n",
    "    * Loading and Visualising\n",
    "    * Testing\n",
    "* MNIST Fashion"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MNIST HANDWRITTEN DIGITS CLASSIFICATION\n",
    "\n",
    "The MNIST Digits database, available from [this page](http://yann.lecun.com/exdb/mnist/), is a large database of handwritten digits that is commonly used for training and testing/validating in Machine learning.\n",
    "\n",
    "The dataset has **60,000 training images** each of size 28x28 pixels with labels and **10,000 testing images** of size 28x28 pixels with labels.\n",
    "\n",
    "In this section, we will use this database to compare performances of different learning algorithms.\n",
    "\n",
    "It is estimated that humans have an error rate of about **0.2%** on this problem. Let's see how our algorithms perform!\n",
    "\n",
    "NOTE: We will be using external libraries to load and visualize the dataset smoothly ([numpy](http://www.numpy.org/) for loading and [matplotlib](http://matplotlib.org/) for visualization). You do not need previous experience of the libraries to follow along."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading MNIST Digits Data\n",
    "\n",
    "Let's start by loading MNIST data into numpy arrays.\n",
    "\n",
    "The function `load_MNIST()` loads MNIST data from files saved in `aima-data/MNIST`. It returns four numpy arrays that we are going to use to train and classify hand-written digits in various learning approaches."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_img, train_lbl, test_img, test_lbl = load_MNIST()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the shape of these NumPy arrays to make sure we have loaded the database correctly.\n",
    "\n",
    "Each 28x28 pixel image is flattened to a 784x1 array and we should have 60,000 of them in training data. Similarly, we should have 10,000 of those 784x1 arrays in testing data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training images size: (60000, 784)\n",
      "Training labels size: (60000,)\n",
      "Testing images size: (10000, 784)\n",
      "Testing labels size: (10000,)\n"
     ]
    }
   ],
   "source": [
    "print(\"Training images size:\", train_img.shape)\n",
    "print(\"Training labels size:\", train_lbl.shape)\n",
    "print(\"Testing images size:\", test_img.shape)\n",
    "print(\"Testing labels size:\", test_lbl.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualizing Data\n",
    "\n",
    "To get a better understanding of the dataset, let's visualize some random images for each class from training and testing datasets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 70020 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 80 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# takes 5-10 seconds to execute this\n",
    "show_MNIST(train_lbl, train_img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 72280 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 80 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# takes 5-10 seconds to execute this\n",
    "show_MNIST(test_lbl, test_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look at the average of all the images of training and testing data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Average of all images in training dataset.\n",
      "Digit 0 : 5923 images.\n",
      "Digit 1 : 6742 images.\n",
      "Digit 2 : 5958 images.\n",
      "Digit 3 : 6131 images.\n",
      "Digit 4 : 5842 images.\n",
      "Digit 5 : 5421 images.\n",
      "Digit 6 : 5918 images.\n",
      "Digit 7 : 6265 images.\n",
      "Digit 8 : 5851 images.\n",
      "Digit 9 : 5949 images.\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 17312 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Average of all images in testing dataset.\n",
      "Digit 0 : 980 images.\n",
      "Digit 1 : 1135 images.\n",
      "Digit 2 : 1032 images.\n",
      "Digit 3 : 1010 images.\n",
      "Digit 4 : 982 images.\n",
      "Digit 5 : 892 images.\n",
      "Digit 6 : 958 images.\n",
      "Digit 7 : 1028 images.\n",
      "Digit 8 : 974 images.\n",
      "Digit 9 : 1009 images.\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 17516 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(\"Average of all images in training dataset.\")\n",
    "show_ave_MNIST(train_lbl, train_img)\n",
    "\n",
    "print(\"Average of all images in testing dataset.\")\n",
    "show_ave_MNIST(test_lbl, test_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing\n",
    "\n",
    "Now, let us convert this raw data into `DataSet.examples` to run our algorithms defined in `learning.py`. Every image is represented by 784 numbers (28x28 pixels) and we append them with its label or class to make them work with our implementations in learning module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(60000, 784) (60000,)\n",
      "(60000, 785)\n"
     ]
    }
   ],
   "source": [
    "print(train_img.shape, train_lbl.shape)\n",
    "temp_train_lbl = train_lbl.reshape((60000,1))\n",
    "training_examples = np.hstack((train_img, temp_train_lbl))\n",
    "print(training_examples.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we will initialize a DataSet with our training examples, so we can use it in our algorithms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "# takes ~10 seconds to execute this\n",
    "MNIST_DataSet = DataSet(examples=training_examples, distance=manhattan_distance)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Moving forward we can use `MNIST_DataSet` to test our algorithms."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Plurality Learner\n",
    "\n",
    "The Plurality Learner always returns the class with the most training samples. In this case, `1`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "pL = PluralityLearner(MNIST_DataSet)\n",
    "print(pL(177))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Actual class of test image: 8\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x121c3d90>"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 4924 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "print(\"Actual class of test image:\", test_lbl[177])\n",
    "plt.imshow(test_img[177].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is obvious that this Learner is not very efficient. In fact, it will guess correctly in only 1135/10000 of the samples, roughly 10%. It is very fast though, so it might have its use as a quick first guess."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Naive-Bayes\n",
    "\n",
    "The Naive-Bayes classifier is an improvement over the Plurality Learner. It is much more accurate, but a lot slower."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n"
     ]
    }
   ],
   "source": [
    "# takes ~45 Secs. to execute this\n",
    "\n",
    "nBD = NaiveBayesLearner(MNIST_DataSet, continuous = False)\n",
    "print(nBD(test_img[0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To make sure that the output we got is correct, let's plot that image along with its label."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Actual class of test image: 7\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x571c8b0>"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 4660 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "print(\"Actual class of test image:\", test_lbl[0])\n",
    "plt.imshow(test_img[0].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### k-Nearest Neighbors\n",
    "\n",
    "We will now try to classify a random image from the dataset using the kNN classifier."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "# takes ~20 Secs. to execute this\n",
    "kNN = NearestNeighborLearner(MNIST_DataSet, k=3)\n",
    "print(kNN(test_img[211]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To make sure that the output we got is correct, let's plot that image along with its label."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Actual class of test image: 5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x12a87df0>"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 4940 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "print(\"Actual class of test image:\", test_lbl[211])\n",
    "plt.imshow(test_img[211].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Hurray! We've got it correct. Don't worry if our algorithm predicted a wrong class. With this techinique we have only ~97% accuracy on this dataset."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MNIST FASHION\n",
    "\n",
    "Another dataset in the same format is [MNIST Fashion](https://github.com/zalandoresearch/fashion-mnist/blob/master/README.md). This dataset, instead of digits contains types of apparel (t-shirts, trousers and others). As with the Digits dataset, it is split into training and testing images, with labels from 0 to 9 for each of the ten types of apparel present in the dataset. The below table shows what each label means:\n",
    "\n",
    "| Label | Description |\n",
    "| ----- | ----------- |\n",
    "|   0   | T-shirt/top |\n",
    "|   1   | Trouser     |\n",
    "|   2   | Pullover    |\n",
    "|   3   | Dress       |\n",
    "|   4   | Coat        |\n",
    "|   5   | Sandal      |\n",
    "|   6   | Shirt       |\n",
    "|   7   | Sneaker     |\n",
    "|   8   | Bag         |\n",
    "|   9   | Ankle boot  |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since both the MNIST datasets follow the same format, the code we wrote for loading and visualizing the Digits dataset will work for Fashion too! The only difference is that we have to let the functions know which dataset we're using, with the `fashion` argument. Let's start by loading the training and testing images:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_img, train_lbl, test_img, test_lbl = load_MNIST(fashion=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualizing Data\n",
    "\n",
    "Let's visualize some random images for each class, both for the training and testing sections:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 132912 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 80 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# takes 5-10 seconds to execute this\n",
    "show_MNIST(train_lbl, train_img, fashion=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 131664 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 80 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# takes 5-10 seconds to execute this\n",
    "show_MNIST(test_lbl, test_img, fashion=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's now see how many times each class appears in the training and testing data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Average of all images in training dataset.\n",
      "Apparel 0 : 6000 images.\n",
      "Apparel 1 : 6000 images.\n",
      "Apparel 2 : 6000 images.\n",
      "Apparel 3 : 6000 images.\n",
      "Apparel 4 : 6000 images.\n",
      "Apparel 5 : 6000 images.\n",
      "Apparel 6 : 6000 images.\n",
      "Apparel 7 : 6000 images.\n",
      "Apparel 8 : 6000 images.\n",
      "Apparel 9 : 6000 images.\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 28492 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Average of all images in testing dataset.\n",
      "Apparel 0 : 1000 images.\n",
      "Apparel 1 : 1000 images.\n",
      "Apparel 2 : 1000 images.\n",
      "Apparel 3 : 1000 images.\n",
      "Apparel 4 : 1000 images.\n",
      "Apparel 5 : 1000 images.\n",
      "Apparel 6 : 1000 images.\n",
      "Apparel 7 : 1000 images.\n",
      "Apparel 8 : 1000 images.\n",
      "Apparel 9 : 1000 images.\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 28972 characters]\n",
      "text/plain": [
       "<Figure size 1000x800 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(\"Average of all images in training dataset.\")\n",
    "show_ave_MNIST(train_lbl, train_img, fashion=True)\n",
    "\n",
    "print(\"Average of all images in testing dataset.\")\n",
    "show_ave_MNIST(test_lbl, test_img, fashion=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Unlike Digits, in Fashion all items appear the same number of times."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing\n",
    "\n",
    "We will now begin testing our algorithms on Fashion.\n",
    "\n",
    "First, we need to convert the dataset into the `learning`-compatible `Dataset` class:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [],
   "source": [
    "temp_train_lbl = train_lbl.reshape((60000,1))\n",
    "training_examples = np.hstack((train_img, temp_train_lbl))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [],
   "source": [
    "# takes ~10 seconds to execute this\n",
    "MNIST_DataSet = DataSet(examples=training_examples, distance=manhattan_distance)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Plurality Learner\n",
    "\n",
    "The Plurality Learner always returns the class with the most training samples. In this case, `9`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9\n"
     ]
    }
   ],
   "source": [
    "pL = PluralityLearner(MNIST_DataSet)\n",
    "print(pL(177))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Actual class of test image: 0\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x56e9ad0>"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 6092 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "print(\"Actual class of test image:\", test_lbl[177])\n",
    "plt.imshow(test_img[177].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Naive-Bayes\n",
    "\n",
    "The Naive-Bayes classifier is an improvement over the Plurality Learner. It is much more accurate, but a lot slower."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n"
     ]
    }
   ],
   "source": [
    "# takes ~45 Secs. to execute this\n",
    "\n",
    "nBD = NaiveBayesLearner(MNIST_DataSet, continuous = False)\n",
    "print(nBD(test_img[24]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's check if we got the right output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Actual class of test image: 1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x1dadc8d0>"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 5304 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "print(\"Actual class of test image:\", test_lbl[24])\n",
    "plt.imshow(test_img[24].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### K-Nearest Neighbors\n",
    "\n",
    "With the dataset in hand, we will first test how the kNN algorithm performs:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "# takes ~20 Secs. to execute this\n",
    "kNN = NearestNeighborLearner(MNIST_DataSet, k=3)\n",
    "print(kNN(test_img[211]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The output is 1, which means the item at index 211 is a trouser. Let's see if the prediction is correct:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Actual class of test image: 1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x1dc87370>"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 5296 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "print(\"Actual class of test image:\", test_lbl[211])\n",
    "plt.imshow(test_img[211].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Indeed, the item was a trouser! The algorithm classified the item correctly."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
