Skip to content
Snippets Groups Projects
Jupyter Notebook Block 4 - Convolutional Neural Networks.ipynb 2.96 MiB
Newer Older
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part 1 - Convolutional Neural Networks for CIFAR-10\n",
    "\n",
    "\n",
    "In this notebook chapter, we'll build, train and optimize a neural network to classify images of the CIFAR-10 dataset using convolutional neural networks.\n",
    "\n",
    "This guide uses [tf.keras](https://www.tensorflow.org/guide/keras), a high-level API to build and train models in TensorFlow.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.7.1\n",
      "Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz\n",
      "170500096/170498071 [==============================] - 7s 0us/step\n",
      "170508288/170498071 [==============================] - 7s 0us/step\n",
      "Train: X=(50000, 32, 32, 3), y=(50000, 1)\n",
      "Test: X=(10000, 32, 32, 3), y=(10000, 1)\n",
      "(50000, 1)\n",
      "(10000, 1)\n",
      "(50000, 10)\n",
      "(10000, 10)\n"
     ]
    }
   ],
   "source": [
    "from __future__ import absolute_import, division, print_function, unicode_literals\n",
    "\n",
    "# Import TensorFlow and TensorFlow Datasets\n",
    "import tensorflow as tf\n",
    "print(tf.__version__)\n",
    "\n",
    "# Helper libraries\n",
    "import math\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from tensorflow.keras.datasets import cifar10\n",
    "from tensorflow.keras.utils import to_categorical\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "\n",
    "# load dataset\n",
    "(X_train, y_train), (X_test, y_test) = cifar10.load_data()\n",
    "X_train = X_train.astype('float32')\n",
    "X_test = X_test.astype('float32')\n",
    "\n",
    "class_names = ['airplanes', 'cars', 'birds', 'cats', 'deer',\n",
    "               'dogs',      'frogs',   'horses',  'ships',   'trucks']\n",
    "num_classes = len(class_names)\n",
    "\n",
    "\n",
    "# summarize loaded dataset\n",
    "print('Train: X=%s, y=%s' % (X_train.shape, y_train.shape))\n",
    "print('Test: X=%s, y=%s' % (X_test.shape, y_test.shape))\n",
    "y_train_cat = to_categorical(y_train, 10)\n",
    "y_test_cat  = to_categorical(y_test, 10)\n",
    "print(y_train.shape)\n",
    "print(y_test.shape)\n",
    "print(y_train_cat.shape)\n",
    "print(y_test_cat.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Preprocess the data\n",
    "\n",
    "### 1.1 Zero-Centered Images\n",
    "\n",
    "The value of each pixel in the image data is an integer in the range `[0,255]`. For the model to work properly, these values need to be zero-centered to the range. So here we compute the mean value per colour channel over all training images and subtract the mean value per colour channel from every image in the training and test set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[125.3069  122.95015 113.866  ]\n",
      "[-25.327402 -39.670845 -56.451923]\n",
      "(32, 32, 3)\n",
      "(50000, 32, 32, 3)\n",
      "(10000, 32, 32, 3)\n",
      "float32\n"
     ]
    }
   ],
   "source": [
    "train_mean = X_train.mean(axis=(0,1,2))\n",
    "train_std =  X_train.std(axis=(0,1,2))\n",
    "print(train_mean)\n",
    "X_train_zc = X_train - train_mean\n",
    "X_test_zc  = X_test - train_mean\n",
    "\n",
    "\n",
    "print(X_train_zc[3].mean(axis=(0,1)))\n",
    "print(X_train_zc[3].shape)\n",
    "print(X_train_zc.shape)\n",
    "print(X_test_zc.shape)\n",
    "print(X_train_zc.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 Data Augmentation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "from tensorflow.keras.preprocessing import image\n",
    "\n",
    "\n",
    "train_datagen = ImageDataGenerator(\n",
    "        # set input mean to 0 over the dataset\n",
    "        featurewise_center=False, \n",
    "        # set each sample mean to 0\n",
    "        samplewise_center=False,  \n",
    "        # divide inputs by std of the dataset\n",
    "        featurewise_std_normalization=False, \n",
    "        # divide each input by its std\n",
    "        samplewise_std_normalization=False,  \n",
    "        # apply ZCA whitening\n",
    "        zca_whitening=False, \n",
    "        # epsilon for ZCA whitening\n",
    "        zca_epsilon=1e-06,  \n",
    "        # randomly rotate images in the range (degrees, 0 to 180)\n",
    "        rotation_range=0,  \n",
    "        # randomly shift images horizontally (fraction of total width)\n",
    "        width_shift_range=0.1,\n",
    "        # randomly shift images vertically (fraction of total height)\n",
    "        height_shift_range=0.1,\n",
    "        # set range for random shear\n",
    "        shear_range=0., \n",
    "        # set range for random zoom\n",
    "        zoom_range=0.,  \n",
    "        # set range for random channel shifts\n",
    "        # set mode for filling points outside the input boundaries\n",
    "        channel_shift_range=0.,  \n",
    "        # value used for fill_mode = \"constant\"\n",
    "        fill_mode='nearest',\n",
    "        cval=0.,  \n",
    "        # randomly flip images\n",
    "        horizontal_flip=True, \n",
    "        # randomly flip images\n",
    "        vertical_flip=False,  \n",
    "        # set rescaling factor (applied before any other transformation)\n",
    "        rescale=None,\n",
    "        # set function that will be applied on each input\n",
    "        preprocessing_function=None,\n",
    "        # image data format, either \"channels_first\" or \"channels_last\"\n",
    "        data_format=None,\n",
    "        # fraction of images reserved for validation (strictly between 0 and 1)\n",
    "        validation_split=0.0)\n",
    "\n",
    "validation_datagen = ImageDataGenerator( \n",
    "      # rescale the pixel values (between 0 and 255) to the [0,1] interval \n",
    "      # rescale=1./255\n",
    ")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Build the model\n",
    "\n",
    "Building the neural network requires configuring the layers of the model, then compiling the model."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 Define the network\n",
    "\n",
    "The basic building block of a neural network is the *layer*. A layer extracts a representation from the data fed into it. Hopefully, a series of connected layers results in a representation that is meaningful for the problem at hand.\n",
    "\n",
    "Much of deep learning consists of chaining together simple layers. Most layers, like `tf.keras.layers.Dense`, have internal parameters which are adjusted (\"learned\") during training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tf.keras.Sequential()\n",
    "model.add(tf.keras.layers.Conv2D(32, (3, 3), padding='same',\n",
    "                 input_shape=X_train_zc.shape[1:]))\n",
    "model.add(tf.keras.layers.BatchNormalization())\n",
    "model.add(tf.keras.layers.Activation('relu'))\n",
    "model.add(tf.keras.layers.Conv2D(32, (3, 3)))\n",
    "model.add(tf.keras.layers.BatchNormalization())\n",
    "model.add(tf.keras.layers.Activation('relu'))\n",
    "model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n",
    "model.add(tf.keras.layers.Dropout(0.25))\n",
    "\n",
    "model.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same'))\n",
    "model.add(tf.keras.layers.BatchNormalization())\n",
    "model.add(tf.keras.layers.Activation('relu'))\n",
    "model.add(tf.keras.layers.Conv2D(64, (3, 3)))\n",
    "model.add(tf.keras.layers.BatchNormalization())\n",
    "model.add(tf.keras.layers.Activation('relu'))\n",
    "model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n",
    "model.add(tf.keras.layers.Dropout(0.25))\n",
    "\n",
    "model.add(tf.keras.layers.Flatten())\n",
    "model.add(tf.keras.layers.Dense(512))\n",
    "model.add(tf.keras.layers.BatchNormalization())\n",
    "model.add(tf.keras.layers.Activation('relu'))\n",
    "model.add(tf.keras.layers.Dropout(0.5))\n",
    "model.add(tf.keras.layers.Dense(num_classes))\n",
    "model.add(tf.keras.layers.BatchNormalization())\n",
    "model.add(tf.keras.layers.Activation('softmax'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`tf.keras.layers.Conv2D(32, (3, 3)))` implies the following parameter settings:\n",
    "\n",
    "\n",
    "- `filters` : Integer, the dimensionality of the output space (i.e. the number of output filters in the \n",
    "convolution). In this case, the number of filters is $32$.\n",
    "\n",
    "- `kernel_size` : An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window (receptive field). Can be a single integer to specify the same value for all spatial dimensions. In this \n",
    "case, the receptive field of the filters are $3\\times3$.\n",
    "\n",
    "- `strides` : An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Default strides : $(1, 1)$\n",
    "\n",
    "- `padding`: one of `valid` or `same`. In this case, the size of the output volume won't be changed.\n",
    "\n",
    "`tf.keras.layers.MaxPooling2D(pool_size=(2, 2))` implies the following parameter settings:\n",
    "\n",
    "- `pool_size`: integer or tuple of 2 integers, factors by which to downscale (vertical, horizontal). $(2, 2)$ will halve the input in both spatial dimension. If only one integer is specified, the same window length will be used for both dimensions.\n",
    "- `strides`: Integer, tuple of 2 integers, or `None`. `strides` values. If `None`, it will default to `pool_size`. In this case $(2,2)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " conv2d_4 (Conv2D)           (None, 32, 32, 32)        896       \n",
      "                                                                 \n",
      " batch_normalization_4 (Batc  (None, 32, 32, 32)       128       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation (Activation)     (None, 32, 32, 32)        0         \n",
      "                                                                 \n",
      " conv2d_5 (Conv2D)           (None, 30, 30, 32)        9248      \n",
      "                                                                 \n",
      " batch_normalization_5 (Batc  (None, 30, 30, 32)       128       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_1 (Activation)   (None, 30, 30, 32)        0         \n",
      "                                                                 \n",
      " max_pooling2d (MaxPooling2D  (None, 15, 15, 32)       0         \n",
      " )                                                               \n",
      "                                                                 \n",
      " dropout (Dropout)           (None, 15, 15, 32)        0         \n",
      "                                                                 \n",
      " conv2d_6 (Conv2D)           (None, 15, 15, 64)        18496     \n",
      "                                                                 \n",
      " batch_normalization_6 (Batc  (None, 15, 15, 64)       256       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_2 (Activation)   (None, 15, 15, 64)        0         \n",
      "                                                                 \n",
      " conv2d_7 (Conv2D)           (None, 13, 13, 64)        36928     \n",
      "                                                                 \n",
      " batch_normalization_7 (Batc  (None, 13, 13, 64)       256       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_3 (Activation)   (None, 13, 13, 64)        0         \n",
      "                                                                 \n",
      " max_pooling2d_1 (MaxPooling  (None, 6, 6, 64)         0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " dropout_1 (Dropout)         (None, 6, 6, 64)          0         \n",
      "                                                                 \n",
      " flatten (Flatten)           (None, 2304)              0         \n",
      "                                                                 \n",
      " dense (Dense)               (None, 512)               1180160   \n",
      "                                                                 \n",
      " batch_normalization_8 (Batc  (None, 512)              2048      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_4 (Activation)   (None, 512)               0         \n",
      "                                                                 \n",
      " dropout_2 (Dropout)         (None, 512)               0         \n",
      "                                                                 \n",
      " dense_1 (Dense)             (None, 10)                5130      \n",
      "                                                                 \n",
      " batch_normalization_9 (Batc  (None, 10)               40        \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_5 (Activation)   (None, 10)                0         \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 1,253,714\n",
      "Trainable params: 1,252,286\n",
      "Non-trainable params: 1,428\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 Compile and Fit the Network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:26: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "125/125 [==============================] - 65s 496ms/step - loss: 2.2637 - accuracy: 0.1915 - val_loss: 1.9200 - val_accuracy: 0.2960\n",
      "Epoch 2/100\n",
      "125/125 [==============================] - 59s 475ms/step - loss: 1.9513 - accuracy: 0.2770 - val_loss: 1.7717 - val_accuracy: 0.3740\n",
      "Epoch 3/100\n",
      "125/125 [==============================] - 58s 461ms/step - loss: 1.8561 - accuracy: 0.3145 - val_loss: 1.6933 - val_accuracy: 0.4010\n",
      "Epoch 4/100\n",
      "125/125 [==============================] - 60s 482ms/step - loss: 1.7906 - accuracy: 0.3532 - val_loss: 1.6480 - val_accuracy: 0.4350\n",
      "Epoch 5/100\n",
      "125/125 [==============================] - 56s 451ms/step - loss: 1.7519 - accuracy: 0.3702 - val_loss: 1.6108 - val_accuracy: 0.4580\n",
      "Epoch 6/100\n",
      "125/125 [==============================] - 57s 456ms/step - loss: 1.7103 - accuracy: 0.3938 - val_loss: 1.5763 - val_accuracy: 0.4750\n",
      "Epoch 7/100\n",
      "125/125 [==============================] - 57s 453ms/step - loss: 1.6755 - accuracy: 0.4050 - val_loss: 1.5648 - val_accuracy: 0.4650\n",
      "Epoch 8/100\n",
      "125/125 [==============================] - 59s 472ms/step - loss: 1.6370 - accuracy: 0.4275 - val_loss: 1.5384 - val_accuracy: 0.4800\n",
      "Epoch 9/100\n",
      "125/125 [==============================] - 57s 456ms/step - loss: 1.6283 - accuracy: 0.4325 - val_loss: 1.4877 - val_accuracy: 0.5010\n",
      "Epoch 10/100\n",
      "125/125 [==============================] - 57s 454ms/step - loss: 1.5921 - accuracy: 0.4462 - val_loss: 1.4827 - val_accuracy: 0.5000\n",
      "Epoch 11/100\n",
      "125/125 [==============================] - 57s 455ms/step - loss: 1.5814 - accuracy: 0.4538 - val_loss: 1.4720 - val_accuracy: 0.5030\n",
      "Epoch 12/100\n",
      "125/125 [==============================] - 56s 452ms/step - loss: 1.5691 - accuracy: 0.4595 - val_loss: 1.4404 - val_accuracy: 0.5180\n",
      "Epoch 13/100\n",
      "125/125 [==============================] - 57s 460ms/step - loss: 1.5502 - accuracy: 0.4582 - val_loss: 1.4321 - val_accuracy: 0.5130\n",
      "Epoch 14/100\n",
      "125/125 [==============================] - 60s 477ms/step - loss: 1.5285 - accuracy: 0.4715 - val_loss: 1.4144 - val_accuracy: 0.5300\n",
      "Epoch 15/100\n",
      "125/125 [==============================] - 59s 473ms/step - loss: 1.5151 - accuracy: 0.4755 - val_loss: 1.3980 - val_accuracy: 0.5310\n",
      "Epoch 16/100\n",
      "125/125 [==============================] - 60s 477ms/step - loss: 1.5007 - accuracy: 0.4757 - val_loss: 1.4200 - val_accuracy: 0.5270\n",
      "Epoch 17/100\n",
      "125/125 [==============================] - 60s 479ms/step - loss: 1.4775 - accuracy: 0.4885 - val_loss: 1.4524 - val_accuracy: 0.4960\n",
      "Epoch 18/100\n",
      "125/125 [==============================] - 58s 468ms/step - loss: 1.4692 - accuracy: 0.5027 - val_loss: 1.3896 - val_accuracy: 0.5330\n",
      "Epoch 19/100\n",
      "125/125 [==============================] - 59s 471ms/step - loss: 1.4788 - accuracy: 0.4870 - val_loss: 1.3865 - val_accuracy: 0.5140\n",
      "Epoch 20/100\n",
      "125/125 [==============================] - 61s 489ms/step - loss: 1.4375 - accuracy: 0.5148 - val_loss: 1.3598 - val_accuracy: 0.5390\n",
      "Epoch 21/100\n",
      "125/125 [==============================] - 59s 473ms/step - loss: 1.4504 - accuracy: 0.4988 - val_loss: 1.3318 - val_accuracy: 0.5450\n",
      "Epoch 22/100\n",
      "125/125 [==============================] - 59s 471ms/step - loss: 1.4279 - accuracy: 0.5215 - val_loss: 1.3777 - val_accuracy: 0.5300\n",
      "Epoch 23/100\n",
      "125/125 [==============================] - 58s 466ms/step - loss: 1.4136 - accuracy: 0.5180 - val_loss: 1.3823 - val_accuracy: 0.5200\n",
      "Epoch 24/100\n",
      "125/125 [==============================] - 59s 472ms/step - loss: 1.4027 - accuracy: 0.5340 - val_loss: 1.3522 - val_accuracy: 0.5270\n",
      "Epoch 25/100\n",
      "125/125 [==============================] - 59s 472ms/step - loss: 1.3762 - accuracy: 0.5440 - val_loss: 1.3318 - val_accuracy: 0.5430\n",
      "Epoch 26/100\n",
      "125/125 [==============================] - 59s 472ms/step - loss: 1.3990 - accuracy: 0.5272 - val_loss: 1.4013 - val_accuracy: 0.5180\n",
      "Epoch 27/100\n",
      "125/125 [==============================] - 59s 473ms/step - loss: 1.3665 - accuracy: 0.5437 - val_loss: 1.3762 - val_accuracy: 0.5210\n",
      "Epoch 28/100\n",
      "125/125 [==============================] - 58s 466ms/step - loss: 1.3634 - accuracy: 0.5460 - val_loss: 1.3323 - val_accuracy: 0.5380\n",
      "Epoch 29/100\n",
      "125/125 [==============================] - 59s 473ms/step - loss: 1.3478 - accuracy: 0.5477 - val_loss: 1.3114 - val_accuracy: 0.5390\n",
      "Epoch 30/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 1.3260 - accuracy: 0.5583 - val_loss: 1.2892 - val_accuracy: 0.5530\n",
      "Epoch 32/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 1.3238 - accuracy: 0.5508 - val_loss: 1.3091 - val_accuracy: 0.5420\n",
      "Epoch 33/100\n",
      "125/125 [==============================] - 56s 445ms/step - loss: 1.3083 - accuracy: 0.5645 - val_loss: 1.3815 - val_accuracy: 0.5130\n",
      "Epoch 34/100\n",
      "125/125 [==============================] - 55s 439ms/step - loss: 1.2933 - accuracy: 0.5725 - val_loss: 1.2927 - val_accuracy: 0.5430\n",
      "Epoch 35/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 1.2855 - accuracy: 0.5698 - val_loss: 1.1875 - val_accuracy: 0.5910\n",
      "Epoch 36/100\n",
      "125/125 [==============================] - 56s 445ms/step - loss: 1.2898 - accuracy: 0.5732 - val_loss: 1.2752 - val_accuracy: 0.5550\n",
      "Epoch 37/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.2658 - accuracy: 0.5832 - val_loss: 1.3143 - val_accuracy: 0.5400\n",
      "Epoch 38/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.2637 - accuracy: 0.5817 - val_loss: 1.2509 - val_accuracy: 0.5640\n",
      "Epoch 39/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 1.2505 - accuracy: 0.5907 - val_loss: 1.2469 - val_accuracy: 0.5640\n",
      "Epoch 40/100\n",
      "125/125 [==============================] - 56s 444ms/step - loss: 1.2545 - accuracy: 0.5910 - val_loss: 1.1830 - val_accuracy: 0.5850\n",
      "Epoch 41/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 1.2268 - accuracy: 0.6062 - val_loss: 1.1905 - val_accuracy: 0.5830\n",
      "Epoch 42/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 1.2524 - accuracy: 0.5847 - val_loss: 1.2197 - val_accuracy: 0.5750\n",
      "Epoch 43/100\n",
      "125/125 [==============================] - 55s 441ms/step - loss: 1.2286 - accuracy: 0.5938 - val_loss: 1.2149 - val_accuracy: 0.5740\n",
      "Epoch 44/100\n",
      "125/125 [==============================] - 56s 444ms/step - loss: 1.2193 - accuracy: 0.5953 - val_loss: 1.2929 - val_accuracy: 0.5420\n",
      "Epoch 45/100\n",
      "125/125 [==============================] - 55s 441ms/step - loss: 1.2190 - accuracy: 0.5965 - val_loss: 1.2086 - val_accuracy: 0.5710\n",
      "Epoch 46/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 1.2008 - accuracy: 0.6115 - val_loss: 1.1594 - val_accuracy: 0.5880\n",
      "Epoch 47/100\n",
      "125/125 [==============================] - 55s 442ms/step - loss: 1.2039 - accuracy: 0.6085 - val_loss: 1.1784 - val_accuracy: 0.5770\n",
      "Epoch 48/100\n",
      "125/125 [==============================] - 55s 444ms/step - loss: 1.1963 - accuracy: 0.6047 - val_loss: 1.2196 - val_accuracy: 0.5760\n",
      "Epoch 49/100\n",
      "125/125 [==============================] - 55s 444ms/step - loss: 1.1730 - accuracy: 0.6242 - val_loss: 1.1989 - val_accuracy: 0.5790\n",
      "Epoch 50/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 1.1624 - accuracy: 0.6148 - val_loss: 1.1506 - val_accuracy: 0.6000\n",
      "Epoch 51/100\n",
      "125/125 [==============================] - 55s 440ms/step - loss: 1.1769 - accuracy: 0.6235 - val_loss: 1.2207 - val_accuracy: 0.5760\n",
      "Epoch 52/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 1.1402 - accuracy: 0.6382 - val_loss: 1.1913 - val_accuracy: 0.5810\n",
      "Epoch 53/100\n",
      "125/125 [==============================] - 55s 441ms/step - loss: 1.1687 - accuracy: 0.6120 - val_loss: 1.2070 - val_accuracy: 0.5780\n",
      "Epoch 54/100\n",
      "125/125 [==============================] - 55s 441ms/step - loss: 1.1623 - accuracy: 0.6168 - val_loss: 1.2214 - val_accuracy: 0.5800\n",
      "Epoch 55/100\n",
      " 77/125 [=================>............] - ETA: 19s - loss: 1.1498 - accuracy: 0.6246"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The notebook server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--NotebookApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "NotebookApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "NotebookApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 62/100\n",
      "125/125 [==============================] - 55s 442ms/step - loss: 1.0842 - accuracy: 0.6538 - val_loss: 1.1262 - val_accuracy: 0.6240\n",
      "Epoch 63/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.1145 - accuracy: 0.6292 - val_loss: 1.0857 - val_accuracy: 0.6260\n",
      "Epoch 64/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.1011 - accuracy: 0.6392 - val_loss: 1.1256 - val_accuracy: 0.6110\n",
      "Epoch 65/100\n",
      "125/125 [==============================] - 56s 445ms/step - loss: 1.0765 - accuracy: 0.6565 - val_loss: 1.0557 - val_accuracy: 0.6370\n",
      "Epoch 66/100\n",
      "125/125 [==============================] - 56s 445ms/step - loss: 1.0834 - accuracy: 0.6450 - val_loss: 1.1164 - val_accuracy: 0.6160\n",
      "Epoch 67/100\n",
      "125/125 [==============================] - 55s 442ms/step - loss: 1.0699 - accuracy: 0.6575 - val_loss: 1.0950 - val_accuracy: 0.6170\n",
      "Epoch 68/100\n",
      "125/125 [==============================] - 56s 450ms/step - loss: 1.0688 - accuracy: 0.6615 - val_loss: 1.1049 - val_accuracy: 0.6220\n",
      "Epoch 69/100\n",
      "125/125 [==============================] - 56s 452ms/step - loss: 1.0589 - accuracy: 0.6578 - val_loss: 1.0180 - val_accuracy: 0.6580\n",
      "Epoch 70/100\n",
      "125/125 [==============================] - 56s 451ms/step - loss: 1.0588 - accuracy: 0.6555 - val_loss: 1.1188 - val_accuracy: 0.6100\n",
      "Epoch 71/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 1.0515 - accuracy: 0.6590 - val_loss: 1.0780 - val_accuracy: 0.6370\n",
      "Epoch 72/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.0405 - accuracy: 0.6637 - val_loss: 1.1619 - val_accuracy: 0.6070\n",
      "Epoch 73/100\n",
      "125/125 [==============================] - 56s 449ms/step - loss: 1.0456 - accuracy: 0.6575 - val_loss: 1.1258 - val_accuracy: 0.6220\n",
      "Epoch 74/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.0444 - accuracy: 0.6587 - val_loss: 1.0532 - val_accuracy: 0.6410\n",
      "Epoch 75/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 1.0352 - accuracy: 0.6727 - val_loss: 1.0651 - val_accuracy: 0.6350\n",
      "Epoch 76/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.0354 - accuracy: 0.6662 - val_loss: 1.0534 - val_accuracy: 0.6430\n",
      "Epoch 77/100\n",
      "125/125 [==============================] - 57s 453ms/step - loss: 1.0294 - accuracy: 0.6662 - val_loss: 1.0510 - val_accuracy: 0.6550\n",
      "Epoch 78/100\n",
      "125/125 [==============================] - 57s 453ms/step - loss: 1.0230 - accuracy: 0.6733 - val_loss: 1.0229 - val_accuracy: 0.6620\n",
      "Epoch 79/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 1.0049 - accuracy: 0.6685 - val_loss: 1.0117 - val_accuracy: 0.6500\n",
      "Epoch 80/100\n",
      "125/125 [==============================] - 56s 447ms/step - loss: 1.0287 - accuracy: 0.6693 - val_loss: 1.0722 - val_accuracy: 0.6320\n",
      "Epoch 81/100\n",
      "125/125 [==============================] - 56s 452ms/step - loss: 0.9973 - accuracy: 0.6783 - val_loss: 1.0493 - val_accuracy: 0.6560\n",
      "Epoch 82/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 1.0021 - accuracy: 0.6817 - val_loss: 0.9638 - val_accuracy: 0.6770\n",
      "Epoch 83/100\n",
      "125/125 [==============================] - 57s 454ms/step - loss: 1.0031 - accuracy: 0.6800 - val_loss: 1.0365 - val_accuracy: 0.6540\n",
      "Epoch 84/100\n",
      "125/125 [==============================] - 56s 445ms/step - loss: 0.9859 - accuracy: 0.6867 - val_loss: 1.0449 - val_accuracy: 0.6490\n",
      "Epoch 85/100\n",
      "125/125 [==============================] - 55s 438ms/step - loss: 0.9872 - accuracy: 0.6840 - val_loss: 1.0435 - val_accuracy: 0.6610\n",
      "Epoch 86/100\n",
      "125/125 [==============================] - 57s 456ms/step - loss: 0.9900 - accuracy: 0.6837 - val_loss: 1.0121 - val_accuracy: 0.6690\n",
      "Epoch 87/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 0.9744 - accuracy: 0.6898 - val_loss: 1.0126 - val_accuracy: 0.6620\n",
      "Epoch 88/100\n",
      "125/125 [==============================] - 57s 456ms/step - loss: 0.9805 - accuracy: 0.6830 - val_loss: 1.0174 - val_accuracy: 0.6630\n",
      "Epoch 89/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 0.9726 - accuracy: 0.6798 - val_loss: 1.1025 - val_accuracy: 0.6260\n",
      "Epoch 90/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 0.9697 - accuracy: 0.6815 - val_loss: 1.0069 - val_accuracy: 0.6640\n",
      "Epoch 91/100\n",
      "125/125 [==============================] - 55s 439ms/step - loss: 0.9654 - accuracy: 0.6835 - val_loss: 1.0464 - val_accuracy: 0.6450\n",
      "Epoch 92/100\n",
      "125/125 [==============================] - 56s 446ms/step - loss: 0.9722 - accuracy: 0.6833 - val_loss: 1.0428 - val_accuracy: 0.6530\n",
      "Epoch 93/100\n",
      "125/125 [==============================] - 55s 444ms/step - loss: 0.9626 - accuracy: 0.6860 - val_loss: 0.9629 - val_accuracy: 0.6750\n",
      "Epoch 94/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 0.9472 - accuracy: 0.6930 - val_loss: 0.9866 - val_accuracy: 0.6710\n",
      "Epoch 95/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 0.9285 - accuracy: 0.6970 - val_loss: 0.9925 - val_accuracy: 0.6740\n",
      "Epoch 96/100\n",
      "125/125 [==============================] - 55s 442ms/step - loss: 0.9325 - accuracy: 0.7030 - val_loss: 1.0282 - val_accuracy: 0.6610\n",
      "Epoch 97/100\n",
      "125/125 [==============================] - 55s 443ms/step - loss: 0.9534 - accuracy: 0.6977 - val_loss: 1.0087 - val_accuracy: 0.6480\n",
      "Epoch 98/100\n",
      "125/125 [==============================] - 56s 445ms/step - loss: 0.9582 - accuracy: 0.6845 - val_loss: 1.0345 - val_accuracy: 0.6560\n",
      "Epoch 99/100\n",
      "125/125 [==============================] - 56s 448ms/step - loss: 0.9299 - accuracy: 0.6998 - val_loss: 0.9744 - val_accuracy: 0.6860\n",
      "Epoch 100/100\n",
      "125/125 [==============================] - 55s 440ms/step - loss: 0.9254 - accuracy: 0.7017 - val_loss: 0.9833 - val_accuracy: 0.6780\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<bound method Model.evaluate of <keras.engine.sequential.Sequential object at 0x7ff455bf7410>>"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import datetime, os\n",
    "logdir = os.path.join(\"logs\", datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n",
    "tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)\n",
    "\n",
    "# Compile Network \n",
    "model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001, decay=1e-6),\n",
    "              loss='categorical_crossentropy',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "num_validation_examples = 1000\n",
    "num_train_examples = 5000\n",
    "\n",
    "\n",
    "train_iterator = train_datagen.flow(X_train_zc[num_validation_examples:num_train_examples], \n",
    "                                    y_train_cat[num_validation_examples:num_train_examples], \n",
    "                                    batch_size=32)\n",
    "validation_iterator = validation_datagen.flow(X_train_zc[:num_validation_examples:], \n",
    "                                              y_train_cat[:num_validation_examples:], \n",
    "                                              batch_size=32)\n",
    "\n",
    "# Fit Network\n",
    "history = model.fit_generator(generator= train_iterator,  \n",
    "                              validation_data = validation_iterator, \n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "                              epochs=100, \n",
    "                              steps_per_epoch=len(train_iterator),\n",
    "                              callbacks=[tensorboard_callback])\n",
    "\n",
    "# Determine \n",
    "model.evaluate"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 Evaluate the Network on the test dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "313/313 [==============================] - 30s 95ms/step - loss: 1.0085 - accuracy: 0.6609\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[1.0084725618362427, 0.6608999967575073]"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(X_test_zc, y_test_cat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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vna73X2+d+PGjdx+++39fsapp546JG1du3YtF1100ZDca7TImLIQQoheZWVlsWXLFgDuvPNOkpOT+cpXvtJ53uv14nKFDiXLly9n+fLl/X7G+vXrh6StY4FkykIIIQbk+uuv59Zbb2XVqlV87WtfY8OGDZxyyimcdNJJnHrqqezduxfomrneeeed3HjjjaxevZpp06Zx1113dd4vOTm58/rVq1dzxRVXMGfOHK699lrsnQyfe+455syZw7Jly7j99tsHlBE/9NBDLFy4kAULFvD1r38dAJ/Px/XXX8+CBQtYuHAhv/nNbwC46667mDdvHosWLeLqq68+8W/WAEmmLIQQUeL7z+xkV2njkN5z3oRUvvfh+QN+X0lJCevXr8fpdNLY2Mgbb7yBy+Xi5Zdf5pvf/CaPP/54j/fs2bOH1157jaamJmbPns1tt93WY9nQ+++/z86dO5kwYQKnnXYab731FsuXL+eWW25h3bp1TJ06lWuuuSbsdpaWlvL1r3+dTZs2kZGRwXnnncdTTz1FUVERx48fZ8eOHQDU19cD8NOf/pTDhw8TFxfXeWwkSaYshBBiwK688kqcTicADQ0NXHnllSxYsIA77riDnTt3hnzPhRdeSFxcHNnZ2eTm5lJRUdHjmpUrV1JYWIjD4WDJkiUUFxezZ88epk2b1rnEaCBB+b333mP16tXk5OTgcrm49tprWbduHdOmTePQoUN8/vOf54UXXiA1NRWARYsWce211/LAAw/02i0/nCRTFkKIKDGYjHa4JCUldT7/zne+w5o1a3jyyScpLi5m9erVId8TFxfX+dzpdOL1egd1zVDIyMhg69atvPjii9x99908+uij3HvvvTz77LOsW7eOZ555hh//+Mds3759RIOzZMpCCCFOSENDAxMnTgTg/vvvH/L7z549m0OHDlFcXAzAI488EvZ7V65cyeuvv051dTU+n4+HHnqIs846i+rqavx+P5dffjk/+tGP2Lx5M36/n2PHjrFmzRp+9rOf0dDQQHNz85B/PX2RTFkIIcQJ+drXvsYnP/lJfvSjH3HhhRcO+f0TEhL44x//yPnnn09SUhIrVqzo9dpXXnmFwsLCztf/+te/+OlPf8qaNWvQWnPhhRdyySWXsHXrVm644Qb8fj8AP/nJT/D5fFx33XU0NDSgteb2228nPT19yL+evih7ZttIW758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li3j9ttv77xvd2vXrmX+/PncdtttPPTQQ53HKyoquOyyy1i8eDGLFy/u/EXg73//O4sWLWLx4sV8/OMf7/z6HnvssZDtO+OMM7j44ouZN8+U0bv00ktZtmwZ8+fP55577ul8zwsvvMDSpUtZvHgxZ599Nn6/n5kzZ2JXs/L7/cyYMQOpbiXECEnKBlRg3+YwKaU4Y2YOj916Kl8/fw5JcS7u/vgy7v74MhpUirkonKA8DCI2LbD7+uNixnbxkO8/s5NdpY1Des95E1L53ofnD/h9JSUlrF+/HqfTSWNjI2+88QYul4uXX36Zb37zmzz++OM93rNnzx5ee+01mpqamD17NrfddluPJT3vv/8+O3fuZMKECZx22mm89dZbLF++nFtuuYV169YxdepUrrmm95U6Dz30ENdccw2XXHIJ3/zmN/F4PMTExHD77bdz1lln8eSTT+Lz+Whubmbnzp386Ec/Yv369WRnZ1Nb29feC8bmzZvZsWNH56zne++9l8zMTNra2lixYgWXX345fr+fm266qbO9tbW1OBwOrrvuOh588EG++MUv8vLLL7N48WKkupUQIyQuBa79F0xcNqi3Ox2K21ZP57bV0zuPJa28jl+uT+O8xkQWpYZ+n9vr551DNZwxM3vI54KElYYqpc5XSu219lj9RojzX1JK7bL2X31FKXXCI94dkimPuCuvvBKn0/wS1NDQwJVXXsmCBQu444472LkzdFWcCy+8kLi4OLKzs8nNzaWioqLHNStXrqSwsBCHw8GSJUsoLi5mz549TJs2rTMQ9haU3W43zz33HJdeeimpqamsWrWKF198EYBXX32V2267DQCn00laWhqvvvoqV155JdnZZuJHZmZmyPt2b1/wMqS77rqLxYsXc/LJJ3Ps2DH279/PO++8w5lnntl5nX3fG2+8kb///e+ACeY33CC1NoQYUTPP7VJE5EStPvtD3Ou8ggfeORLyfEldK1f+39t84t4NvLSr58+7E9VvpqyUcgJ/AM7F7BjznlLqaa31rqDL3geWa61blVK3AT8HPnoiDRvrs69tg8loh0tSUlLn8+985zusWbOGJ598kuLiYlavXh3yPXFxcZ3PnU4nXq93UNf05sUXX6S+vp6FC83C/9bWVhISEnrt6u6Ny+XqnCTm9/u7TGgL/rrXrl3Lyy+/zNtvv01iYiKrV6/uc5lS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\n",
      "text/plain": [
       "<Figure size 576x576 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot training and validation accuracy\n",
    "acc = history.history['accuracy']\n",
    "val_acc = history.history['val_accuracy']\n",
    "\n",
    "loss = history.history['loss']\n",
    "val_loss = history.history['val_loss']\n",
    "\n",
    "epochs_range = range(100)\n",
    "\n",
    "plt.figure(figsize=(8, 8))\n",
    "plt.subplot(1, 2, 1)\n",
    "plt.plot(epochs_range, acc, label='Training Accuracy')\n",
    "plt.plot(epochs_range, val_acc, label='Validation Accuracy')\n",
    "plt.legend(loc='lower right')\n",
    "plt.title('Training and Validation Accuracy')\n",
    "\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(epochs_range, loss, label='Training Loss')\n",
    "plt.plot(epochs_range, val_loss, label='Validation Loss')\n",
    "plt.legend(loc='upper right')\n",
    "plt.title('Training and Validation Loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the TensorBoard notebook extension\n",
    "%load_ext tensorboard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ERROR: Failed to launch TensorBoard (exited with 1).\n",
       "Contents of stderr:\n",
       "Traceback (most recent call last):\n",
       "  File \"/opt/conda/bin/tensorboard\", line 5, in <module>\n",
       "    from tensorboard.main import run_main\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/tensorboard/main.py\", line 27, in <module>\n",
       "    from tensorboard import default\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/tensorboard/default.py\", line 33, in <module>\n",
       "    from tensorboard.plugins.audio import audio_plugin\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/tensorboard/plugins/audio/audio_plugin.py\", line 23, in <module>\n",
       "    from tensorboard import plugin_util\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/tensorboard/plugin_util.py\", line 24, in <module>\n",
       "    import markdown\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/markdown/__init__.py\", line 29, in <module>\n",
       "    from .core import Markdown, markdown, markdownFromFile  # noqa: E402\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/markdown/core.py\", line 26, in <module>\n",
       "    from . import util\n",
       "  File \"/opt/conda/lib/python3.7/site-packages/markdown/util.py\", line 88, in <module>\n",
       "    INSTALLED_EXTENSIONS = metadata.entry_points(group='markdown.extensions')\n",
       "TypeError: entry_points() got an unexpected keyword argument 'group'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "os.makedirs(logdir, exist_ok=True)\n",
    "%tensorboard --logdir logs\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Save the model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "model.save('./Daten/cifar_10_convnets_1.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "FE7KNzPPVrVV"
   },
   "source": [
    "# Part 2 - Dogs vs Cats Image Classification : Visualizing what ConvNets learn?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "gN7G9GFmVrVY"
   },
   "source": [
    "In this notebook chapter, we will discuss how to classify images into pictures of cats or pictures of dogs. We'll build an image classifier using `tf.keras.Sequential` model and load data using `tf.keras.preprocessing.image.ImageDataGenerator`. At the end, we will visualize filters and intermediate activation layers.\n",
    "\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "### Specific concepts that will be covered:\n",
    "In the process, we will build practical experience and develop intuition around the following concepts\n",
    "\n",
    "* Building _data input pipelines_ using the `tf.keras.preprocessing.image.ImageDataGenerator` class — How can we efficiently work with data on disk to interface with our model?\n",
    "* _Overfitting_ - what is it, how to identify it, and how can we prevent it?\n",
    "* _Data Augmentation_ and _Dropout_ - Key techniques to fight overfitting in computer vision tasks that we will incorporate into our data pipeline and image classifier model.\n",
    "* _Visualizing ConvNet filters_\n",
    "* _Visualizing intermediate activations_\n",
    "\n",
    "\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "### We will follow the general machine learning workflow:\n",
    "\n",
    "1. Examine and understand data\n",
    "2. Build an input pipeline\n",
    "3. Build our model\n",
    "4. Train our model\n",
    "5. Test our model\n",
    "6. Improve our model/Repeat the process\n",
    "\n",
    "<hr>\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "zF9uvbXNVrVY"
   },
   "source": [
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "### Importing packages"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "VddxeYBEVrVZ"
   },
   "source": [
    "Let's start by importing required packages:\n",
    "\n",
    "*   os — to read files and directory structure\n",
    "*   numpy — for some matrix math outside of TensorFlow\n",
    "*   matplotlib.pyplot — to plot the graph and display images in our training and validation data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "rtPGh2MAVrVa"
   },
   "outputs": [],
   "source": [
    "from __future__ import absolute_import, division, print_function, unicode_literals\n",
    "\n",
    "import os\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "L1WtoaOHVrVh"
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UZZI6lNkVrVm"
   },
   "source": [
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "### Data Loading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "DPHx8-t-VrVo"
   },
   "source": [
    "To build our image classifier, we begin by downloading the dataset. The dataset we are using is a filtered version of <a href=\"https://www.kaggle.com/c/dogs-vs-cats/data\" target=\"_blank\">Dogs vs. Cats</a> dataset from Kaggle (ultimately, this dataset is provided by Microsoft Research).\n",
    "\n",
    "In this Jupyter Notebook however, we will make use of the class `tf.keras.preprocessing.image.ImageDataGenerator` which will read data from disk. We therefore need to directly download *Dogs vs. Cats* from a URL and unzip it to your computers filesystem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "OYmOylPlVrVt"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading data from https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip\n",
      "68608000/68606236 [==============================] - 0s 0us/step\n",
      "68616192/68606236 [==============================] - 0s 0us/step\n"
     ]
    }
   ],
   "source": [
    "_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'\n",
    "\n",
    "zip_dir = tf.keras.utils.get_file('cats_and_dogs_filterted.zip', origin=_URL, extract=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Giv0wMQzVrVw"
   },
   "source": [
    "The dataset we have downloaded has following directory structure.\n",
    "\n",
    "<pre style=\"font-size: 10.0pt; font-family: Arial; line-height: 2; letter-spacing: 1.0pt;\" >\n",
    "<b>cats_and_dogs_filtered</b>\n",
    "|__ <b>train</b>\n",
    "    |______ <b>cats</b>: [cat.0.jpg, cat.1.jpg, cat.2.jpg ....]\n",
    "    |______ <b>dogs</b>: [dog.0.jpg, dog.1.jpg, dog.2.jpg ...]\n",
    "|__ <b>validation</b>\n",
    "    |______ <b>cats</b>: [cat.2000.jpg, cat.2001.jpg, cat.2002.jpg ....]\n",
    "    |______ <b>dogs</b>: [dog.2000.jpg, dog.2001.jpg, dog.2002.jpg ...]\n",
    "</pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "VpmywIlsVrVx"
   },
   "source": [
    "We'll now assign variables with the proper file path for the training and validation sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "sRucI3QqVrVy"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/jovyan/.keras/datasets\n",
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered\n",
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered/train\n",
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered/validation\n"
     ]
    }
   ],
   "source": [
    "print(os.path.dirname(zip_dir))\n",
    "base_dir = os.path.join(os.path.dirname(zip_dir), 'cats_and_dogs_filtered')\n",
    "print(base_dir)\n",
    "train_dir = os.path.join(base_dir, 'train')\n",
    "print(train_dir)\n",
    "validation_dir = os.path.join(base_dir, 'validation')\n",
    "print(validation_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "Utv3nryxVrV0"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered/train/cats\n",
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered/train/dogs\n",
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered/validation/cats\n",
      "/home/jovyan/.keras/datasets/cats_and_dogs_filtered/validation/dogs\n"
     ]
    }
   ],
   "source": [
    "train_cats_dir = os.path.join(train_dir, 'cats')  # directory with our training cat pictures\n",
    "print(train_cats_dir)\n",
    "train_dogs_dir = os.path.join(train_dir, 'dogs')  # directory with our training dog pictures\n",
    "print(train_dogs_dir)\n",
    "validation_cats_dir = os.path.join(validation_dir, 'cats')  # directory with our validation cat pictures\n",
    "print(validation_cats_dir)\n",
    "validation_dogs_dir = os.path.join(validation_dir, 'dogs')  # directory with our validation dog pictures\n",
    "print(validation_dogs_dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "ZdrHHTy2VrV3"