{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### CNN avec keras\n",
    "\n",
    "Dans ce notebook, nous allons utiliser keras pour concevoir et entrainer un réseau de neurones avec une architecture CNN.\n",
    "\n",
    "La chargement, le découpage et en général le prétraitement des données reste le même. Ce qui change essentiellement c'est l'architecture du réseau."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "import keras\n",
    "import numpy as np\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from keras.datasets import mnist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "(X_train, Y_train), (X_test, Y_test) = mnist.load_data()\n",
    "\n",
    "#To input our values in our network Conv2D layer, we need to reshape the datasets, i.e.,\n",
    "# pass from (60000, 28, 28) to (60000, 28, 28, 1) where 1 is the number of channels of our images\n",
    "img_rows, img_cols = X_train.shape[1], X_train.shape[2]\n",
    "X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)\n",
    "X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)\n",
    "\n",
    "X_train = X_train.astype('float32')\n",
    "X_test = X_test.astype('float32')\n",
    "Y_train = Y_train.astype('float32')\n",
    "Y_test = Y_test.astype('float32')\n",
    "X_train  = X_train / 255\n",
    "X_test  = X_test / 255"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La commence réellement l'utilisation des CNN. Nous avons besoin d'importer un certain nombre d'autres éléments de la bibliothèque keras :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten\n",
    "from keras.optimizers import adam"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et on définit notre réseau :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "\n",
    "#Convert class vectors to binary class matrices (\"one hot encoding\")\n",
    "## Doc : https://keras.io/utils/#to_categorical\n",
    "Y_train = keras.utils.to_categorical(Y_train, num_classes)\n",
    "Y_test = keras.utils.to_categorical(Y_test, num_classes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cnn():\n",
    "    model = Sequential()\n",
    "    model.add(Conv2D(32,\n",
    "                     kernel_size=(3,3),\n",
    "                     activation='relu',\n",
    "                     input_shape=(28, 28, 1)))\n",
    "    model.add(Conv2D(64,\n",
    "                     kernel_size=(3,3),\n",
    "                     activation='relu'))\n",
    "    model.add(MaxPooling2D(pool_size=(2,2)))\n",
    "    model.add(Flatten())\n",
    "    model.add(Dense(128, activation='relu'))\n",
    "    model.add(Dense(num_classes, activation='softmax'))\n",
    "    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "    return model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On créee donc notre réseau :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       \n",
      "_________________________________________________________________\n",
      "conv2d_2 (Conv2D)            (None, 24, 24, 64)        18496     \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 12, 12, 64)        0         \n",
      "_________________________________________________________________\n",
      "flatten_1 (Flatten)          (None, 9216)              0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 128)               1179776   \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 10)                1290      \n",
      "=================================================================\n",
      "Total params: 1,199,882\n",
      "Trainable params: 1,199,882\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model = cnn()\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "et on l'antraine :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/10\n",
      "60000/60000 [==============================] - 62s 1ms/step - loss: 0.1229 - accuracy: 0.9623 - val_loss: 0.0491 - val_accuracy: 0.9835\n",
      "Epoch 2/10\n",
      "60000/60000 [==============================] - 65s 1ms/step - loss: 0.0389 - accuracy: 0.9878 - val_loss: 0.0344 - val_accuracy: 0.9885\n",
      "Epoch 3/10\n",
      "60000/60000 [==============================] - 65s 1ms/step - loss: 0.0230 - accuracy: 0.9926 - val_loss: 0.0434 - val_accuracy: 0.9879\n",
      "Epoch 4/10\n",
      "60000/60000 [==============================] - 70s 1ms/step - loss: 0.0168 - accuracy: 0.9946 - val_loss: 0.0314 - val_accuracy: 0.9898\n",
      "Epoch 5/10\n",
      "60000/60000 [==============================] - 71s 1ms/step - loss: 0.0111 - accuracy: 0.9964 - val_loss: 0.0310 - val_accuracy: 0.9904\n",
      "Epoch 6/10\n",
      "60000/60000 [==============================] - 70s 1ms/step - loss: 0.0092 - accuracy: 0.9967 - val_loss: 0.0423 - val_accuracy: 0.9877\n",
      "Epoch 7/10\n",
      "60000/60000 [==============================] - 66s 1ms/step - loss: 0.0061 - accuracy: 0.9979 - val_loss: 0.0451 - val_accuracy: 0.9889\n",
      "Epoch 8/10\n",
      "60000/60000 [==============================] - 62s 1ms/step - loss: 0.0066 - accuracy: 0.9978 - val_loss: 0.0430 - val_accuracy: 0.9894\n",
      "Epoch 9/10\n",
      "60000/60000 [==============================] - 58s 970us/step - loss: 0.0054 - accuracy: 0.9982 - val_loss: 0.0480 - val_accuracy: 0.9892\n",
      "Epoch 10/10\n",
      "60000/60000 [==============================] - 60s 994us/step - loss: 0.0051 - accuracy: 0.9983 - val_loss: 0.0475 - val_accuracy: 0.9887\n"
     ]
    }
   ],
   "source": [
    "batch_size=64\n",
    "epochs=10\n",
    "\n",
    "hist = model.fit(X_train, Y_train,\n",
    "            validation_data=(X_test, Y_test),\n",
    "            epochs=epochs,\n",
    "            batch_size=batch_size)            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test loss:  0.04750595308612313\n",
      "Test accuracy:  0.9886999726295471\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "score = model.evaluate(X_test, Y_test, verbose=0)\n",
    "print('Test loss: ', score[0])\n",
    "print('Test accuracy: ', score[1])\n",
    "#plot accuracies\n",
    "plt.plot(hist.history['accuracy'])\n",
    "#plt.plot(hist.history['val_acc'])\n",
    "plt.title('model accuracy')\n",
    "plt.xlabel('epoch')\n",
    "plt.ylabel('accuracy')\n",
    "plt.legend(['train', 'test'], loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
