{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9yupXUk1DKOe"
   },
   "source": [
    "# MNIST from scratch\n",
    "\n",
    "This notebook walks through an example of training a TensorFlow model to do digit classification using the [MNIST data set](http://yann.lecun.com/exdb/mnist/). MNIST is a labeled set of images of handwritten digits.\n",
    "\n",
    "An example follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:20.863031",
     "start_time": "2016-09-16T14:49:20.818734"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "id": "sbUKaF8_uDI_",
    "outputId": "67a51332-3aea-4c29-8c3d-4752db08ccb3"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.5/site-packages/ipykernel/__main__.py:5: DeprecationWarning: decodestring() is a deprecated alias, use decodebytes()\n"
     ]
    },
    {
     "data": {
      "image/png": "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\ngUDg/wHX+3lgThDIegAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from __future__ import print_function\n",
    "\n",
    "from IPython.display import Image\n",
    "import base64\n",
    "Image(data=base64.decodestring(\"[encoded data, 8472 characters]\".encode('utf-8')), embed=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "J0QZYD_HuDJF"
   },
   "source": [
    "We're going to be building a model that recognizes these digits as 5, 0, and 4.\n",
    "\n",
    "# Imports and input data\n",
    "\n",
    "We'll proceed in steps, beginning with importing and inspecting the MNIST data. This doesn't have anything to do with TensorFlow in particular -- we're just downloading the data archive."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:20.958307",
     "start_time": "2016-09-16T14:49:20.864840"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 110,
     "status": "ok",
     "timestamp": 1446749124399,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "w5vKZqr6CDz9",
    "outputId": "794eac6d-a918-4888-e8cf-a8628474d7f1"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Already downloaded train-images-idx3-ubyte.gz\n",
      "Already downloaded train-labels-idx1-ubyte.gz\n",
      "Already downloaded t10k-images-idx3-ubyte.gz\n",
      "Already downloaded t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from six.moves.urllib.request import urlretrieve\n",
    "\n",
    "SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'\n",
    "WORK_DIRECTORY = \"/tmp/mnist-data\"\n",
    "\n",
    "def maybe_download(filename):\n",
    "    \"\"\"A helper to download the data files if not present.\"\"\"\n",
    "    if not os.path.exists(WORK_DIRECTORY):\n",
    "        os.mkdir(WORK_DIRECTORY)\n",
    "    filepath = os.path.join(WORK_DIRECTORY, filename)\n",
    "    if not os.path.exists(filepath):\n",
    "        filepath, _ = urlretrieve(SOURCE_URL + filename, filepath)\n",
    "        statinfo = os.stat(filepath)\n",
    "        print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.')\n",
    "    else:\n",
    "        print('Already downloaded', filename)\n",
    "    return filepath\n",
    "\n",
    "train_data_filename = maybe_download('train-images-idx3-ubyte.gz')\n",
    "train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz')\n",
    "test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz')\n",
    "test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "gCtMhpIoC84F"
   },
   "source": [
    "## Working with the images\n",
    "\n",
    "Now we have the files, but the format requires a bit of pre-processing before we can work with it. The data is gzipped, requiring us to decompress it. And, each of the images are grayscale-encoded with values from [0, 255]; we'll normalize these to [-0.5, 0.5].\n",
    "\n",
    "Let's try to unpack the data using the documented format:\n",
    "\n",
    "    [offset] [type]          [value]          [description] \n",
    "    0000     32 bit integer  0x00000803(2051) magic number \n",
    "    0004     32 bit integer  60000            number of images \n",
    "    0008     32 bit integer  28               number of rows \n",
    "    0012     32 bit integer  28               number of columns \n",
    "    0016     unsigned byte   ??               pixel \n",
    "    0017     unsigned byte   ??               pixel \n",
    "    ........ \n",
    "    xxxx     unsigned byte   ??               pixel\n",
    "    \n",
    "Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).\n",
    "\n",
    "We'll start by reading the first image from the test data as a sanity check."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:22.112407",
     "start_time": "2016-09-16T14:49:20.960204"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 57,
     "status": "ok",
     "timestamp": 1446749125010,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "P_3Fm5BpFMDF",
    "outputId": "c8e777e0-d891-4eb1-a178-9809f293cc28"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "magic number 2051\n",
      "image count 10000\n",
      "rows 28\n",
      "columns 28\n",
      "First 10 pixels: [0 0 0 0 0 0 0 0 0 0]\n"
     ]
    }
   ],
   "source": [
    "import gzip, binascii, struct, numpy\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "with gzip.open(test_data_filename) as f:\n",
    "    # Print the header fields.\n",
    "    for field in ['magic number', 'image count', 'rows', 'columns']:\n",
    "        # struct.unpack reads the binary data provided by f.read.\n",
    "        # The format string '>i' decodes a big-endian integer, which\n",
    "        # is the encoding of the data.\n",
    "        print(field, struct.unpack('>i', f.read(4))[0])\n",
    "    \n",
    "    # Read the first 28x28 set of pixel values. \n",
    "    # Each pixel is one byte, [0, 255], a uint8.\n",
    "    buf = f.read(28 * 28)\n",
    "    image = numpy.frombuffer(buf, dtype=numpy.uint8)\n",
    "  \n",
    "    # Print the first few values of image.\n",
    "    print('First 10 pixels:', image[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "7NXKCQENNRQT"
   },
   "source": [
    "The first 10 pixels are all 0 values. Not very interesting, but also unsurprising. We'd expect most of the pixel values to be the background color, 0.\n",
    "\n",
    "We could print all 28 * 28 values, but what we really need to do to make sure we're reading our data properly is look at an image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:22.525418",
     "start_time": "2016-09-16T14:49:22.114324"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 887,
     "status": "ok",
     "timestamp": 1446749126640,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "F_5w-cOoNLaG",
    "outputId": "77dabc81-e3ee-4fcf-ac72-88038494fb6c"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f84680e3fd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "# We'll show the image and its pixel value histogram side-by-side.\n",
    "_, (ax1, ax2) = plt.subplots(1, 2)\n",
    "\n",
    "# To interpret the values as a 28x28 image, we need to reshape\n",
    "# the numpy array, which is one dimensional.\n",
    "ax1.imshow(image.reshape(28, 28), cmap=plt.cm.Greys);\n",
    "\n",
    "ax2.hist(image, bins=20, range=[0,255]);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "weVoVR-nN0cN"
   },
   "source": [
    "The large number of 0 values correspond to the background of the image, another large mass of value 255 is black, and a mix of grayscale transition values in between.\n",
    "\n",
    "Both the image and histogram look sensible. But, it's good practice when training image models to normalize values to be centered around 0.\n",
    "\n",
    "We'll do that next. The normalization code is fairly short, and it may be tempting to assume we haven't made mistakes, but we'll double-check by looking at the rendered input and histogram again. Malformed inputs are a surprisingly common source of errors when developing new models."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:22.895369",
     "start_time": "2016-09-16T14:49:22.527595"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 531,
     "status": "ok",
     "timestamp": 1446749126656,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "jc1xCZXHNKVp",
    "outputId": "bd45b3dd-438b-41db-ea8f-d202d4a09e63"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nR6FQKPn86OjoilWXjdw4aGZmpmx7nrogl1+VsNyF+8iRI6tY9vhLLC39vysGvc1M4UBE1ms30Awc\nyzx+DHhmide0w/q+Xf3Hf/xHfG8I2FXirEfi28fKvNPXALj88svLfl5ra4H3vOfP2b17d+7zjz3m\nP+NOoiCQdd+GtWV4eJg/+IM/ZGFhtuz7RGPSl8qesVLVZaW2QPQte2mp/OesdM7w8DD33PNPK7Yn\nUurv4GuArfj7jZT7e3o0vv2/gVJdRI8A/1imLU99xnr+Pwhe277mN8lhzrlqvp+IbDNmdhrwfeBC\n59wDwePXAT/pnPu/cl7z68BHNq6VIlvea5xzH63Wm6lyICLrNUxUu9+XeXwvy6sJ3t3Aa4DvACt9\nvRWR0tqBc4j+n6oaVQ5EZN3M7CvAA865N8c/G/A4cKNz7j11bZyIVEyVAxGphuuBD5vZQzw1lbET\n+FA9GyUia6NwICLr5py73cx2A+8i6l74OnCJc+5EfVsmImuhbgURERFJ0d4KIiIikqJwICIiIikK\nByJSc2bWb2YfMbOimY2a2d+aWdcqXnehmd1jZpPxaz9vZqWX9Ktxe4LXf9rMlszsso1uS3z+jWb2\nLTObMrPvmtlfmlnPGj77KjN7zMxmzOwrZvb8Fc7/L2Z2JD7/YTN7eaWfWa32mNnrzeyLZjYSH59d\nqf21akvmda+O/9v4h3q1xcx6zewmM3syfs23zOxllXymwoGIbISPEq1FezHRngsvBt5f7gVmdiHw\naeAu4Hnx8T5WWtKvRu0J2nWQaF2Hag3YqrQtpxMty/d7wI8CvwG8DPjbSj402CzrauC5RDtp3h0P\nLM07/8K4rX8D/ATwv4D/ZWbPquRzq9Ue4Kfi9rwEuAB4AvhMvCjXRrfFv+5s4D3AF9fbhrW2JV7O\n/HPAWcAvE61S+ptEC5WtnnNOhw4dOmp2AD9CdEF/bvDYJcAisL/M6+4HrmmU9sTnPQf4LtECT0vA\nZfVqS+Z9fgWYAZoqeM1XgL8Mfjbge8BbSpz/98Ancv6Obq7S30tF7cl5fRNQBC6vR1viz/8ScAXw\nQeAf6vF7Ad4A/AfQvJ7PVeVARGrtQmDUOfe14LHPEX3zfmHeC8xsT/zcsJndZ2ZH4y6FF9WjPXGb\nOoi+qV7lnDtehXasuS05+oBx59yqqirBZln3+MdcdGUpt1nWhfHzobvLnL9qa2xPVhfQCozUqS1X\nA8edcx9cz+dXoS2/QBza4v9vHjGzt5lZRdd7hQMRqbX9QOpi6pw7RfSP+P4Srzk3vr2aqMR+CXAY\nuMfMfqgO7QE4BNzrnPvf6/z8arQlEZeX38Equ0Vi5TbLKvW5+ys8vxJraU/WnxOVzrMBpuZtiUPr\nFcDr1/nZ624L0f87/4Xo+v5y4FrgvwJvr+SDFQ5EZE3M7E/jgVeljlNmdl65t6B0v73/t+mvnXO3\nOOceds79HtF2eFdudHvigYc/Q7Ty44pq/LsJP6cb+BTwDeCPV9O2ld5yNZ+7jvMrtdrfwx8Cvwq8\n0jk3v5FtMbMdwK3AbzrnRmv02atqS6yJKDz8lnPua86524F3A2+s5AO0QqKIrNV/J+pbLef/AEeJ\n+ugTZtYM9FN6Y6YfxLfZvWyPEA202uj2/DTRN7KimYWP/4OZfdE59zMb2BZ/3g6isv4Y8MtxxWG1\n1rJZ1tEKz6/EWtoDgJn9PvAW4GLn3L/VoS0/BJwNfNKe+o+jKW7bPPBM51y5/Z+r2RaI/t+Zj7sf\nvCPAfjNrcc4truaDFQ5EZE2ccyeBkyudZ2b3A31m9tygb/1iom8/D+S9xjn3HTN7kmikdeg84M6N\nbg/wp0Sj9EPfAN4MLOtmqHFbfMXgbqJBiJdV+m3ZObdg0T4YFwOfiN/T4p9vLPGy+3Oe/7n48XVZ\nY3swsz8gKpe/NDNuYyPbcgT4scxj7wZ2AP8P0SyKjWoLwH3AYOaxZwI/WG0w8B+uQ4cOHTU9iC7o\n/wI8H3gRUffArcHzpxP9I/u84LE3A6PAq4i+nV0LTAFPr0d7ct5j3bMV1tIWoovOV4j2r3g60bdK\nf1QyW+FXicLFa4lmTbyfKNDsiZ+/BfiT4PwLgXmiKZTPBK4h2m77WVX6b6TS9rwl/vxfyvwOuja6\nLTmvr+ZshUp/L2cQzdr4S+CHiabHHgX+sKLPrUbjdejQoaPcQTSa/rb4H61Rom/hncHzZxOVT1+c\ned1biKYOTgD3AhfWsz2Z9zhVpXBQUVuI5vefyhxL8e1ZFX727wDfiS8+95MOZ/8E/F3m/FcB34rP\n/1eizbWq+d/JqtsDPJbzezgF/NFGtyXntVULB2v8e3oh8GVgmmha41uJ91Ja7aGNl0RERCRFsxVE\nREQkReFAREREUhQOREREJEXhQERERFIUDkRERCRF4UBERERSFA5EREQkReFA5P9vt44FAAAAAAb5\nW++eQ1EEwMgBADByAACMHAAAE5OOiZtgWJb5AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f8444471358>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Let's convert the uint8 image to 32 bit floats and rescale \n",
    "# the values to be centered around 0, between [-0.5, 0.5]. \n",
    "# \n",
    "# We again plot the image and histogram to check that we \n",
    "# haven't mangled the data.\n",
    "scaled = image.astype(numpy.float32)\n",
    "scaled = (scaled - (255 / 2.0)) / 255\n",
    "_, (ax1, ax2) = plt.subplots(1, 2)\n",
    "ax1.imshow(scaled.reshape(28, 28), cmap=plt.cm.Greys);\n",
    "ax2.hist(scaled, bins=20, range=[-0.5, 0.5]);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "PlqlwkX-O0Hd"
   },
   "source": [
    "Great -- we've retained the correct image data while properly rescaling to the range [-0.5, 0.5].\n",
    "\n",
    "## Reading the labels\n",
    "\n",
    "Let's next unpack the test label data. The format here is similar: a magic number followed by a count followed by the labels as `uint8` values. In more detail:\n",
    "\n",
    "    [offset] [type]          [value]          [description] \n",
    "    0000     32 bit integer  0x00000801(2049) magic number (MSB first) \n",
    "    0004     32 bit integer  10000            number of items \n",
    "    0008     unsigned byte   ??               label \n",
    "    0009     unsigned byte   ??               label \n",
    "    ........ \n",
    "    xxxx     unsigned byte   ??               label\n",
    "\n",
    "As with the image data, let's read  the first test set value to sanity check our input path. We'll expect a 7."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:22.925176",
     "start_time": "2016-09-16T14:49:22.897739"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 90,
     "status": "ok",
     "timestamp": 1446749126903,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "d8zv9yZzQOnV",
    "outputId": "ad203b2c-f095-4035-e0cd-7869c078da3d"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "magic number 2049\n",
      "label count 10000\n",
      "First label: 7\n"
     ]
    }
   ],
   "source": [
    "with gzip.open(test_labels_filename) as f:\n",
    "    # Print the header fields.\n",
    "    for field in ['magic number', 'label count']:\n",
    "        print(field, struct.unpack('>i', f.read(4))[0])\n",
    "\n",
    "    print('First label:', struct.unpack('B', f.read(1))[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "zAGrQSXCQtIm"
   },
   "source": [
    "Indeed, the first label of the test set is 7.\n",
    "\n",
    "## Forming the training, testing, and validation data sets\n",
    "\n",
    "Now that we understand how to read a single element, we can read a much larger set that we'll use for training, testing, and validation.\n",
    "\n",
    "### Image data\n",
    "\n",
    "The code below is a generalization of our prototyping above that reads the entire test and training data set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:23.525119",
     "start_time": "2016-09-16T14:49:22.928289"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 734,
     "status": "ok",
     "timestamp": 1446749128718,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "ofFZ5oJeRMDA",
    "outputId": "ff2de90b-aed9-4ce5-db8c-9123496186b1"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting /tmp/mnist-data/train-images-idx3-ubyte.gz\n",
      "Extracting /tmp/mnist-data/t10k-images-idx3-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "IMAGE_SIZE = 28\n",
    "PIXEL_DEPTH = 255\n",
    "\n",
    "def extract_data(filename, num_images):\n",
    "    \"\"\"Extract the images into a 4D tensor [image index, y, x, channels].\n",
    "  \n",
    "    For MNIST data, the number of channels is always 1.\n",
    "\n",
    "    Values are rescaled from [0, 255] down to [-0.5, 0.5].\n",
    "    \"\"\"\n",
    "    print('Extracting', filename)\n",
    "    with gzip.open(filename) as bytestream:\n",
    "        # Skip the magic number and dimensions; we know these values.\n",
    "        bytestream.read(16)\n",
    "\n",
    "        buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images)\n",
    "        data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32)\n",
    "        data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH\n",
    "        data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, 1)\n",
    "        return data\n",
    "\n",
    "train_data = extract_data(train_data_filename, 60000)\n",
    "test_data = extract_data(test_data_filename, 10000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "0x4rwXxUR96O"
   },
   "source": [
    "A crucial difference here is how we `reshape` the array of pixel values. Instead of one image that's 28x28, we now have a set of 60,000 images, each one being 28x28. We also include a number of channels, which for grayscale images as we have here is 1.\n",
    "\n",
    "Let's make sure we've got the reshaping parameters right by inspecting the dimensions and the first two images. (Again, mangled input is a very common source of errors.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:23.829853",
     "start_time": "2016-09-16T14:49:23.527283"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {},
      {}
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 400,
     "status": "ok",
     "timestamp": 1446749129657,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "0AwSo8mlSja_",
    "outputId": "11490c39-7c67-4fe5-982c-ca8278294d96"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data shape (60000, 28, 28, 1)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f8444461630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('Training data shape', train_data.shape)\n",
    "_, (ax1, ax2) = plt.subplots(1, 2)\n",
    "ax1.imshow(train_data[0].reshape(28, 28), cmap=plt.cm.Greys);\n",
    "ax2.imshow(train_data[1].reshape(28, 28), cmap=plt.cm.Greys);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "cwBhQ3ouTQcW"
   },
   "source": [
    "Looks good. Now we know how to index our full set of training and test images."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "PBCB9aYxRvBi"
   },
   "source": [
    "### Label data\n",
    "\n",
    "Let's move on to loading the full set of labels. As is typical in classification problems, we'll convert our input labels into a [1-hot](https://en.wikipedia.org/wiki/One-hot) encoding over a length 10 vector corresponding to 10 digits. The vector [0, 1, 0, 0, 0, 0, 0, 0, 0, 0], for example, would correspond to the digit 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:23.854577",
     "start_time": "2016-09-16T14:49:23.831545"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 191,
     "status": "ok",
     "timestamp": 1446749131421,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "9pK1j2WlRwY9",
    "outputId": "1ca31655-e14f-405a-b266-6a6c78827af5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting /tmp/mnist-data/train-labels-idx1-ubyte.gz\n",
      "Extracting /tmp/mnist-data/t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "NUM_LABELS = 10\n",
    "\n",
    "def extract_labels(filename, num_images):\n",
    "    \"\"\"Extract the labels into a 1-hot matrix [image index, label index].\"\"\"\n",
    "    print('Extracting', filename)\n",
    "    with gzip.open(filename) as bytestream:\n",
    "        # Skip the magic number and count; we know these values.\n",
    "        bytestream.read(8)\n",
    "        buf = bytestream.read(1 * num_images)\n",
    "        labels = numpy.frombuffer(buf, dtype=numpy.uint8)\n",
    "    # Convert to dense 1-hot representation.\n",
    "    return (numpy.arange(NUM_LABELS) == labels[:, None]).astype(numpy.float32)\n",
    "\n",
    "train_labels = extract_labels(train_labels_filename, 60000)\n",
    "test_labels = extract_labels(test_labels_filename, 10000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "hb3Vaq72UUxW"
   },
   "source": [
    "As with our image data, we'll double-check that our 1-hot encoding of the first few values matches our expectations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:23.864350",
     "start_time": "2016-09-16T14:49:23.857177"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 127,
     "status": "ok",
     "timestamp": 1446749132853,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "uEBID71nUVj1",
    "outputId": "3f318310-18dd-49ed-9943-47b4aae7ee69"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training labels shape (60000, 10)\n",
      "First label vector [ 0.  0.  0.  0.  0.  1.  0.  0.  0.  0.]\n",
      "Second label vector [ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n"
     ]
    }
   ],
   "source": [
    "print('Training labels shape', train_labels.shape)\n",
    "print('First label vector', train_labels[0])\n",
    "print('Second label vector', train_labels[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "5EwtEhxRUneF"
   },
   "source": [
    "The 1-hot encoding looks reasonable.\n",
    "\n",
    "### Segmenting data into training, test, and validation\n",
    "\n",
    "The final step in preparing our data is to split it into three sets: training, test, and validation. This isn't the format of the original data set, so we'll take a small slice of the training data and treat that as our validation set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:23.874014",
     "start_time": "2016-09-16T14:49:23.866161"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 176,
     "status": "ok",
     "timestamp": 1446749134110,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "e7aBYBtIVxHE",
    "outputId": "bdeae1a8-daff-4743-e594-f1d2229c0f4e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Validation shape (5000, 28, 28, 1)\n",
      "Train size 55000\n"
     ]
    }
   ],
   "source": [
    "VALIDATION_SIZE = 5000\n",
    "\n",
    "validation_data = train_data[:VALIDATION_SIZE, :, :, :]\n",
    "validation_labels = train_labels[:VALIDATION_SIZE]\n",
    "train_data = train_data[VALIDATION_SIZE:, :, :, :]\n",
    "train_labels = train_labels[VALIDATION_SIZE:]\n",
    "\n",
    "train_size = train_labels.shape[0]\n",
    "\n",
    "print('Validation shape', validation_data.shape)\n",
    "print('Train size', train_size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "1JFhEH8EVj4O"
   },
   "source": [
    "# Defining the model\n",
    "\n",
    "Now that we've prepared our data, we're ready to define our model.\n",
    "\n",
    "The comments describe the architecture, which fairly typical of models that process image data. The raw input passes through several [convolution](https://en.wikipedia.org/wiki/Convolutional_neural_network#Convolutional_layer) and [max pooling](https://en.wikipedia.org/wiki/Convolutional_neural_network#Pooling_layer) layers with [rectified linear](https://en.wikipedia.org/wiki/Convolutional_neural_network#ReLU_layer) activations before several fully connected layers and a [softmax](https://en.wikipedia.org/wiki/Convolutional_neural_network#Loss_layer) loss for predicting the output class. During training, we use [dropout](https://en.wikipedia.org/wiki/Convolutional_neural_network#Dropout_method).\n",
    "\n",
    "We'll separate our model definition into three steps:\n",
    "\n",
    "1. Defining the variables that will hold the trainable weights.\n",
    "1. Defining the basic model graph structure described above. And,\n",
    "1. Stamping out several copies of the model graph for training, testing, and validation.\n",
    "\n",
    "We'll start with the variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:28.803525",
     "start_time": "2016-09-16T14:49:23.875999"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 2081,
     "status": "ok",
     "timestamp": 1446749138298,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "Q1VfiAzjzuK8",
    "outputId": "f53a39c9-3a52-47ca-d7a3-9f9d84eccf63"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Done\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "# We'll bundle groups of examples during training for efficiency.\n",
    "# This defines the size of the batch.\n",
    "BATCH_SIZE = 60\n",
    "# We have only one channel in our grayscale images.\n",
    "NUM_CHANNELS = 1\n",
    "# The random seed that defines initialization.\n",
    "SEED = 42\n",
    "\n",
    "# This is where training samples and labels are fed to the graph.\n",
    "# These placeholder nodes will be fed a batch of training data at each\n",
    "# training step, which we'll write once we define the graph structure.\n",
    "train_data_node = tf.placeholder(\n",
    "  tf.float32,\n",
    "  shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))\n",
    "train_labels_node = tf.placeholder(tf.float32,\n",
    "                                   shape=(BATCH_SIZE, NUM_LABELS))\n",
    "\n",
    "# For the validation and test data, we'll just hold the entire dataset in\n",
    "# one constant node.\n",
    "validation_data_node = tf.constant(validation_data)\n",
    "test_data_node = tf.constant(test_data)\n",
    "\n",
    "# The variables below hold all the trainable weights. For each, the\n",
    "# parameter defines how the variables will be initialized.\n",
    "conv1_weights = tf.Variable(\n",
    "  tf.truncated_normal([5, 5, NUM_CHANNELS, 32],  # 5x5 filter, depth 32.\n",
    "                      stddev=0.1,\n",
    "                      seed=SEED))\n",
    "conv1_biases = tf.Variable(tf.zeros([32]))\n",
    "conv2_weights = tf.Variable(\n",
    "  tf.truncated_normal([5, 5, 32, 64],\n",
    "                      stddev=0.1,\n",
    "                      seed=SEED))\n",
    "conv2_biases = tf.Variable(tf.constant(0.1, shape=[64]))\n",
    "fc1_weights = tf.Variable(  # fully connected, depth 512.\n",
    "  tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512],\n",
    "                      stddev=0.1,\n",
    "                      seed=SEED))\n",
    "fc1_biases = tf.Variable(tf.constant(0.1, shape=[512]))\n",
    "fc2_weights = tf.Variable(\n",
    "  tf.truncated_normal([512, NUM_LABELS],\n",
    "                      stddev=0.1,\n",
    "                      seed=SEED))\n",
    "fc2_biases = tf.Variable(tf.constant(0.1, shape=[NUM_LABELS]))\n",
    "\n",
    "print('Done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "QHB_u04Z4HO6"
   },
   "source": [
    "Now that we've defined the variables to be trained, we're ready to wire them together into a TensorFlow graph.\n",
    "\n",
    "We'll define a helper to do this, `model`, which will return copies of the graph suitable for training and testing. Note the `train` argument, which controls whether or not dropout is used in the hidden layer. (We want to use dropout only during training.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:28.834326",
     "start_time": "2016-09-16T14:49:28.805723"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 772,
     "status": "ok",
     "timestamp": 1446749138306,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "V85_B9QF3uBp",
    "outputId": "457d3e49-73ad-4451-c196-421dd4681efc"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Done\n"
     ]
    }
   ],
   "source": [
    "def model(data, train=False):\n",
    "    \"\"\"The Model definition.\"\"\"\n",
    "    # 2D convolution, with 'SAME' padding (i.e. the output feature map has\n",
    "    # the same size as the input). Note that {strides} is a 4D array whose\n",
    "    # shape matches the data layout: [image index, y, x, depth].\n",
    "    conv = tf.nn.conv2d(data,\n",
    "                        conv1_weights,\n",
    "                        strides=[1, 1, 1, 1],\n",
    "                        padding='SAME')\n",
    "\n",
    "    # Bias and rectified linear non-linearity.\n",
    "    relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases))\n",
    "\n",
    "    # Max pooling. The kernel size spec ksize also follows the layout of\n",
    "    # the data. Here we have a pooling window of 2, and a stride of 2.\n",
    "    pool = tf.nn.max_pool(relu,\n",
    "                          ksize=[1, 2, 2, 1],\n",
    "                          strides=[1, 2, 2, 1],\n",
    "                          padding='SAME')\n",
    "    conv = tf.nn.conv2d(pool,\n",
    "                        conv2_weights,\n",
    "                        strides=[1, 1, 1, 1],\n",
    "                        padding='SAME')\n",
    "    relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases))\n",
    "    pool = tf.nn.max_pool(relu,\n",
    "                          ksize=[1, 2, 2, 1],\n",
    "                          strides=[1, 2, 2, 1],\n",
    "                          padding='SAME')\n",
    "\n",
    "    # Reshape the feature map cuboid into a 2D matrix to feed it to the\n",
    "    # fully connected layers.\n",
    "    pool_shape = pool.get_shape().as_list()\n",
    "    reshape = tf.reshape(\n",
    "        pool,\n",
    "        [pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]])\n",
    "  \n",
    "    # Fully connected layer. Note that the '+' operation automatically\n",
    "    # broadcasts the biases.\n",
    "    hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases)\n",
    "\n",
    "    # Add a 50% dropout during training only. Dropout also scales\n",
    "    # activations such that no rescaling is needed at evaluation time.\n",
    "    if train:\n",
    "        hidden = tf.nn.dropout(hidden, 0.5, seed=SEED)\n",
    "    return tf.matmul(hidden, fc2_weights) + fc2_biases\n",
    "\n",
    "print('Done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "7bvEtt8C4fLC"
   },
   "source": [
    "Having defined the basic structure of the graph, we're ready to stamp out multiple copies for training, testing, and validation.\n",
    "\n",
    "Here, we'll do some customizations depending on which graph we're constructing. `train_prediction` holds the training graph, for which we use cross-entropy loss and weight regularization. We'll adjust the learning rate during training -- that's handled by the `exponential_decay` operation, which is itself an argument to the `MomentumOptimizer` that performs the actual training.\n",
    "\n",
    "The vaildation and prediction graphs are much simpler the generate -- we need only create copies of the model with the validation and test inputs and a softmax classifier as the output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.058141",
     "start_time": "2016-09-16T14:49:28.836169"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 269,
     "status": "ok",
     "timestamp": 1446749139596,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "9pR1EBNT3sCv",
    "outputId": "570681b1-f33e-4618-b742-48e12aa58132"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Done\n"
     ]
    }
   ],
   "source": [
    "# Training computation: logits + cross-entropy loss.\n",
    "logits = model(train_data_node, True)\n",
    "loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(\n",
    "  logits, train_labels_node))\n",
    "\n",
    "# L2 regularization for the fully connected parameters.\n",
    "regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) +\n",
    "                tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases))\n",
    "# Add the regularization term to the loss.\n",
    "loss += 5e-4 * regularizers\n",
    "\n",
    "# Optimizer: set up a variable that's incremented once per batch and\n",
    "# controls the learning rate decay.\n",
    "batch = tf.Variable(0)\n",
    "# Decay once per epoch, using an exponential schedule starting at 0.01.\n",
    "learning_rate = tf.train.exponential_decay(\n",
    "  0.01,                # Base learning rate.\n",
    "  batch * BATCH_SIZE,  # Current index into the dataset.\n",
    "  train_size,          # Decay step.\n",
    "  0.95,                # Decay rate.\n",
    "  staircase=True)\n",
    "# Use simple momentum for the optimization.\n",
    "optimizer = tf.train.MomentumOptimizer(learning_rate,\n",
    "                                       0.9).minimize(loss,\n",
    "                                                     global_step=batch)\n",
    "\n",
    "# Predictions for the minibatch, validation set and test set.\n",
    "train_prediction = tf.nn.softmax(logits)\n",
    "# We'll compute them only once in a while by calling their {eval()} method.\n",
    "validation_prediction = tf.nn.softmax(model(validation_data_node))\n",
    "test_prediction = tf.nn.softmax(model(test_data_node))\n",
    "\n",
    "print('Done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "4T21uZJq5UfH"
   },
   "source": [
    "# Training and visualizing results\n",
    "\n",
    "Now that we have the training, test, and validation graphs, we're ready to actually go through the training loop and periodically evaluate loss and error.\n",
    "\n",
    "All of these operations take place in the context of a session. In Python, we'd write something like:\n",
    "\n",
    "    with tf.Session() as s:\n",
    "      ...training / test / evaluation loop...\n",
    "  \n",
    "But, here, we'll want to keep the session open so we can poke at values as we work out the details of training. The TensorFlow API includes a function for this, `InteractiveSession`.\n",
    "\n",
    "We'll start by creating a session and initializing the varibles we defined above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.357483",
     "start_time": "2016-09-16T14:49:29.059952"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "collapsed": true,
    "id": "z6Kc5iql6qxV"
   },
   "outputs": [],
   "source": [
    "# Create a new interactive session that we'll use in\n",
    "# subsequent code cells.\n",
    "s = tf.InteractiveSession()\n",
    "\n",
    "# Use our newly created session as the default for \n",
    "# subsequent operations.\n",
    "s.as_default()\n",
    "\n",
    "# Initialize all the variables we defined above.\n",
    "tf.global_variables_initializer().run()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "hcG8H-Ka6_mw"
   },
   "source": [
    "Now we're ready to perform operations on the graph. Let's start with one round of training. We're going to organize our training steps into batches for efficiency; i.e., training using a small set of examples at each step rather than a single example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.584699",
     "start_time": "2016-09-16T14:49:29.359107"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 386,
     "status": "ok",
     "timestamp": 1446749389138,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "LYVxeEox71Pg",
    "outputId": "9184b5df-009a-4b1b-e312-5be94351351f"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Done\n"
     ]
    }
   ],
   "source": [
    "BATCH_SIZE = 60\n",
    "\n",
    "# Grab the first BATCH_SIZE examples and labels.\n",
    "batch_data = train_data[:BATCH_SIZE, :, :, :]\n",
    "batch_labels = train_labels[:BATCH_SIZE]\n",
    "\n",
    "# This dictionary maps the batch data (as a numpy array) to the\n",
    "# node in the graph it should be fed to.\n",
    "feed_dict = {train_data_node: batch_data,\n",
    "             train_labels_node: batch_labels}\n",
    "\n",
    "# Run the graph and fetch some of the nodes.\n",
    "_, l, lr, predictions = s.run(\n",
    "  [optimizer, loss, learning_rate, train_prediction],\n",
    "  feed_dict=feed_dict)\n",
    "\n",
    "print('Done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "7bL4-RNm_K-B"
   },
   "source": [
    "Let's take a look at the predictions. How did we do? Recall that the output will be probabilities over the possible classes, so let's look at those probabilities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.593985",
     "start_time": "2016-09-16T14:49:29.586233"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 160,
     "status": "ok",
     "timestamp": 1446749519023,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "2eNitV_4_ZUL",
    "outputId": "f1340dd1-255b-4523-bf62-7e3ebb361333"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  2.25393116e-04   4.76219611e-05   1.66867452e-03   5.67827519e-05\n",
      "   6.03432178e-01   4.34969068e-02   2.19316553e-05   1.41286102e-04\n",
      "   1.54903100e-05   3.50893795e-01]\n"
     ]
    }
   ],
   "source": [
    "print(predictions[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "X5MgraJb_eQZ"
   },
   "source": [
    "As expected without training, the predictions are all noise. Let's write a scoring function that picks the class with the maximum probability and compares with the example's label. We'll start by converting the probability vectors returned by the softmax into predictions we can match against the labels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.606284",
     "start_time": "2016-09-16T14:49:29.597095"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 220,
     "status": "ok",
     "timestamp": 1446750411574,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "wMMlUf5rCKgT",
    "outputId": "2c10e96d-52b6-47b0-b6eb-969ad462d46b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "First prediction 4\n",
      "(60, 10)\n",
      "All predictions [4 4 2 7 7 7 7 7 7 7 7 7 0 8 9 0 7 7 0 7 4 0 5 0 9 9 7 0 7 4 7 7 7 0 7 7 9\n",
      " 7 9 9 0 7 7 7 2 7 0 7 2 9 9 9 9 9 0 7 9 4 8 7]\n"
     ]
    }
   ],
   "source": [
    "# The highest probability in the first entry.\n",
    "print('First prediction', numpy.argmax(predictions[0]))\n",
    "\n",
    "# But, predictions is actually a list of BATCH_SIZE probability vectors.\n",
    "print(predictions.shape)\n",
    "\n",
    "# So, we'll take the highest probability for each vector.\n",
    "print('All predictions', numpy.argmax(predictions, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "8pMCIZ3_C2ni"
   },
   "source": [
    "Next, we can do the same thing for our labels -- using `argmax` to convert our 1-hot encoding into a digit class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.615484",
     "start_time": "2016-09-16T14:49:29.609168"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 232,
     "status": "ok",
     "timestamp": 1446750498351,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "kZWp4T0JDDUe",
    "outputId": "47b588cd-bc82-45c3-a5d0-8d84dc27a3be"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Batch labels [7 3 4 6 1 8 1 0 9 8 0 3 1 2 7 0 2 9 6 0 1 6 7 1 9 7 6 5 5 8 8 3 4 4 8 7 3\n",
      " 6 4 6 6 3 8 8 9 9 4 4 0 7 8 1 0 0 1 8 5 7 1 7]\n"
     ]
    }
   ],
   "source": [
    "print('Batch labels', numpy.argmax(batch_labels, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "bi5Z6whtDiht"
   },
   "source": [
    "Now we can compare the predicted and label classes to compute the error rate and confusion matrix for this batch."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.841313",
     "start_time": "2016-09-16T14:49:29.618274"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      },
      {
       "item_id": 2
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 330,
     "status": "ok",
     "timestamp": 1446751307304,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "U4hrLW4CDtQB",
    "outputId": "720494a3-cbf9-4687-9d94-e64a33fdd78f"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.06666666666666667\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n9OY6UgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f841ece8128>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "correct = numpy.sum(numpy.argmax(predictions, 1) == numpy.argmax(batch_labels, 1))\n",
    "total = predictions.shape[0]\n",
    "\n",
    "print(float(correct) / float(total))\n",
    "\n",
    "confusions = numpy.zeros([10, 10], numpy.float32)\n",
    "bundled = zip(numpy.argmax(predictions, 1), numpy.argmax(batch_labels, 1))\n",
    "for predicted, actual in bundled:\n",
    "  confusions[predicted, actual] += 1\n",
    "\n",
    "plt.grid(False)\n",
    "plt.xticks(numpy.arange(NUM_LABELS))\n",
    "plt.yticks(numpy.arange(NUM_LABELS))\n",
    "plt.imshow(confusions, cmap=plt.cm.jet, interpolation='nearest');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "iZmx_9DiDXQ3"
   },
   "source": [
    "Now let's wrap this up into our scoring function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:49:29.857607",
     "start_time": "2016-09-16T14:49:29.843904"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 178,
     "status": "ok",
     "timestamp": 1446751995007,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "DPJie7bPDaLa",
    "outputId": "a06c64ed-f95f-416f-a621-44cccdaba0f8"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Done\n"
     ]
    }
   ],
   "source": [
    "def error_rate(predictions, labels):\n",
    "    \"\"\"Return the error rate and confusions.\"\"\"\n",
    "    correct = numpy.sum(numpy.argmax(predictions, 1) == numpy.argmax(labels, 1))\n",
    "    total = predictions.shape[0]\n",
    "\n",
    "    error = 100.0 - (100 * float(correct) / float(total))\n",
    "\n",
    "    confusions = numpy.zeros([10, 10], numpy.float32)\n",
    "    bundled = zip(numpy.argmax(predictions, 1), numpy.argmax(labels, 1))\n",
    "    for predicted, actual in bundled:\n",
    "        confusions[predicted, actual] += 1\n",
    "    \n",
    "    return error, confusions\n",
    "\n",
    "print('Done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "sLv22cjeB5Rd"
   },
   "source": [
    "We'll need to train for some time to actually see useful predicted values. Let's define a loop that will go through our data. We'll print the loss and error periodically.\n",
    "\n",
    "Here, we want to iterate over the entire data set rather than just the first batch, so we'll need to slice the data to that end.\n",
    "\n",
    "(One pass through our training set will take some time on a CPU, so be patient if you are executing this notebook.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:53:26.998313",
     "start_time": "2016-09-16T14:49:29.860079"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "collapsed": false,
    "id": "4cgKJrS1_vej"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Step 0 of 916\n",
      "Mini-batch loss: 7.71249 Error: 91.66667 Learning rate: 0.01000\n",
      "Validation error: 88.9%\n",
      "Step 100 of 916\n",
      "Mini-batch loss: 3.28715 Error: 8.33333 Learning rate: 0.01000\n",
      "Validation error: 5.8%\n",
      "Step 200 of 916\n",
      "Mini-batch loss: 3.30949 Error: 8.33333 Learning rate: 0.01000\n",
      "Validation error: 3.6%\n",
      "Step 300 of 916\n",
      "Mini-batch loss: 3.15385 Error: 3.33333 Learning rate: 0.01000\n",
      "Validation error: 3.1%\n",
      "Step 400 of 916\n",
      "Mini-batch loss: 3.08212 Error: 1.66667 Learning rate: 0.01000\n",
      "Validation error: 2.7%\n",
      "Step 500 of 916\n",
      "Mini-batch loss: 3.02827 Error: 1.66667 Learning rate: 0.01000\n",
      "Validation error: 2.2%\n",
      "Step 600 of 916\n",
      "Mini-batch loss: 3.03260 Error: 5.00000 Learning rate: 0.01000\n",
      "Validation error: 1.9%\n",
      "Step 700 of 916\n",
      "Mini-batch loss: 3.16032 Error: 6.66667 Learning rate: 0.01000\n",
      "Validation error: 2.2%\n",
      "Step 800 of 916\n",
      "Mini-batch loss: 3.06246 Error: 3.33333 Learning rate: 0.01000\n",
      "Validation error: 2.0%\n",
      "Step 900 of 916\n",
      "Mini-batch loss: 2.85098 Error: 0.00000 Learning rate: 0.01000\n",
      "Validation error: 1.9%\n"
     ]
    }
   ],
   "source": [
    "# Train over the first 1/4th of our training set.\n",
    "steps = train_size // BATCH_SIZE\n",
    "for step in range(steps):\n",
    "    # Compute the offset of the current minibatch in the data.\n",
    "    # Note that we could use better randomization across epochs.\n",
    "    offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE)\n",
    "    batch_data = train_data[offset:(offset + BATCH_SIZE), :, :, :]\n",
    "    batch_labels = train_labels[offset:(offset + BATCH_SIZE)]\n",
    "    # This dictionary maps the batch data (as a numpy array) to the\n",
    "    # node in the graph it should be fed to.\n",
    "    feed_dict = {train_data_node: batch_data,\n",
    "                 train_labels_node: batch_labels}\n",
    "    # Run the graph and fetch some of the nodes.\n",
    "    _, l, lr, predictions = s.run(\n",
    "      [optimizer, loss, learning_rate, train_prediction],\n",
    "      feed_dict=feed_dict)\n",
    "    \n",
    "    # Print out the loss periodically.\n",
    "    if step % 100 == 0:\n",
    "        error, _ = error_rate(predictions, batch_labels)\n",
    "        print('Step %d of %d' % (step, steps))\n",
    "        print('Mini-batch loss: %.5f Error: %.5f Learning rate: %.5f' % (l, error, lr))\n",
    "        print('Validation error: %.1f%%' % error_rate(\n",
    "              validation_prediction.eval(), validation_labels)[0])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "J4LskgGXIDAm"
   },
   "source": [
    "The error seems to have gone down. Let's evaluate the results using the test set.\n",
    "\n",
    "To help identify rare mispredictions, we'll include the raw count of each (prediction, label) pair in the confusion matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:55:10.942063",
     "start_time": "2016-09-16T14:53:26.999971"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      },
      {
       "item_id": 2
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 436,
     "status": "ok",
     "timestamp": 1446752934104,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "6Yh1jGFuIKc_",
    "outputId": "4e411de4-0fe2-451b-e4ca-8a4854f0db89"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test error: 2.0%\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nRK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f841eb30f98>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_error, confusions = error_rate(test_prediction.eval(), test_labels)\n",
    "print('Test error: %.1f%%' % test_error)\n",
    "\n",
    "plt.xlabel('Actual')\n",
    "plt.ylabel('Predicted')\n",
    "plt.grid(False)\n",
    "plt.xticks(numpy.arange(NUM_LABELS))\n",
    "plt.yticks(numpy.arange(NUM_LABELS))\n",
    "plt.imshow(confusions, cmap=plt.cm.jet, interpolation='nearest');\n",
    "\n",
    "for i, cas in enumerate(confusions):\n",
    "    for j, count in enumerate(cas):\n",
    "        if count > 0:\n",
    "            xoff = .07 * len(str(count))\n",
    "            plt.text(j-xoff, i+.2, int(count), fontsize=9, color='white')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "yLnS4dGiMwI1"
   },
   "source": [
    "We can see here that we're mostly accurate, with some errors you might expect, e.g., '9' is often confused as '4'.\n",
    "\n",
    "Let's do another sanity check to make sure this matches roughly the distribution of our test set, e.g., it seems like we have fewer '5' values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2016-09-16T14:55:18.083458",
     "start_time": "2016-09-16T14:55:17.830485"
    },
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "collapsed": false,
    "executionInfo": {
     "elapsed": 352,
     "status": "ok",
     "timestamp": 1446753006584,
     "user": {
      "color": "#1FA15D",
      "displayName": "Michael Piatek",
      "isAnonymous": false,
      "isMe": true,
      "permissionId": "00327059602783983041",
      "photoUrl": "//lh6.googleusercontent.com/-wKJwK_OPl34/AAAAAAAAAAI/AAAAAAAAAlk/Rh3u6O2Z7ns/s50-c-k-no/photo.jpg",
      "sessionId": "716a6ad5e180d821",
      "userId": "106975671469698476657"
     },
     "user_tz": 480
    },
    "id": "x5KOv1AJMgzV",
    "outputId": "2acdf737-bab6-408f-8b3c-05fa66d04fe6"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nG1beKa9dAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f841c174f60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xticks(numpy.arange(NUM_LABELS))\n",
    "plt.hist(numpy.argmax(test_labels, 1));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "E6DzLSK5M1ju"
   },
   "source": [
    "Indeed, we appear to have fewer 5 labels in the test set. So, on the whole, it seems like our model is learning and our early results are sensible.\n",
    "\n",
    "But, we've only done one round of training. We can greatly improve accuracy by training for longer. To try this out, just re-execute the training cell above."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "colab": {
   "default_view": {},
   "name": "Untitled",
   "provenance": [],
   "version": "0.3.2",
   "views": {}
  },
  "kernelspec": {
   "display_name": "Python [default]",
   "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
