{"nbformat_minor": 1, "nbformat": 4, "metadata": {"language_info": {"pygments_lexer": "ipython3", "nbconvert_exporter": "python", "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "codemirror_mode": {"name": "ipython", "version": 3}, "version": "3.6.3"}, "kernelspec": {"name": "python3", "display_name": "Python 3", "language": "python"}}, "cells": [{"metadata": {"_uuid": "02735ddce5b62f3fd56c797b6c7d45d13479693a", "_cell_guid": "2c2784ee-8ee0-41d9-9d6a-b8d23f0f10a7"}, "cell_type": "markdown", "source": ["# UPDATE : I perform many updates to provide a better explanation of my code. In addition, I added layers and dropout in my CNN to have better results.\n", "\n", "# Convolutional Neural Network with tensorflow\n", "\n", "My goal is to use Tensorflow (not Keras) for this competition.\n", "Just a quick word about Keras. In order to have better result, it's better to use pre-trained model which can be export from Keras and do transfert leraning.To quickly summarize, you can reuse some weights from the pre-trained models and add or remove some of the layers in order to create a new model.\n", "Here we will not do it. We just want t create from scratch our own CNN.\n", "\n", "I share a Python code which shows how to use Tensorflow to build a simple convolutional network (2 layers of convolutional network). I learn a lot from [Hvass-Labs github](https://github.com/Hvass-Labs/TensorFlow-Tutorials) so go to see his tutorial, it's definitely one of the best. As you will see, I copy a lot from his code for the convolutional network part.\n", "\n", "To simplify the game, I will reduce the dataset with the 8 main breeds (take only 3 or 5 if you want to run the code faster)..\n", "\n", "Please let me know if you manage to improve the results (by using Tensorflow) and how did you do? I really need your help as you will see the results are not good. As well, if you find some mistakes or have some questions, do not hesitate to put a comment. I will continue to add more informations on this code to make it more clear.\n", "\n", "## Architecture\n", "We will create a Convolutional Neural Network (CNN) which willl be able to classify dogs depending on their breed. Our CNN architecture will be as followed:\n", "\n", "- Convolutional Layer n\u00b01 with 32 filters\n", " + Max pooling\n", " + Relu\n", "- Convolutional Layer n\u00b02 with 64 filters\n", " + Max pooling\n", " + Relu\n", "- Convolutional Layer n\u00b03 with 128 filters\n", " + Max pooling\n", " + Relu\n", " + DropOut\n", "- Flatten Layer\n", "- Fully Connected Layer with 500 nodes\n", " + Relu\n", " + DropOut\n", "- Fully Connected Layer with n nodes (n = number of breeds)\n", "\n", "## Preliminary work\n", "\n", "### **1. Packages**\n", "Let's import all the packages we need."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "46765236dae635ea92027d4d6da1af42a3185ec2", "_kg_hide-output": false, "_cell_guid": "94bc289c-c58e-4c85-977f-92d416a2f58f", "_kg_hide-input": false}, "cell_type": "code", "source": ["#We upload all the packages we need\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import tensorflow as tf\n", "import numpy as np\n", "import time\n", "from datetime import timedelta\n", "import math\n", "import os\n", "import scipy.misc\n", "from scipy.stats import itemfreq\n", "from random import sample\n", "import pickle\n", "from sklearn.metrics import confusion_matrix\n", "from sklearn.model_selection import train_test_split\n", "\n", "# Image manipulation.\n", "import PIL.Image\n", "from IPython.display import display\n", "#from resizeimage import resizeimage\n", "\n", "#Panda\n", "import pandas as pd\n", "\n", "#Open a Zip File\n", "from zipfile import ZipFile\n", "from io import BytesIO\n", "\n", "#check tensorflow version\n", "tf.__version__"]}, {"metadata": {"_uuid": "a4b95c1800b91abacbce6fd1040cebbd953f3928", "_cell_guid": "a0a434b9-a058-4e90-8a2f-bc4e3ad825c9"}, "cell_type": "markdown", "source": ["As you can see, I'm currently using the version 1.0.1 but you can use any other one less updated like 1.1.0. It should also work.\n", "\n", "### **2. Unzip the files**\n", "\n", "## **The following code is design to be run on *your own JUPYTER NOTEBOOK made on your computer*. It will not work on a Kaggle Kernel.**\n", "We need now to extract the train and test files from the zip. This is the code to use :"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "4e4ccf9d7a7584a209bc7b696d42242524227d66", "_cell_guid": "ded178d0-c866-4792-abaa-a88bdd145a7c", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["#We unzip the train and test zip file\n", "archive_train = ZipFile(\"Data/train.zip\", 'r')\n", "archive_test = ZipFile(\"Data/test.zip\", 'r')\n", "\n", "#This line shows the 5 first image name of the train database\n", "archive_train.namelist()[0:5]\n", "\n", "#This line shows the number of images in the train database\n", "len(archive_train.namelist()[:])-1 #we must remove the 1st value"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "381b4d1393f750e6261a361f06eb1e0812800352", "_cell_guid": "6efa3989-8bc3-4581-af53-fc1ae01d68b2", "_kg_hide-input": true}, "cell_type": "code", "source": ["10222"]}, {"metadata": {"_uuid": "cf571ca426ceb5d36f12138149132deea9586370", "_cell_guid": "92deb375-c571-4381-935b-8f3ba10f4b73"}, "cell_type": "markdown", "source": ["### **3. Resize and normalize the data**\n", "\n", "The next cells contains the following features:\n", "\n", "- a function which ****create a pickle file to save all the images unzipped.\n", "- all the images do not have the same shape. For our model, we need to resize them to the same shape. We use the commonly practice to reshape them as a square.\n", "- we normalize our dataset by dividing by 255 all the pixel values. The new pixels values will be in the range [0,1]."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "ef4eabfa88754d8002596fd1b97e5fcf9e61e458", "_cell_guid": "61edad19-3bb8-406c-8880-4f96e97771e7", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["# This function help to create  a pickle file gathering all the image from a zip folder\n", "###############\n", "def DataBase_creator(archivezip, nwigth, nheight, save_name):\n", "    #We choose the archive (zip file) + the new wigth and height for all the image which will be reshaped\n", "    \n", "    # Start-time used for printing time-usage below.\n", "    start_time = time.time()\n", "    \n", "    s = (len(archivezip.namelist()[:])-1, nwigth, nheight,3) #nwigth x nheight = number of features because images are nwigth x nheight pixels\n", "    allImage = np.zeros(s)\n", "\n", "    for i in range(1,len(archivezip.namelist()[:])):\n", "        filename = BytesIO(archivezip.read(archivezip.namelist()[i]))\n", "        image = PIL.Image.open(filename) # open colour image\n", "        image = image.resize((nwigth, nheight))\n", "        image = np.array(image)\n", "        image = np.clip(image/255.0, 0.0, 1.0) #255 = max of the value of a pixel\n", "\n", "        allImage[i-1]=image\n", "    \n", "    #we save the newly created data base\n", "    pickle.dump(allImage, open( save_name + '.p', \"wb\" ) )\n", "    \n", "    # Ending time.\n", "    end_time = time.time()\n", "\n", "    # Difference between start and end-times.\n", "    time_dif = end_time - start_time\n", "\n", "    # Print the time-usage.\n", "    print(\"Time usage: \" + str(timedelta(seconds=int(round(time_dif)))))"]}, {"metadata": {"_uuid": "24fe0b1d22b6b628ae658f8a961bdbc6bf53146a", "_cell_guid": "825e6e0b-4268-4b06-927a-a4f946a1b120"}, "cell_type": "markdown", "source": ["**We define the new image size applied for all images :**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "cf3d1d2aba10b615891f0928a6142a9d1379b53b", "_cell_guid": "39a57c73-4c06-4082-b4e0-10a716cf1d43", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["image_resize = 60"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "8f5cfe3d45efe55d7e3334b3999f3f7bd05e1fc7", "_cell_guid": "46ed3e33-1022-4b83-94f2-744bf122f019", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["DataBase_creator(archivezip = archive_train, nwigth = image_resize, nheight = image_resize , save_name = \"train\")"]}, {"metadata": {"_uuid": "ffc0d59dca1a20f8622c2b4a3ec2cf7011eaeb8b", "_cell_guid": "c0b5c95d-4fc6-46be-9fe4-3fba56ab400e"}, "cell_type": "markdown", "source": ["Time usage: 0:00:40"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "ee5edc05afc406f50c2ea5efec4b46e80c0935a9", "_cell_guid": "592ff135-aedd-42dc-9740-98f1ce9e3ef6", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["DataBase_creator(archivezip = archive_test, nwigth = image_resize, nheight = image_resize , save_name = \"test\")"]}, {"metadata": {"_uuid": "7e8ed1494f1e8711cc9e19c8f0f6d602399193ac", "_cell_guid": "f4edcedc-cc4c-4297-8dba-02899c89a576"}, "cell_type": "markdown", "source": ["Time usage: 0:00:41\n", "\n", "You have now a train and test pickle files. Next time you open this Python Notebook, you can load them directly and the step above can be skip if we relaunch the code later."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "6de948d217408bba3ed02cddf408c0e5f6c6b4ab", "_cell_guid": "0bf1a99b-3956-4ed0-ad99-6d80ba3d4a02", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["#load TRAIN\n", "train = pickle.load( open( \"train.p\", \"rb\" ) )\n", "train.shape"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "466fc580f9ce6e3558ce85a0302e40697c0dc84e", "_cell_guid": "d3eab799-d035-45d5-8f2c-6901794e2cb7", "_kg_hide-input": true}, "cell_type": "code", "source": ["(10222, 60, 60, 3)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "7475748c190f0bce29e797cc9de58272d2abef5f", "_cell_guid": "f9809677-e6af-4976-954d-1a2dd7953cac", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["#load TEST\n", "test = pickle.load( open( \"test.p\", \"rb\" ) )\n", "test.shape"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "605f42cba4d15b225b9d37ba4d70bf19f8ce70e0", "_cell_guid": "e63486a2-0113-4736-972a-272291df0ba9", "_kg_hide-input": true}, "cell_type": "code", "source": ["(10357, 60, 60, 3)"]}, {"metadata": {"_uuid": "569942754044a793a3f2e034311addd0433315e4", "_cell_guid": "446139b2-1493-4ad0-89e2-87f68713821f"}, "cell_type": "markdown", "source": ["## **The following code is design for the *Kaggle Kernel*. DO NOT COPY IT ON YOUR COMPUTER.**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "7ed6f91584253eb2095a3750a7ca1607ec70fd20", "_cell_guid": "5be613d5-bb5d-465c-bad1-04a19acf4a66"}, "cell_type": "code", "source": ["df_train= pd.read_csv('../input/labels.csv')\n", "df_train.sample(5)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "ee1ef62294fe5036bd5886d33eab7ff63aa950e7", "_cell_guid": "3307f16a-20b3-47ec-a1d2-f890cb8fb62c"}, "cell_type": "code", "source": ["image_resize = 60\n", "nwigth = image_resize\n", "nheight = image_resize\n", "\n", "\n", "# Start-time used for printing time-usage below.\n", "start_time = time.time()\n", "\n", "s = (len(df_train['breed']), nwigth, nheight,3) #nwigth x nheight = number of features because images are nwigth x nheight pixels\n", "allImage = np.zeros(s)\n", "i= 0\n", "for f, breed in df_train.values:\n", "    image = PIL.Image.open('../input/train/{}.jpg'.format(f))\n", "    image = image.resize((nwigth, nheight))\n", "    image = np.array(image)\n", "    image = np.clip(image/255.0, 0.0, 1.0) #255 = max of the value of a pixel\n", "    i += 1\n", "    \n", "    allImage[i-1]=image\n", "\n", "train = allImage\n", "\n", "# Ending time.\n", "end_time = time.time()\n", "\n", "# Difference between start and end-times.\n", "time_dif = end_time - start_time\n", "print(time_dif)"]}, {"metadata": {"_uuid": "687bad1a8e9e369839709eaa91f3730f91e9f845", "_cell_guid": "290c3f13-f189-41fb-89c9-b1bbba791b7f"}, "cell_type": "markdown", "source": ["## **We come back to the code commonly used by the Kaggle Kernel or your jupyter notebook**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "71340a59225a820e58184353741d64f38ee5ceb7", "_cell_guid": "641484fa-3246-4cbf-8e68-9839e1973f08"}, "cell_type": "code", "source": ["#let's check one image from the train data base\n", "lum_img = train[100,:,:,:]\n", "plt.imshow(lum_img)\n", "plt.show()"]}, {"metadata": {"_uuid": "0c80f5a04064c87ada715e319b2c9951d57dc06a", "_cell_guid": "ec539f4f-fabc-4171-bf8e-f61d3ad9ac91"}, "cell_type": "markdown", "source": ["### **4. Zoom on label from the train dataset**\n", "\n", "## **The following code is design to be run on *your own JUPYTER NOTEBOOK made on your computer*. It will not work on a Kaggle Kernel.******"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "6a0761f12a2552099c5352736c7e83807e1b9808", "_cell_guid": "a44fa889-2027-403e-b7f5-9e13277cd377", "collapsed": true, "_kg_hide-output": true}, "cell_type": "code", "source": ["#######Upload the zip (input data base)########\n", "labels_raw = pd.read_csv(\"Data/labels.csv.zip\", compression='zip', header=0, sep=',', quotechar='\"')\n", "\n", "#Check 5 random values\n", "labels_raw.sample(5)"]}, {"metadata": {"_uuid": "ce801fecaaf7457f16ab43ac4d3d1649d4935066", "_cell_guid": "3eb3c4ba-8034-42f0-8471-817cf2304a90"}, "cell_type": "markdown", "source": ["## **The following code is design for the *Kaggle Kernel*. DO NOT COPY IT ON YOUR COMPUTER.**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "836fa0736e20e33e13ce8035122613c00fa414ed", "_cell_guid": "69e79790-3726-4b8d-9c2e-ae6249022637"}, "cell_type": "code", "source": ["labels_raw = pd.read_csv('../input/labels.csv')\n", "df_train.sample(5)"]}, {"metadata": {"_uuid": "3ec2b2eb594d8bb7e82c04a758b1f44c5f176a7d", "_cell_guid": "c42c66b5-b6fd-4d1e-b72b-675b58dcbe4e"}, "cell_type": "markdown", "source": ["## **We come back to the code commonly used by the Kaggle Kernel or your jupyter notebook**"]}, {"metadata": {"_uuid": "7ae1136b1b1a977811ed577e7cdd0e1327666fe8", "_cell_guid": "6c8fb582-5dad-4fe9-b81a-36c8c208e36f"}, "cell_type": "markdown", "source": ["### **5. Extract the N most represented breeds**\n", "\n", "We will reduce the data base so that we can reduce the complexity of our model.\n", "In addition, it will help for the calculation as there will be only N breeds to classify.\n", "We will be able to easily run the model in less than 10 minutes."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "0e168e3aaba2754f92f18864b165fbdc5fd469e5", "_cell_guid": "68738a2d-6913-46c6-b1d2-cb0f4e8cda52", "_kg_hide-output": false}, "cell_type": "code", "source": ["Nber_of_breeds = 8\n", "\n", "#######Get the N most represented breeds########\n", "def main_breeds(labels_raw, Nber_breeds , all_breeds='TRUE'):\n", "    labels_freq_pd = itemfreq(labels_raw[\"breed\"])\n", "    labels_freq_pd = labels_freq_pd[labels_freq_pd[:, 1].argsort()[::-1]] #[::-1] ==> to sort in descending order\n", "    \n", "    if all_breeds == 'FALSE':\n", "        main_labels = labels_freq_pd[:,0][0:Nber_breeds]\n", "    else: \n", "        main_labels = labels_freq_pd[:,0][:]\n", "        \n", "    labels_raw_np = labels_raw[\"breed\"].as_matrix() #transform in numpy\n", "    labels_raw_np = labels_raw_np.reshape(labels_raw_np.shape[0],1)\n", "\n", "    labels_filtered_index = np.where(labels_raw_np == main_labels)\n", "    \n", "    return labels_filtered_index\n", "\n", "labels_filtered_index = main_breeds(labels_raw = labels_raw, Nber_breeds = Nber_of_breeds, all_breeds='FALSE')\n", "labels_filtered = labels_raw.iloc[labels_filtered_index[0],:]\n", "train_filtered = train[labels_filtered_index[0],:,:,:]\n", "\n", "print('- Number of images remaining after selecting the {0} main breeds : {1}'.format(Nber_of_breeds, labels_filtered_index[0].shape))\n", "print('- The shape of train_filtered dataset is : {0}'.format(train_filtered.shape))"]}, {"metadata": {"_uuid": "7959b3e9dddf2bcd1878de55c53108e3fe1be8e3", "_cell_guid": "7ff5fa12-6156-49c2-8dd1-bc30b1cf3e86"}, "cell_type": "markdown", "source": ["Let's have a look on 1 image :"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "df596ed016b22bf8b273887181715a0c0e5b2ac7", "_cell_guid": "94073df1-7233-422c-af7f-6c2e2648cdd1", "_kg_hide-input": false}, "cell_type": "code", "source": ["#print(labels_filtered[90])\n", "lum_img = train_filtered[1,:,:,:]\n", "plt.imshow(lum_img)\n", "plt.show()"]}, {"metadata": {"_uuid": "05fab67c05d86d4be4431884e9da571c81e691e1", "_cell_guid": "e69664dd-4262-4341-af95-f36ad0feec5d"}, "cell_type": "markdown", "source": ["### **6. One-hot labels**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "ef2f7d54bfe8d16efddb2ff26f6935110fff260c", "_cell_guid": "38160bdc-2692-41bd-824f-af64fee0931f", "_kg_hide-output": false}, "cell_type": "code", "source": ["#We select the labels from the N main breeds\n", "labels = labels_filtered[\"breed\"].as_matrix()\n", "labels = labels.reshape(labels.shape[0],1) #labels.shape[0] looks faster than using len(labels)\n", "labels.shape"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "90707f8ab2dd5689b171106037fa462956065d5e", "_cell_guid": "e6a7cf04-3d59-40aa-9aac-52b2a509df33", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["#Function to breate one-hot labels\n", "def matrix_Bin(labels):\n", "    labels_bin=np.array([])\n", "\n", "    labels_name, labels0 = np.unique(labels, return_inverse=True)\n", "    labels0\n", "    \n", "    for _, i in enumerate(itemfreq(labels0)[:,0].astype(int)):\n", "        labels_bin0 = np.where(labels0 == itemfreq(labels0)[:,0][i], 1., 0.)\n", "        labels_bin0 = labels_bin0.reshape(1,labels_bin0.shape[0])\n", "\n", "        if (labels_bin.shape[0] == 0):\n", "            labels_bin = labels_bin0\n", "        else:\n", "            labels_bin = np.concatenate((labels_bin,labels_bin0 ),axis=0)\n", "\n", "    print(\"Nber SubVariables {0}\".format(itemfreq(labels0)[:,0].shape[0]))\n", "    labels_bin = labels_bin.transpose()\n", "    print(\"Shape : {0}\".format(labels_bin.shape))\n", "    \n", "    return labels_name, labels_bin"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "7b788139c4a16762b7c58ddc978f4d673a0d0979", "_cell_guid": "8fb9fe53-55c5-4446-bdaa-f0a8f233f1e3", "_kg_hide-input": false}, "cell_type": "code", "source": ["labels_name, labels_bin = matrix_Bin(labels = labels)\n", "labels_bin[0:9]"]}, {"metadata": {"_uuid": "4cf65094569de30490b0ee501eb182b5c86fe099", "_cell_guid": "32843d9a-d657-46d6-8735-d75b9121d8f5"}, "cell_type": "markdown", "source": ["### **7. Quick checks on Labels**\n", "\n", "Let's see exactly the N labels we keep.\n", "As you will see below from the one-hot labels arry you can find which breed it corresponds."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "a63658026d9da0ddb2ce7ebf61e28efb1f8821b9", "_kg_hide-output": false, "_cell_guid": "dd61b271-8d77-42b6-ae12-74389653716a", "_kg_hide-input": false}, "cell_type": "code", "source": ["for breed in range(len(labels_name)):\n", "    print('Breed {0} : {1}'.format(breed,labels_name[breed]))"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "e8559bbdfb3d30f53165541bd9998f3dd0a688d1", "_cell_guid": "c7759737-1385-44d5-a069-36761aa0903d"}, "cell_type": "code", "source": ["labels[0:9]"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "2c20e4c4cc694005385ad2aa9e8a34524bb16590", "_cell_guid": "2231025d-d9a4-4bc9-a5a5-18aa44986743"}, "cell_type": "code", "source": ["#You can proceed backward with np.argmax to find the breed of an image\n", "labels_cls = np.argmax(labels_bin, axis=1)\n", "labels_name[labels_cls[2]]"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "f01cea473d775b367d372b5511cd18a5d7f59b6b", "_cell_guid": "823a9065-2f16-4496-ba54-86609e3213e0"}, "cell_type": "code", "source": ["i=11\n", "print(labels_name[labels_cls[i]])\n", "lum_img = train_filtered[i,:,:,:]\n", "plt.imshow(lum_img)\n", "plt.show()"]}, {"metadata": {"_uuid": "79095c19da46c458b477e0cd05f03673e8d3ca1c", "_cell_guid": "bcbac0e3-f72e-4fb9-93d3-cabfb68a3f99"}, "cell_type": "markdown", "source": ["## **Convolutional Neural Network**\n", "\n", "### **1. Creation of a Train and Validation DataBase**\n", "\n", "We split our train data base in two: a train data base and a validation database.\n", "Therefore, we can check the accuracy of the model train made from the 'train database', on the validation database.\n", "\n"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "ab306042f02a182586304a716946c4c4ac968e69", "_cell_guid": "00b33496-d4e3-4f05-ba81-847ab735e40c", "_kg_hide-output": false}, "cell_type": "code", "source": ["num_validation = 0.30\n", "X_train, X_validation, y_train, y_validation = train_test_split(train_filtered, labels_bin, test_size=num_validation, random_state=6)\n", "X_train.shape"]}, {"metadata": {"_uuid": "835ebf82c4723b77590e2209c9ccf9038f21d271", "_cell_guid": "0735d515-3eaa-4328-a7c6-ff6d93934fe3"}, "cell_type": "markdown", "source": ["*Here you will find a code which also split a database in two.*\n", "\n", "#Creation of the Train DataBase and Test DataBase\n", "#x% of the observations will belong to the Train DataBase\n", "\n", "def train_test_creation(x, data, toPred):\n", "    indices = sample(range(data.shape[0]),int(x * data.shape[0]))\n", "    indices = np.sort(indices, axis=None) \n", "    index = np.arange(data.shape[0])\n", "    reverse_index = np.delete(index, indices,0)\n", "    \n", "    train_toUse = data[indices]\n", "    train_toPred = toPred[indices]\n", "    test_toUse = data[reverse_index]\n", "    test_toPred = toPred[reverse_index]\n", "        \n", "    return train_toUse, train_toPred, test_toUse, test_toPred\n", "\n", "df_train_toUse, df_train_toPred, df_test_toUse, df_test_toPred = train_test_creation(0.7, train_filtered, labels_bin)\n", "df_train_toUse.shape"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "272342e87496f674a043c9b41de8fc23673053c6", "_cell_guid": "55d9d8bb-f114-4a6d-b244-1a1dd26a47ef"}, "cell_type": "code", "source": ["#from the one-hot database we can find the breed.\n", "df_validation_toPred_cls = np.argmax(y_validation, axis=1)\n", "df_validation_toPred_cls[0:9]"]}, {"metadata": {"_uuid": "ee8276a5361fca379636899c001a659944c04534", "_cell_guid": "acf21610-22e0-4076-908d-06f303d97fc2"}, "cell_type": "markdown", "source": ["Quick check of the array created :"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "37223b48ed8d1bd724fd68256c38794e6b15010f", "_cell_guid": "df4d8af5-e27c-493f-a589-b3106294d461"}, "cell_type": "code", "source": ["i=2\n", "print(labels_name[df_validation_toPred_cls[i]])\n", "print(df_validation_toPred_cls[i])\n", "lum_img = X_validation[i,:,:,:]\n", "plt.imshow(lum_img)\n", "plt.show()"]}, {"metadata": {"_uuid": "177cfea98fb86bf81e8650f1ca2eb0c09269004c", "_cell_guid": "83f54321-e1b1-45fc-a2be-f7bf42d5c9b1"}, "cell_type": "markdown", "source": ["### **2. CNN with Tensorflow - definition of the layers**\n", "\n", "The CNN archtecture will be as followed :\n", "\n", "- Convolutional Layer n\u00b01 with 32 filters\n", " + Max pooling\n", " + Relu\n", "- Convolutional Layer n\u00b02 with 64 filters\n", " + Max pooling\n", " + Relu\n", "- Convolutional Layer n\u00b03 with 128 filters\n", " + Max pooling\n", " + Relu\n", " + DropOut\n", "- Flatten Layer\n", "- Fully Connected Layer with 500 nodes\n", " + Relu\n", " + DropOut\n", "- Fully Connected Layer with n nodes (n = number of breeds)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "58ed78e229e034b8b6caff7acf063f934d2b70f3", "_cell_guid": "c1b98d08-400b-4ff6-819b-325a28c1234f", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["# Our images are 100 pixels in each dimension.\n", "img_size = image_resize\n", "\n", "# Number of colour channels for the images: 3\n", "num_channels = 3\n", "\n", "# Images are stored in one-dimensional arrays of this length.\n", "img_size_flat = img_size * img_size\n", "\n", "# Image Shape\n", "img_shape = (img_size, img_size, num_channels)\n", "\n", "# Number of classes : 5 breeds\n", "num_classes = Nber_of_breeds"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "5acb6c694a742bb528d3c172d16253cddcffa89e", "_cell_guid": "1c50b439-0515-4106-a4dc-4cbbaef0c06e", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def new_weights(shape):\n", "    return tf.Variable(tf.truncated_normal(shape, stddev=0.05))\n", "#outputs random value from a truncated normal distribution\n", "\n", "def new_biases(length):\n", "    return tf.Variable(tf.constant(0.05, shape=[length]))\n", "#outputs the constant value 0.05"]}, {"metadata": {"_uuid": "08f7952e6c73bd31ae769c6ecab590ab3c14c105", "_cell_guid": "6aa6a748-1e17-4781-bd6c-e25110c9270e"}, "cell_type": "markdown", "source": ["**I mainly reuse the code of Hvass and his comments. **If you need more information, just visit his github (I put the link on the top of this kernel). His works and sharing are really great, I strongly advise you to have a look.\n", "The main difference is that I added dropout."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "afcf8b16bbb30711e3c53908e405776252bd5065", "_cell_guid": "d04cd84e-8732-40f5-91d5-5c66b10b2721", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def new_conv_layer(input,              # The previous layer.\n", "                   num_input_channels, # Num. channels in prev. layer.\n", "                   filter_size,        # Width and height of each filter.\n", "                   num_filters,        # Number of filters.\n", "                   use_pooling=True,\n", "                   use_dropout=True):  # Use 2x2 max-pooling.\n", "\n", "    # Shape of the filter-weights for the convolution.\n", "    # This format is determined by the TensorFlow API.\n", "    shape = [filter_size, filter_size, num_input_channels, num_filters]\n", "\n", "    # Create new weights aka. filters with the given shape.\n", "    weights = new_weights(shape=shape)\n", "\n", "    # Create new biases, one for each filter.\n", "    biases = new_biases(length=num_filters)\n", "\n", "    # Create the TensorFlow operation for convolution.\n", "    # Note the strides are set to 1 in all dimensions.\n", "    # The first and last stride must always be 1,\n", "    # because the first is for the image-number and\n", "    # the last is for the input-channel.\n", "    # But e.g. strides=[1, 2, 2, 1] would mean that the filter\n", "    # is moved 2 pixels across the x- and y-axis of the image.\n", "    # The padding is set to 'SAME' which means the input image\n", "    # is padded with zeroes so the size of the output is the same.\n", "    layer = tf.nn.conv2d(input=input,\n", "                         filter=weights,\n", "                         strides=[1, 1, 1, 1],\n", "                         padding='SAME')\n", "\n", "    # Add the biases to the results of the convolution.\n", "    # A bias-value is added to each filter-channel.\n", "    layer += biases\n", "\n", "    # Use pooling to down-sample the image resolution?\n", "    if use_pooling:\n", "        # This is 2x2 max-pooling, which means that we\n", "        # consider 2x2 windows and select the largest value\n", "        # in each window. Then we move 2 pixels to the next window.\n", "        layer = tf.nn.max_pool(value=layer,\n", "                               ksize=[1, 2, 2, 1],\n", "                               strides=[1, 2, 2, 1],\n", "                               padding='SAME')\n", "\n", "    # Rectified Linear Unit (ReLU).\n", "    # It calculates max(x, 0) for each input pixel x.\n", "    # This adds some non-linearity to the formula and allows us\n", "    # to learn more complicated functions.\n", "    layer = tf.nn.relu(layer)\n", "    \n", "    if use_dropout:\n", "        layer = tf.nn.dropout(layer,keep_prob_conv)\n", "\n", "    # Note that ReLU is normally executed before the pooling,\n", "    # but since relu(max_pool(x)) == max_pool(relu(x)) we can\n", "    # save 75% of the relu-operations by max-pooling first.\n", "\n", "    # We return both the resulting layer and the filter-weights\n", "    # because we will plot the weights later.\n", "    return layer, weights"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "1fb3c16ba840a1b7808fe2c08a1cdca065ff6c92", "_cell_guid": "59576d0a-688e-49bd-a0dd-fc5935c1bb62", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def flatten_layer(layer):\n", "    # Get the shape of the input layer.\n", "    layer_shape = layer.get_shape()\n", "\n", "    # The shape of the input layer is assumed to be:\n", "    # layer_shape == [num_images, img_height, img_width, num_channels]\n", "\n", "    # The number of features is: img_height * img_width * num_channels\n", "    # We can use a function from TensorFlow to calculate this.\n", "    num_features = layer_shape[1:4].num_elements()\n", "    \n", "    # Reshape the layer to [num_images, num_features].\n", "    # Note that we just set the size of the second dimension\n", "    # to num_features and the size of the first dimension to -1\n", "    # which means the size in that dimension is calculated\n", "    # so the total size of the tensor is unchanged from the reshaping.\n", "    layer_flat = tf.reshape(layer, [-1, num_features])\n", "\n", "    # The shape of the flattened layer is now:\n", "    # [num_images, img_height * img_width * num_channels]\n", "\n", "    # Return both the flattened layer and the number of features.\n", "    return layer_flat, num_features"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "d349ca4bf757c32836906725c2b992c7b12571e0", "_cell_guid": "c7284c42-cf6f-49a9-9180-c04f516c15e5", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def new_fc_layer(input,          # The previous layer.\n", "                 num_inputs,     # Num. inputs from prev. layer.\n", "                 num_outputs,    # Num. outputs.\n", "                 use_relu=True,\n", "                 use_dropout=True): # Use Rectified Linear Unit (ReLU)?\n", "\n", "    # Create new weights and biases.\n", "    weights = new_weights(shape=[num_inputs, num_outputs])\n", "    biases = new_biases(length=num_outputs)\n", "\n", "    # Calculate the layer as the matrix multiplication of\n", "    # the input and weights, and then add the bias-values.\n", "    layer = tf.matmul(input, weights) + biases\n", "\n", "    # Use ReLU?\n", "    if use_relu:\n", "        layer = tf.nn.relu(layer)\n", "    \n", "    if use_dropout:\n", "        layer = tf.nn.dropout(layer,keep_prob_fc)\n", "        \n", "    return layer"]}, {"metadata": {"_uuid": "2a6e01c86bc56b0a590dd03887ac9e481269bcf3", "_cell_guid": "0fbeba85-4789-4346-b64e-217bfd1cd983"}, "cell_type": "markdown", "source": ["### **3. CNN with Tensorflow - set up of placeholder tensor**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "d1bc431d4a8d8caeb227d0fac9835bcab82e98ea", "_cell_guid": "f53c5511-811a-42fe-8575-e7e1bf54f92d", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["x = tf.placeholder(tf.float32, shape=[None, img_size, img_size, num_channels], name='x')\n", "x_image = tf.reshape(x, [-1, img_size, img_size, num_channels]) #-1 put everything as 1 array\n", "y_true = tf.placeholder(tf.float32, shape=[None, num_classes], name='y_true')\n", "y_true_cls = tf.argmax(y_true, axis=1)\n", "keep_prob_fc=tf.placeholder(tf.float32)\n", "keep_prob_conv=tf.placeholder(tf.float32)"]}, {"metadata": {"_uuid": "ad213574022f708d7734d5ae04638d5627a9c922", "_cell_guid": "ba175ccf-1d57-4cb7-95dc-82ba2a0a9f39"}, "cell_type": "markdown", "source": ["### **4. CNN with Tensorflow - Design the layer**\n", "\n", "In this part, you can play with the filter sizes and the number of filters. The best model is ont with the proper number of layers but also a good choice of filter sizes and number of filters."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "b6fcc1b024218baa2387a00d3527e7499b328352", "_cell_guid": "b4d8b346-ddb0-4b85-8d3b-0481c694bf21", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["# Convolutional Layer 1.\n", "filter_size1 = 5          # Convolution filters are 5 x 5 pixels.\n", "num_filters1 = 32         # There are 32 of these filters.\n", "\n", "# Convolutional Layer 2.\n", "filter_size2 = 4          # Convolution filters are 4 x 4 pixels.\n", "num_filters2 = 64      # There are 64 of these filters.\n", "\n", "# Convolutional Layer 3.\n", "filter_size3 = 3          # Convolution filters are 3 x 3 pixels.\n", "num_filters3 = 128      # There are 128 of these filters.\n", "\n", "# Fully-connected layer.\n", "fc_size = 500 "]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "6d3d3b5ccfb895ebed1fb2d055b95dcb0d428761", "_cell_guid": "463a46c3-762a-47ba-89e6-c9edebd17c3f", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["layer_conv1, weights_conv1 = \\\n", "    new_conv_layer(input=x_image,\n", "                   num_input_channels=num_channels,\n", "                   filter_size=filter_size1,\n", "                   num_filters=num_filters1,\n", "                   use_pooling=True,\n", "                   use_dropout=False)\n", "    \n", "layer_conv2, weights_conv2 = \\\n", "    new_conv_layer(input=layer_conv1,\n", "                   num_input_channels=num_filters1,\n", "                   filter_size=filter_size2,\n", "                   num_filters=num_filters2,\n", "                   use_pooling=True,\n", "                   use_dropout=False)\n", "    \n", "layer_conv3, weights_conv3 = \\\n", "    new_conv_layer(input=layer_conv2,\n", "                   num_input_channels=num_filters2,\n", "                   filter_size=filter_size3,\n", "                   num_filters=num_filters3,\n", "                   use_pooling=True,\n", "                   use_dropout=True)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "98f4a0af755b4b539d089659a16fc2b602c9e18f", "_cell_guid": "a04626ee-5317-4a11-b539-7d6fcd7c30db", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["layer_flat, num_features = flatten_layer(layer_conv3)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "c719d9893131f3c8c0fb4dc00d33ac1e48a4f474", "_cell_guid": "ded3de34-8c28-4a6f-8bdb-04ec9068b6bb", "_kg_hide-output": false}, "cell_type": "code", "source": ["#Train\n", "layer_fc1 = new_fc_layer(input=layer_flat,\n", "                         num_inputs=num_features,\n", "                         num_outputs=fc_size,\n", "                         use_relu=True,\n", "                         use_dropout=True)\n", "\n", "layer_fc1\n", "\n", "layer_fc2 = new_fc_layer(input=layer_fc1,\n", "                         num_inputs=fc_size,\n", "                         num_outputs=num_classes,\n", "                         use_relu=False,\n", "                         use_dropout=False)\n", "\n", "layer_fc2"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "f5edf09d4fa4f7c377efcba9e76c4df4c32cc40e", "_cell_guid": "e75d521b-aa03-4423-9bc6-47a5c48d0aa1", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["#Prediction :\n", "y_pred = tf.nn.softmax(layer_fc2)\n", "y_pred_cls = tf.argmax(y_pred, axis=1)"]}, {"metadata": {"_uuid": "f196fdc1bfdac35956770e7b0ef8017d1f7d30a6", "_cell_guid": "c3081721-8120-49b2-a860-4d07002d644b"}, "cell_type": "markdown", "source": ["### **5. CNN with Tensorflow - Definition of the cost function (cross-entropy)**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "5a56e0fa1b9c4f0cdf7d5e7803a141798699de03", "_cell_guid": "0e787c29-4ae7-4ff6-b349-40a3f6deaeed", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=layer_fc2,\n", "                                                        labels=y_true)\n", "cost = tf.reduce_mean(cross_entropy)\n", "\n", "optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost)\n", "correct_prediction = tf.equal(y_pred_cls, y_true_cls)\n", "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))"]}, {"metadata": {"_uuid": "ad8d0dac362e664ee31878d707e06bfd7169297d", "_cell_guid": "4cf843b1-a5f0-4c2a-81c9-b05d560aa0dd"}, "cell_type": "markdown", "source": ["### **6. CNN with Tensorflow - Training of the CNN**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "b4050f82e375b4e94c57cb3517542e58f99284a9", "_cell_guid": "92f7f20e-ca59-4038-8eb0-4027a38137ec", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["session = tf.Session()\n", "\n", "def init_variables():\n", "    session.run(tf.global_variables_initializer())"]}, {"metadata": {"_uuid": "6205acf369cb224dbbf7ebf038f44b0ebdee1d5a", "_cell_guid": "546da5af-29d4-4588-b2e6-d710b130c25b"}, "cell_type": "markdown", "source": ["The function below create a batch from a dataset. We use batch to train our model."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "05c043901f10fb3b3a91adf8fff1e17e0cac2382", "_cell_guid": "5edd9f33-05bc-4137-a959-ac8c7d6bd32e", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["batch_size = 50\n", "\n", "#function next_batch\n", "def next_batch(num, data, labels):\n", "    '''\n", "    Return a total of `num` random samples and labels. \n", "    '''\n", "    idx = np.arange(0 , len(data))\n", "    np.random.shuffle(idx)\n", "    idx = idx[:num]\n", "    data_shuffle = [data[i] for i in idx]\n", "    labels_shuffle = [labels[i] for i in idx]\n", "\n", "    return np.asarray(data_shuffle), np.asarray(labels_shuffle)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "88fc8edb5ac8c041c7808f2bb762f0100836c6db", "_cell_guid": "6011d0f6-2338-4950-bed9-b12a94ef2450", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def optimize(num_iterations, X):\n", "    global total_iterations\n", "    \n", "    start_time = time.time()\n", "    \n", "    #array to plot\n", "    losses = {'train':[], 'validation':[]}\n", "    \n", "    for i in range(num_iterations):\n", "            total_iterations += 1\n", "            # Get a batch of training examples.\n", "            # x_batch now holds a batch of images and\n", "            # y_true_batch are the true labels for those images.\n", "            x_batch, y_true_batch = next_batch(batch_size, X_train, y_train)\n", "\n", "            # Put the batch into a dict with the proper names\n", "            # for placeholder variables in the TensorFlow graph.\n", "            feed_dict_train = {x: x_batch,\n", "                               y_true: y_true_batch,\n", "                               keep_prob_conv : 0.3,\n", "                               keep_prob_fc : 0.4}\n", "            feed_dict_validation = {x: X_validation,\n", "                               y_true: y_validation,\n", "                               keep_prob_conv : 1,\n", "                               keep_prob_fc : 1}\n", "            \n", "            # Run the optimizer using this batch of training data.\n", "            # TensorFlow assigns the variables in feed_dict_train\n", "            # to the placeholder variables and then runs the optimizer.\n", "            session.run(optimizer, feed_dict=feed_dict_train)\n", "            \n", "            acc_train = session.run(accuracy, feed_dict=feed_dict_train)\n", "            acc_validation = session.run(accuracy, feed_dict=feed_dict_validation)\n", "            losses['train'].append(acc_train)\n", "            losses['validation'].append(acc_validation)\n", "            \n", "            # Print status every X iterations.\n", "            if (total_iterations % X == 0) or (i ==(num_iterations -1)):\n", "            # Calculate the accuracy on the training-set.\n", "                                \n", "                msg = \"Iteration: {0:>6}, Training Accuracy: {1:>6.1%}, Validation Accuracy: {2:>6.1%}\"\n", "                print(msg.format(total_iterations, acc_train, acc_validation))\n", "                \n", "    \n", "    # Ending time.\n", "    end_time = time.time()\n", "\n", "    # Difference between start and end-times.\n", "    time_dif = end_time - start_time\n", "\n", "    # Print the time-usage.\n", "    print(\"Time usage: \" + str(timedelta(seconds=int(round(time_dif)))))\n", "    \n", "    plt.plot(losses['train'], label='Training loss')\n", "    plt.plot(losses['validation'], label='Validation loss')\n", "    plt.legend()\n", "    _ = plt.ylim()"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "5b391adb029d8cdd41a7ab1bdf3b6dd84e08262d", "_cell_guid": "b978b125-6e9f-46e5-add6-9794aae412cb", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["init_variables()\n", "total_iterations = 0"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "eb0fc725bbe26b7cfb18bb8e451fb2031de5ed7b", "_kg_hide-output": false, "_cell_guid": "ccad519d-a668-46af-9842-6466e2c92971", "_kg_hide-input": false}, "cell_type": "code", "source": ["optimize(num_iterations=3500, X=250)"]}, {"metadata": {"_uuid": "f0f01443a37e04a403274acb0b5ebc10f8e45470", "_cell_guid": "d2e36ced-714a-4333-83d3-fdf858eb9cb8"}, "cell_type": "markdown", "source": ["As you can see, the model tends to overfit and is not very good. "]}, {"metadata": {"_uuid": "8168bf78cac5b5fa0cd9bf6c7536212fd9e2549c", "_cell_guid": "aaae3e6b-77c5-4b9d-9337-caaa5e628da1"}, "cell_type": "markdown", "source": ["### **7. CNN with Tensorflow - Results**\n", "\n", "The results are not so good as the accuracy is only 44%. Using a pre-trained model with Keras will give you a better result but with this model, you will know how to build from scratch your own CNN with tensorflow.\n", "\n", "By having more photos of dogs, we can increase the accuracy. in addition, we can create new images in our training dataset by rotating the images. it's what we call image augmentation. It will help the model to detect a patern which can have different 'position' in the space.\n", "\n", "Go a 'bit' deeper on the result :\n", "\n", "I just share some function to show some images from the new test database with the corresponding breeds and the predicted breeds.\n", "I also add the confusion matrix to see the results."]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "ab676f8daddd01319c77f80e4ade322d1743039d", "_cell_guid": "13d65257-29ba-4f45-9735-9e4b50225be9", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def plot_images(images, cls_true, cls_pred=None):\n", "    assert len(images) == len(cls_true) == 12\n", "    \n", "    # Create figure with 3x3 sub-plots.\n", "    fig, axes = plt.subplots(4, 3)\n", "    fig.subplots_adjust(hspace=0.3, wspace=0.3)\n", "\n", "    for i, ax in enumerate(axes.flat):\n", "        # Plot image.\n", "        ax.imshow(images[i].reshape(img_shape), cmap='binary')\n", "\n", "        # Show true and predicted classes.\n", "        if cls_pred is None:\n", "            xlabel = \"True: {0}\".format(cls_true[i])\n", "        else:\n", "            xlabel = \"True: {0}, Pred: {1}\".format(cls_true[i], cls_pred[i])\n", "\n", "        # Show the classes as the label on the x-axis.\n", "        ax.set_xlabel(xlabel)\n", "        \n", "        # Remove ticks from the plot.\n", "        ax.set_xticks([])\n", "        ax.set_yticks([])\n", "    \n", "    # Ensure the plot is shown correctly with multiple plots\n", "    # in a single Notebook cell.\n", "    plt.show()"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "e0cd9537fe9f9a699d3ff70eb6e9105bce443a18", "_cell_guid": "5bef1909-1d8b-4666-8ff6-3278de87f06f", "collapsed": true, "_kg_hide-output": false}, "cell_type": "code", "source": ["def plot_confusion_matrix(data_pred_cls,data_predicted_cls):\n", "    # This is called from print_test_accuracy() below.\n", "\n", "    # cls_pred is an array of the predicted class-number for\n", "    # all images in the test-set.\n", "  \n", "    # Get the confusion matrix using sklearn.\n", "    cm = confusion_matrix(y_true=data_pred_cls,\n", "                          y_pred=data_predicted_cls)\n", "\n", "    # Print the confusion matrix as text.\n", "    print(cm)\n", "\n", "    # Plot the confusion matrix as an image.\n", "    plt.matshow(cm)\n", "\n", "    # Make various adjustments to the plot.\n", "    plt.colorbar()\n", "    tick_marks = np.arange(num_classes)\n", "    plt.xticks(tick_marks, range(num_classes))\n", "    plt.yticks(tick_marks, range(num_classes))\n", "    plt.xlabel('Predicted')\n", "    plt.ylabel('True')\n", "\n", "    # Ensure the plot is shown correctly with multiple plots\n", "    # in a single Notebook cell.\n", "    plt.show()"]}, {"metadata": {"_uuid": "06d0f114fd77d290b2a3aa2acbf36124d9e3355b", "_cell_guid": "5923249e-1e99-4985-866a-07e60eb1a445"}, "cell_type": "markdown", "source": ["Launch the following codes, you will have 'nice' results!"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "b51dbbcb4719fa861ab735faaca3eb1044cccdda", "_cell_guid": "134627ea-ee00-40ce-95b7-18274a98513e", "_kg_hide-output": false}, "cell_type": "code", "source": ["feed_dict_validation = {x: X_validation,\n", "                    y_true: y_validation,\n", "                    keep_prob_conv : 1,\n", "                    keep_prob_fc : 1}\n", "df_validation_Predicted_cls = session.run(y_pred_cls, feed_dict=feed_dict_validation)\n", "\n", "plot_images(images=X_validation[50:62],\n", "            cls_true=df_validation_toPred_cls[50:62],\n", "            cls_pred=df_validation_Predicted_cls [50:62])"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "de5e42c3c25d24ee0ece02dc74d3abbab4345607", "_cell_guid": "0928952a-fee9-4edb-aafd-fb9b4e7c7df7", "_kg_hide-output": false}, "cell_type": "code", "source": ["i = 63\n", "print((\"True : {0} / {1}\").format(df_validation_toPred_cls[i], labels_name[df_validation_toPred_cls[i]]))\n", "print((\"Pred : {0} / {1}\").format(df_validation_Predicted_cls[i], labels_name[df_validation_Predicted_cls[i]]))\n", "\n", "lum = X_validation[i,:,:,:]\n", "plt.imshow(lum)\n", "plt.show()"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "03722ebe5adc8a9204124c802226926903b34e24", "_cell_guid": "e87698f7-84d3-4524-a11d-22a0888d2d09"}, "cell_type": "code", "source": ["plot_confusion_matrix(df_validation_toPred_cls,df_validation_Predicted_cls)"]}, {"metadata": {"_uuid": "cefd5eb535159638f0b403f3df693652905bd0d3", "_cell_guid": "8439397d-afe9-4c7f-b68e-adcac53ebe0c"}, "cell_type": "markdown", "source": ["As you can see, the model has difficulties to differenciate Breed 1 : bernese_mountain_dog and Breed 2 : entlebucher.\n", "This 2 breeds are look alike a lot (same color and shape). So, it's look normal that our model have make some mistakes between this two breeds."]}, {"metadata": {"_uuid": "a134770ad8ab1f5befc9b1ec08567acc6970f752", "_cell_guid": "81782c05-0a9b-40c9-9a9c-1c06655220e3"}, "cell_type": "markdown", "source": ["### **What the weights look like**\n", "\n", "*Here we use a Hvass code to plot the weights and the layers. It's great his code and again go to visit his github (see the link on the top of this kernel)!"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "7c0eeed6d9dd1a122d999cc58c8026e8c4ba3f29", "_cell_guid": "85739d2b-6e1f-4063-b477-09fe174473f2", "collapsed": true}, "cell_type": "code", "source": ["\"Print the weights\"\n", "def plot_conv_layer(layer, image):\n", "    feed_dict = {x: [image],\n", "                keep_prob_conv : 1,\n", "                keep_prob_fc : 1}\n", "\n", "    values = session.run(layer, feed_dict=feed_dict)\n", "\n", "    num_filters = values.shape[3]\n", "\n", "    # Number of grids to plot.\n", "    # Rounded-up, square-root of the number of filters.\n", "    num_grids = math.ceil(math.sqrt(num_filters))\n", "    \n", "    # Create figure with a grid of sub-plots.\n", "    fig, axes = plt.subplots(num_grids, num_grids)\n", "\n", "    # Plot the output images of all the filters.\n", "    for i, ax in enumerate(axes.flat):\n", "        # Only plot the images for valid filters.\n", "        if i<num_filters:\n", "            img = values[0, :, :, i]\n", "\n", "            # Plot image.\n", "            ax.imshow(img, interpolation='nearest', cmap='binary')\n", "        \n", "        # Remove ticks from the plot.\n", "        ax.set_xticks([])\n", "        ax.set_yticks([])\n", "    \n", "    plt.show()"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "dca43e0cc82653b048d0a94cf5d4d08b6f31c209", "_cell_guid": "352ba2ec-5b13-459f-8ec0-32128f90072f", "collapsed": true}, "cell_type": "code", "source": ["def plot_conv_weights(weights, input_channel):\n", "\n", "    w = session.run(weights)\n", "\n", "    w_min = np.min(w)\n", "    w_max = np.max(w)\n", "\n", "    # Number of filters used in the conv. layer.\n", "    num_filters = w.shape[3]\n", "\n", "    # Number of grids to plot.\n", "    # Rounded-up, square-root of the number of filters.\n", "    num_grids = math.ceil(math.sqrt(num_filters))\n", "    \n", "    # Create figure with a grid of sub-plots.\n", "    fig, axes = plt.subplots(num_grids, num_grids)\n", "\n", "    # Plot all the filter-weights.\n", "    for i, ax in enumerate(axes.flat):\n", "        # Only plot the valid filter-weights.\n", "        if i<num_filters:\n", "            img = w[:, :, input_channel, i]\n", "\n", "            # Plot image.\n", "            ax.imshow(img, vmin=w_min, vmax=w_max,\n", "                      interpolation='nearest', cmap='seismic')\n", "        \n", "        # Remove ticks from the plot.\n", "        ax.set_xticks([])\n", "        ax.set_yticks([])\n", "    \n", "    plt.show()"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "c87e95341f3d4925290195cba876ee98f8262a8e", "_cell_guid": "1f40defc-1fb7-4c56-8a68-2650613d0e7c"}, "cell_type": "code", "source": ["image1 = train[0,:,:,:]\n", "plt.imshow(image1)\n", "plt.show()"]}, {"metadata": {"_uuid": "114cbf90fae172475966718f6cac6086f3b5a37b", "_cell_guid": "620ca3d6-e391-4ed7-af4b-db3c336dfee5"}, "cell_type": "markdown", "source": ["## **Layer 1**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "59ef96202997355cfc5e8d361672dc6c413f7447", "_cell_guid": "d6334174-e5d5-4faa-b593-c094e8123d34"}, "cell_type": "code", "source": ["plot_conv_weights(weights=weights_conv1, input_channel = 0)"]}, {"execution_count": null, "outputs": [], "metadata": {"scrolled": true, "_uuid": "4c7de618346d5cae3dac0e1db60db864ae98fa9a", "_cell_guid": "dd93188d-8fc8-4236-a586-cd2da38d0f9b"}, "cell_type": "code", "source": ["plot_conv_weights(weights=weights_conv1, input_channel = 1)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "71b732bcc3be17f09c130f55c747509b5d63dbe1", "_cell_guid": "55f22cb1-d60f-4d96-a22f-bcf84e54f934"}, "cell_type": "code", "source": ["plot_conv_weights(weights=weights_conv1, input_channel = 2)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "54dab7345cfa285504459c377a82cd55e9a893f2", "_cell_guid": "107895cb-7fb2-4bcf-87da-111db42d4076"}, "cell_type": "code", "source": ["plot_conv_layer(layer=layer_conv1, image=image1)"]}, {"metadata": {"_uuid": "1f160271b1663d76fcd5731b6a1d6e6ff1ac6edf", "_cell_guid": "388c7e6e-e6bf-4a76-b85a-b6a3e9dad5b5"}, "cell_type": "markdown", "source": ["## **Layer 2**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "a2a134cc5de2dbabb1d3fc3a742cf93f74d6d6d5", "_cell_guid": "9a49242e-7b77-4b6b-9956-2e19026437a3"}, "cell_type": "code", "source": ["plot_conv_weights(weights=weights_conv2, input_channel = 0)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "7be0df24d7f80862e9c68588c1973f7d40933947", "_cell_guid": "6aa4d681-3f4a-43c9-b1bf-d132b9ba4390"}, "cell_type": "code", "source": ["plot_conv_layer(layer=layer_conv2, image=image1)"]}, {"metadata": {"_uuid": "c6a89b84d425ab06610da597475a6e43a2e936c7", "_cell_guid": "8431184e-65f4-4c1f-a16d-96bef0f044b6"}, "cell_type": "markdown", "source": ["## **Layer 3**"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "22ec913c06528f4e206402857caeb8516e779ee3", "_cell_guid": "f1d41db5-9ab4-4d73-b899-cbb5243f2ea7"}, "cell_type": "code", "source": ["plot_conv_weights(weights=weights_conv3, input_channel = 1)"]}, {"execution_count": null, "outputs": [], "metadata": {"_uuid": "41ca20ab6f260b48a85e4a5d3fd73a03aa2b5bae", "_cell_guid": "30d24a59-cade-4b0c-adeb-88c4a9af6769"}, "cell_type": "code", "source": ["plot_conv_layer(layer=layer_conv3, image=image1)"]}]}