{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "German Traffic Sign Recognition Benchmark (GTSRB)\n", "=================================================\n", "---\n", "Introduction au Deep Learning (IDLE) - S. Arias, E. Maldonado, JL. Parouty - CNRS/SARI/DEVLOG - 2020 \n", "Vesion : 1.2.1\n", "\n", "## Episode 7 : Full Convolutions\n", "\n", "Our main steps:\n", " - Try n models with n datasets\n", "\n", "## 1/ Import and init" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "IDLE 2020 - Practical Work Module\n", " Version : 0.1.4\n", " Run time : Friday 17 January 2020, 21:38:34\n", " Matplotlib style : idle/talk.mplstyle\n", " TensorFlow version : 2.0.0\n", " Keras version : 2.2.4-tf\n" ] } ], "source": [ "import tensorflow as tf\n", "from tensorflow import keras\n", "from tensorflow.keras.callbacks import TensorBoard\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import h5py\n", "import os,time\n", "\n", "import pandas as pd\n", "import idle.pwk as ooo\n", "from importlib import reload\n", "from IPython.display import display\n", "\n", "ooo.init()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2/ Load dataset functions" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "def read_dataset(name):\n", " '''Reads h5 dataset from ./data\n", "\n", " Arguments: dataset name, without .h5\n", " Returns: x_train,y_train,x_test,y_test data'''\n", " # ---- Read dataset\n", " filename='./data/'+name+'.h5'\n", " with h5py.File(filename) as f:\n", " x_train = f['x_train'][:]\n", " y_train = f['y_train'][:]\n", " x_test = f['x_test'][:]\n", " y_test = f['y_test'][:]\n", "\n", " return x_train,y_train,x_test,y_test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3/ Models collection" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "\n", "# A basic model\n", "#\n", "def get_model_v1(lx,ly,lz):\n", " \n", " model = keras.models.Sequential()\n", " \n", " model.add( keras.layers.Conv2D(96, (3,3), activation='relu', input_shape=(lx,ly,lz)))\n", " model.add( keras.layers.MaxPooling2D((2, 2)))\n", " model.add( keras.layers.Dropout(0.2))\n", "\n", " model.add( keras.layers.Conv2D(192, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D((2, 2)))\n", " model.add( keras.layers.Dropout(0.2))\n", "\n", " model.add( keras.layers.Flatten()) \n", " model.add( keras.layers.Dense(1500, activation='relu'))\n", " model.add( keras.layers.Dropout(0.5))\n", "\n", " model.add( keras.layers.Dense(43, activation='softmax'))\n", " return model\n", " \n", "# A more sophisticated model\n", "#\n", "def get_model_v2(lx,ly,lz):\n", " model = keras.models.Sequential()\n", "\n", " model.add( keras.layers.Conv2D(64, (3, 3), padding='same', input_shape=(lx,ly,lz), activation='relu'))\n", " model.add( keras.layers.Conv2D(64, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D(pool_size=(2, 2)))\n", " model.add( keras.layers.Dropout(0.2))\n", "\n", " model.add( keras.layers.Conv2D(128, (3, 3), padding='same', activation='relu'))\n", " model.add( keras.layers.Conv2D(128, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D(pool_size=(2, 2)))\n", " model.add( keras.layers.Dropout(0.2))\n", "\n", " model.add( keras.layers.Conv2D(256, (3, 3), padding='same',activation='relu'))\n", " model.add( keras.layers.Conv2D(256, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D(pool_size=(2, 2)))\n", " model.add( keras.layers.Dropout(0.2))\n", "\n", " model.add( keras.layers.Flatten())\n", " model.add( keras.layers.Dense(512, activation='relu'))\n", " model.add( keras.layers.Dropout(0.5))\n", " model.add( keras.layers.Dense(43, activation='softmax'))\n", " return model\n", "\n", "# My sphisticated model, but small and fast\n", "#\n", "def get_model_v3(lx,ly,lz):\n", " model = keras.models.Sequential()\n", " model.add( keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(lx,ly,lz)))\n", " model.add( keras.layers.MaxPooling2D((2, 2)))\n", " model.add( keras.layers.Dropout(0.5))\n", "\n", " model.add( keras.layers.Conv2D(64, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D((2, 2)))\n", " model.add( keras.layers.Dropout(0.5))\n", "\n", " model.add( keras.layers.Conv2D(128, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D((2, 2)))\n", " model.add( keras.layers.Dropout(0.5))\n", "\n", " model.add( keras.layers.Conv2D(256, (3, 3), activation='relu'))\n", " model.add( keras.layers.MaxPooling2D((2, 2)))\n", " model.add( keras.layers.Dropout(0.5))\n", "\n", " model.add( keras.layers.Flatten()) \n", " model.add( keras.layers.Dense(1152, activation='relu'))\n", " model.add( keras.layers.Dropout(0.5))\n", "\n", " model.add( keras.layers.Dense(43, activation='softmax'))\n", " return model\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4/ Callbacks " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "total 0\n" ] } ], "source": [ "%%bash\n", "# To clean old logs and saved model, run this cell\n", "#\n", "/bin/rm -r ./run/logs 2>/dev/null\n", "/bin/rm -r ./run/models 2>/dev/null\n", "/bin/ls -l ./run 2>/dev/null" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "ooo.mkdir('./run/models')\n", "ooo.mkdir('./run/logs')\n", "\n", "# ---- Callback tensorboard\n", "log_dir = \"./run/logs/tb_\" + ooo.tag_now()\n", "tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)\n", "\n", "# ---- Callback ModelCheckpoint - Save best model\n", "save_dir = \"./run/models/best-model.h5\"\n", "bestmodel_callback = tf.keras.callbacks.ModelCheckpoint(filepath=save_dir, verbose=0, monitor='accuracy', save_best_only=True)\n", "\n", "# ---- Callback ModelCheckpoint - Save model each epochs\n", "save_dir = \"./run/models/model-{epoch:04d}.h5\"\n", "savemodel_callback = tf.keras.callbacks.ModelCheckpoint(filepath=save_dir, verbose=0, save_freq=2000*5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6/ Multiple datasets, multiple models ;-)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "def multi_run(datasets, models, batch_size=64, epochs=16):\n", "\n", " # ---- Columns of report\n", " #\n", " report={}\n", " report['Dataset']=[]\n", " report['Size'] =[]\n", " for m in models:\n", " report[m+' Accuracy'] = []\n", " report[m+' Duration'] = []\n", "\n", " # ---- Let's go\n", " #\n", " for dname in datasets:\n", " print(\"\\nDataset : \",dname)\n", "\n", " # ---- Read dataset\n", " x_train,y_train,x_test,y_test = read_dataset(dname)\n", " dsize=os.path.getsize('./data/'+dname+'.h5')/(1024*1024)\n", " report['Dataset'].append(dname)\n", " report['Size'].append(dname)\n", " \n", " # ---- Get the shape\n", " (n,lx,ly,lz) = x_train.shape\n", "\n", " # ---- For each model\n", " for kmodel,fmodel in models.items():\n", " print(\" Run model {} : \".format(kmodel), end='')\n", " # ---- get model\n", " try:\n", " model=fmodel(lx,ly,lz)\n", " # ---- Compile it\n", " model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n", " # ---- Train\n", " start_time = time.time()\n", " history = model.fit( x_train[:1000], y_train[:1000],\n", " batch_size = batch_size,\n", " epochs = epochs,\n", " verbose = 0,\n", " validation_data = (x_test, y_test),\n", " callbacks = [tensorboard_callback, bestmodel_callback, savemodel_callback])\n", " # ---- Result\n", " end_time = time.time()\n", " duration = end_time-start_time\n", " accuracy = max(history.history[\"val_accuracy\"])*100\n", " #\n", " report[kmodel+' Accuracy'].append(accuracy)\n", " report[kmodel+' Duration'].append(duration)\n", " print(\"Accuracy={:.2f} and Duration={:.2f})\".format(accuracy,duration))\n", " except:\n", " report[kmodel+' Accuracy'].append('-')\n", " report[kmodel+' Duration'].append('-')\n", " print('-')\n", " print(\"\\n\")\n", " return report" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Dataset : set-24x24-L\n", " Run model v1 : Accuracy=9.46 and Duration=7.51)\n", " Run model v3 : -\n", "\n", "Dataset : set-24x24-RGB\n", " Run model v1 : Accuracy=15.95 and Duration=7.95)\n", " Run model v3 : -\n", "\n", "\n", "CPU times: user 1min 35s, sys: 3.31 s, total: 1min 38s\n", "Wall time: 17 s\n" ] } ], "source": [ "%%time\n", "\n", "# datasets = ['set-24x24-L', 'set-24x24-RGB', 'set-48x48-L', 'set-48x48-RGB', 'set-24x24-L-LHE', 'set-24x24-RGB-HE', 'set-48x48-L-LHE', 'set-48x48-RGB-HE']\n", "# models = {'v1':get_model_v1, 'v2':get_model_v2, 'v3':get_model_v3}\n", "\n", "datasets = ['set-24x24-L', 'set-24x24-RGB']\n", "models = {'v1':get_model_v1, 'v3':get_model_v3}\n", "\n", "out = multi_run(datasets, models, batch_size=64, epochs=2)\n", "report = pd.DataFrame (out)\n" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>Dataset</th>\n", " <th>Size</th>\n", " <th>v1 Accuracy</th>\n", " <th>v1 Duration</th>\n", " <th>v3 Accuracy</th>\n", " <th>v3 Duration</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>set-24x24-L</td>\n", " <td>set-24x24-L</td>\n", " <td>9.46160</td>\n", " <td>7.514726</td>\n", " <td>-</td>\n", " <td>-</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>set-24x24-RGB</td>\n", " <td>set-24x24-RGB</td>\n", " <td>15.94616</td>\n", " <td>7.946994</td>\n", " <td>-</td>\n", " <td>-</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " Dataset Size v1 Accuracy v1 Duration v3 Accuracy \\\n", "0 set-24x24-L set-24x24-L 9.46160 7.514726 - \n", "1 set-24x24-RGB set-24x24-RGB 15.94616 7.946994 - \n", "\n", " v3 Duration \n", "0 - \n", "1 - " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(report)\n", "df.to_hdf('foo.h5', 'df')" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>Dataset</th>\n", " <th>Size</th>\n", " <th>v1 Accuracy</th>\n", " <th>v1 Duration</th>\n", " <th>v3 Accuracy</th>\n", " <th>v3 Duration</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>set-24x24-L</td>\n", " <td>set-24x24-L</td>\n", " <td>11.892320</td>\n", " <td>8.730333</td>\n", " <td>-</td>\n", " <td>-</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>set-24x24-RGB</td>\n", " <td>set-24x24-RGB</td>\n", " <td>12.707838</td>\n", " <td>8.308997</td>\n", " <td>-</td>\n", " <td>-</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " Dataset Size v1 Accuracy v1 Duration v3 Accuracy \\\n", "0 set-24x24-L set-24x24-L 11.892320 8.730333 - \n", "1 set-24x24-RGB set-24x24-RGB 12.707838 8.308997 - \n", "\n", " v3 Duration \n", "0 - \n", "1 - " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df=pd.read_hdf('foo.h5', 'df')\n", "display(df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "### Some results : \n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| Datasets | Size | Model : v1 | Model : v2 | Model : v3 |\n", "|:------------------------:|:---------------:|:------------------:|:------------------:|:------------------:|\n", "| set-24x24-L | 229 Mo | 95.91% 75.04s | 96.86% 102.28s | - - |\n", "| set-24x24-RGB | 684 Mo | 96.60% 77.24s | 97.32% 103.93s | - - |\n", "| set-48x48-L | 914 Mo | **96.71%** 123.94s | 97.68% 149.57s | 97.60% 91.53s |\n", "| set-48x48-RGB | 2736 Mo | 96.36% 117.74s | **98.20%** 142.63s | 97.28% 91.29s |\n", "| set-24x24-L-LHE | 229 Mo | 95.95% 66.12s | 96.75% 89.45s | - - |\n", "| set-24x24-RGB-HE | 684 Mo | 95.30% 68.89s | 96.28% 92.15s | - - |\n", "| set-48x48-L-LHE | 914 Mo | 96.69% 109.28s | 97.94% 135.17s | **97.97%** 83.80s |\n", "| set-48x48-RGB-HE | 2736 Mo | 95.29% 117.70s | **98.13%** 141.56s | 97.00% 89.38s |" ] }, { "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.5" } }, "nbformat": 4, "nbformat_minor": 4 }