{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<br>\n<br>\n<h2 style = \"font-family: garamond; font-size: 50px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:10px;text-align:center; font-weight: bold\" >Hey Siri!! is it a Cat or Dog?</h2> \n<br> \n<br>\n<div class = 'image'> <img style=\"float:center; border:10px solid #fed049; width:90%\" align=center src = https://metro.co.uk/wp-content/uploads/2015/11/mg_dogorcat_comp.png> \n</div>\n<br>\n<br>\n<a href =\"https://metro.co.uk/wp-content/uploads/2015/11/mg_dogorcat_comp.png\" style = \"font-size:20px,color: dimgrey, text-align:left,font-family:serif\">Image Source: can we guess if youre a cat  or dog person</a>\n<br>\n","metadata":{}},{"cell_type":"markdown","source":"<p style = \"font-size: 20px; font-style: normal;color : #36609A;font-weight: bold\" > Hope you find this notebook helpful and enjoy going through this notebook...Thanks and Happy Reading...</p>","metadata":{}},{"cell_type":"markdown","source":"<a id = '0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >Table of Contents</h2> \n\n\n*  [1. Introduction](#1.0)\n*  [2. Initial Ground Work](#2.0)\n*  [3. Data visualization](#3.0)\n*  [4. Classification with Vanila CNN](#4.0)\n*  [5. Data agumentaion, learning rate schedule, and Early stoping](#5.0)\n*  [6. Classification with ResNet](#6.0)\n*  [7. Final predictions on Test Set](#7.0)\n*  [8. Summary](#8.0)\n","metadata":{}},{"cell_type":"markdown","source":"<a id = '1.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >1. Introduction</h2> ","metadata":{}},{"cell_type":"markdown","source":"<p style = \"font-size: 20px; font-style: normal;color : #36609A;font-weight: bold\" ><strong>Who doesn't love a cute cat and adorable dog? </strong></p>\nThese cute creatures are so addorable, and they reach all the way to computer vision compitions on kaggle. As humans we love our cute pets so much that, we can able to identify the speicis very easily, but can our computers able to do that without our help? \n\nIts kind of teach a machine to detect a thing in object. To teach which is cat? and which is dog? to computer we are going to build a deep learning model, which could be very basic to far complex based on our level of accuracy required and computational resources available. For this notebook, we are using a dogs and cats dataset, in which collection of images of dogs and cats and our objective is to build a basic CNN and classify dogs and cats from image, based on feature learning in hidden layers and activation maps in CNN. \n\nWhats the flow for this work? \n<ul><li> First, I will explore the dataset and attempt to make EDA of data</li>\n    <li> later preprocess the data as requried, this includes image augumentations, scaling and what else need?</li>\n    <li> Try to build a basic vanilla CNN, and try to predict species as a binary classification problem</li>\n    <li> Later try to make predictions with transfer learning using ResNet50 and imagenet weights</li>\n    <li> Finally compare the results on vanilla CNN and ResNet50 with sample data</li>\n</ul>\n\n<p style = \"font-size: 30px; font-style: normal;color : #36609A;font-weight: bold\" ><strong>Cute cute Dogs and cats </strong></p>","metadata":{}},{"cell_type":"markdown","source":"\n| | | |\n|:-------------------------:|:-------------------------:|:-------------------------:|\n|<img style=\"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://i.insider.com/536aa78069bedddb13c60c3a?width=1000&format=jpeg&auto=webp\">|<img style=\"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://miro.medium.com/max/639/1*vg3kxX3H9eCNWKgBBeQHeA.jpeg\">|<img style=\"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://images.ctfassets.net/cnu0m8re1exe/7sLmeD1tcL4UoIm0BjNaLh/22a9f42a4315361db96470f50b178e86/Dog-and-Cat.jpg\">|\n|<img style = \"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://cdn.suwalls.com/wallpapers/animals/kitten-and-puppy-6928-1920x1200.jpg\">|<img style = \"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://wallpaperaccess.com/full/1081184.jpg\">|<img style = \"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"http://images4.fanpop.com/image/photos/16700000/Kittens-Puppies-teddybear64-16751426-1024-768.jpg\">|\n|<img style = \"float:center; border:10px solid #fed049; width: 550px; height : 200px\"  src=\"https://www.centrevillesquareanimalhospitalva.com/wp-content/uploads/2018/12/white_cat_and_dog.jpg\">|<img style = \"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://s3.amazonaws.com/cdn-origin-etr.akc.org/wp-content/uploads/2017/09/12192216/Chihuahua-Kitten.jpg\">|<img style = \"float:center; border:10px solid #fed049; width: 550px; height : 200px\" src=\"https://www.petbacker.com/blog/images/2017/dog-and-kitten.jpg\">|\n\n<br>\n<a href =\"https://www.google.com/search?q=dog+and+cat&rlz=1C1SQJL_enIN924IN924&sxsrf=ALeKk00fIZ8zlgT48DcdvzBb4Cvb5D4l1A:1621838427347&tbm=isch&source=iu&ictx=1&fir=BhriCENbREviAM%252CtgNZNGeRXuHXRM%252C_&vet=1&usg=AI4_-kQkz-AyFEDIX_UVuJZwrlUMfNCuMA&sa=X&ved=2ahUKEwjU3uD62uHwAhV35nMBHQ9YBRcQ9QF6BAgMEAE&biw=1536&bih=666#imgrc=lM_FAqlamnVj4M\" style = \"font-size:20px,color: dimgrey, text-align:left,font-family:serif\">Images Source: Google.com</a>\n<br>\n","metadata":{}},{"cell_type":"markdown","source":"<a id = '2.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >2. Initial Ground Work</h2> ","metadata":{}},{"cell_type":"markdown","source":"\n<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >loading all the required libraries.....</p>","metadata":{}},{"cell_type":"code","source":"class color:\n    BOLD = '\\033[1m'\n    BOLD_COLOR = '\\033[1m' + '\\033[93m'\n    END = '\\033[0m'\n\n\n\n# loading libraries\nprint(color.BOLD + '\\nImporting requreid libraries....\\n'+ color.END)\n\nimport warnings \nwarnings.filterwarnings('ignore')\n\n# basic librareis\nimport zipfile\nimport glob\nimport os\nimport pandas as pd\nimport numpy as np\nfrom PIL import Image\n\n\n# plotting and visualizations\nimport matplotlib \nimport matplotlib.pyplot as plt \n%matplotlib inline\nimport seaborn as sns \nimport missingno as msno\n\n# preprocessing\nfrom keras.preprocessing.image import (ImageDataGenerator, \n                                       img_to_array, \n                                       array_to_img, \n                                       load_img)\n\nfrom sklearn.model_selection import train_test_split\n\n# metrics\nfrom sklearn.metrics import (confusion_matrix, \n                             classification_report, \n                             accuracy_score, \n                             f1_score, \n                             roc_auc_score)\n# modeling\nimport tensorflow as tf\nfrom keras.models import Model,Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Dense,Flatten\n\nfrom keras.applications import resnet50\nfrom keras.applications.resnet50 import preprocess_input\nfrom keras import optimizers\nfrom keras import regularizers\nfrom keras.callbacks import EarlyStopping,LearningRateScheduler\n\n\nfrom keras import backend as K\nK.clear_session()\n\n# model plotting\nfrom IPython.display import SVG\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.utils import plot_model\n\n# mesc\nfrom sklearn.utils import shuffle\n\n\n\n\n\nprint(color.BOLD_COLOR + 'Done!!!'+ color.END)\n","metadata":{"id":"ZDKIXSLKKZQA","outputId":"37b1912c-460a-412d-cfca-9a165cb95bb5","_kg_hide-input":true,"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2021-06-25T16:10:14.663714Z","iopub.execute_input":"2021-06-25T16:10:14.664085Z","iopub.status.idle":"2021-06-25T16:10:19.879435Z","shell.execute_reply.started":"2021-06-25T16:10:14.664006Z","shell.execute_reply":"2021-06-25T16:10:19.878622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Color paleete for this notebook...</p>","metadata":{}},{"cell_type":"code","source":"# color palette\ncolors = ['#EF7D71','#41ABD7','#36609A','#FFCE30','#194350']\nsns.palplot(colors,size = 3)\n\nplt.gcf().set_size_inches(15,5)\n\nplt.text(-0.75,-0.75, 'Hey Siri! is it a Cat or Dog?: Color Palette',{'fontfamily':'serif', 'size':24, 'weight':'bold'})\nplt.text(-0.75,-0.68, 'Lets try to stick to these colors throughout presentation.',{'fontfamily':'serif', 'size':16},alpha = 0.9)\nfor idx,values in enumerate(colors):\n    plt.text(idx-0.25,0, colors[idx],{'fontfamily':'serif', 'size':16, 'weight':'bold','color':'#f5f6f6'}, alpha =1)\nplt.gcf().set_facecolor('#f5f6f6')\nplt.box(None)\nplt.axis('off')\nplt.text(3.5,0.65,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:19.880906Z","iopub.execute_input":"2021-06-25T16:10:19.881516Z","iopub.status.idle":"2021-06-25T16:10:20.024982Z","shell.execute_reply.started":"2021-06-25T16:10:19.881476Z","shell.execute_reply":"2021-06-25T16:10:20.023969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets Extract Labels from Image Names...</p>","metadata":{}},{"cell_type":"code","source":"# extraction of train and test data from zipfiles to data folder\nprint('\\n'+color.BOLD_COLOR + 'Extracting the data from dataset.....'+ color.END +'\\n')\nzip_files = glob.glob('/kaggle/input/dogs-vs-cats/*.zip')\n\nprint('{} files found in the input directory'.format(color.BOLD + str(len(zip_files)) + color.END) +'\\n')\nfor file in zip_files:\n    with zipfile.ZipFile(file, 'r') as Z:\n        Z.extractall('data')\n    print ('{} is extracted'.format(color.BOLD + file.split('/')[-1] + color.END) + '\\n')\n      \nprint( color.BOLD_COLOR +'Extraction is completed'+ color.END +'\\n')\n    \n  ","metadata":{"id":"VX8NiXN4Kw16","outputId":"81f2612e-2982-45ac-d046-6fec3c9a7289","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:20.027100Z","iopub.execute_input":"2021-06-25T16:10:20.027549Z","iopub.status.idle":"2021-06-25T16:10:37.176303Z","shell.execute_reply.started":"2021-06-25T16:10:20.027509Z","shell.execute_reply":"2021-06-25T16:10:37.175485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Total number of images in train and test datasets\n\ntrain_dir = '/kaggle/working/data/train/'\ntest_dir  = '/kaggle/working/data/test1/'\nprint(color.BOLD +\"Total Images in Train, and Test Data...\" +color.END)\nprint('\\n' + color.BOLD_COLOR + 'No. of Train Images: '+ color.END + color.BOLD + str(len(os.listdir(train_dir))) + color.END)\nprint( color.BOLD_COLOR + 'No. of Test Images: ' + color.END + color.BOLD + str(len(os.listdir(test_dir))) + color.END + '\\n')        ","metadata":{"id":"jeiIIza1K3-x","outputId":"caf36cf7-6fd5-49be-8557-a4eb3b2e944f","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:37.177814Z","iopub.execute_input":"2021-06-25T16:10:37.178145Z","iopub.status.idle":"2021-06-25T16:10:37.205833Z","shell.execute_reply.started":"2021-06-25T16:10:37.178108Z","shell.execute_reply":"2021-06-25T16:10:37.205035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# category and filepath extraction helper functions\n\ndef category(path): \n    return [file.split('.')[0] for file in os.listdir(path)]\n\ndef filename(path):\n    return [file for file in os.listdir(path)]\n\n# image names and labels\nx_train_imgname = filename(train_dir) \nx_test_imgname = filename(test_dir)\ny_train_label = category(train_dir)\n\n#creation of total dataframe and submission dataframe\nprint( '\\n'+color.BOLD + 'Image data is storing into dataframes...'+ color.END + '\\n')\ntrain_image_df = pd.DataFrame({ 'filename': x_train_imgname, 'category': y_train_label})\nsubmission_image_df = pd.DataFrame({'filename': x_test_imgname})\n\nprint(color.BOLD +'Training image names and labels are read to '+ color.END + color.BOLD_COLOR +'train_image_df' + color.END + '\\n')\nprint(color.BOLD +'Testing image names are read to '+ color.END + color.BOLD_COLOR + 'submission_image_df'+ color.END + '\\n')\n\n","metadata":{"id":"ZkS8Las2KyHK","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:37.207034Z","iopub.execute_input":"2021-06-25T16:10:37.207394Z","iopub.status.idle":"2021-06-25T16:10:37.263794Z","shell.execute_reply.started":"2021-06-25T16:10:37.207357Z","shell.execute_reply":"2021-06-25T16:10:37.262867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id = '3.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >3.Data visualization</h2> ","metadata":{}},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets write helper funtions for path extraction and visualization of training images...</p>","metadata":{}},{"cell_type":"code","source":"print(color.BOLD +'\\n'+'Helper funtions for image path,id, category data extractions and Image visualizations' +'\\n'+color.END)\n# helper functions \n\ndef img_path(directory):\n    ''' \n    This function extracts image ids, category,and image paths from directory.\n    input:\n    directiory: Path to location of images\n    Return:\n    ID_no: list of image ids\n    Paths: list of image paths\n    cate: list of category\n    '''\n    paths = []\n    cate = []\n    ID_no = []\n    for file in os.listdir(directory):\n        path = os.path.join(directory, file)\n        paths.append(path)\n        cate.append(file.split('.')[0])\n        ID_no.append(file.split('.')[1])\n    return ID_no, paths, cate\n\n\n\n\ndef showImages(data,num_row  = 3,num_col =  3, name = 'any', subtitle = 'off'):\n    \"\"\" This function creates a grid of images from  dataset.\n    Shuffled images will be displayed.\n    \n    Input: \n    num_row: default: 3, no. of rows in a grid\n    num_col: default:3, no. of columns in grid\n    data: Dataframe of paths \n    name:  default 'any', takes: cat, dog, any or something else would give both\n    subtitle: display id number for each image, defalult: 'off', takes: 'on' and 'off'\n    Return: None\n    \n    \"\"\"\n    \n    # little data sorting\n    cat_df,dog_df = data[data['Category'] == 'cat'], data[data['Category'] == 'dog']\n\n    \n    if name == 'dog':\n        X, Y  = dog_df['img_paths'], dog_df['ID_no']\n    elif name == 'cat':\n        X, Y  = cat_df['img_paths'], cat_df['ID_no']     \n    else:\n        X, Y  = data['img_paths'], data['ID_no']     # could use try and except but lets stick to minimal code\n\n    (X_rand, Y_rand) = shuffle(X, Y)\n    \n    # showing images on matplotlib \n    \n    fig, ax = plt.subplots(num_row,num_col,figsize = (12,12), dpi = 100)\n    fig.patch.set_facecolor('#f5f6f6')\n    axes = ax.ravel()\n    \n    for idx,ax  in enumerate(axes):\n        x = load_img(X_rand.iloc[idx],target_size= (125, 125))\n        ax.imshow(x)\n        if subtitle == 'on':\n            ax.set_title(\"{}\".format(Y_rand.iloc[idx]))\n        else:\n            ax.set_title('')\n        ax.axis('off')\n        plt.subplots_adjust(wspace =0)\n        del x\n    #fig.tight_layout()\n    \n    fig.text(0.1,0.93, 'Hey Siri! is it a Cat or Dog?: {}s from Training Data'.format(name.capitalize()),{'fontfamily':'serif','size':18,'weight':'bold'})\n    \n    return None\n","metadata":{"id":"taVy1YO0UrXj","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:37.265193Z","iopub.execute_input":"2021-06-25T16:10:37.265555Z","iopub.status.idle":"2021-06-25T16:10:37.279726Z","shell.execute_reply.started":"2021-06-25T16:10:37.265521Z","shell.execute_reply":"2021-06-25T16:10:37.278726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Implementing above function over train data set\nID_no, img_paths, train_images = img_path(train_dir)\n\nprint('\\n'+color.BOLD_COLOR + 'Dataframe is creating for training image visualization in a grid...' + color.END+'\\n' )\n#creating new dataframe for data visulaization\n\nvisual_df = pd.DataFrame({'ID_no':ID_no,'Category':train_images, 'img_paths': img_paths})\n\nprint(color.BOLD );print(visual_df.head(5))\n\nprint('\\n'+color.BOLD_COLOR +'Done!'+color.END + '\\n')","metadata":{"id":"wJWxS9aqaoo7","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:37.281272Z","iopub.execute_input":"2021-06-25T16:10:37.281698Z","iopub.status.idle":"2021-06-25T16:10:37.377466Z","shell.execute_reply.started":"2021-06-25T16:10:37.281661Z","shell.execute_reply":"2021-06-25T16:10:37.376554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets see the images from training images...</p>","metadata":{}},{"cell_type":"code","source":"showImages(visual_df,5,5, name = 'dog', subtitle = 'off')","metadata":{"id":"y2OoIdtTaoPX","outputId":"15a528b6-fec1-4fcf-8cee-3108f3e92ad3","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:37.380117Z","iopub.execute_input":"2021-06-25T16:10:37.380469Z","iopub.status.idle":"2021-06-25T16:10:38.608867Z","shell.execute_reply.started":"2021-06-25T16:10:37.380435Z","shell.execute_reply":"2021-06-25T16:10:38.608004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImages(visual_df,5,5, name = 'cat', subtitle = 'off')","metadata":{"id":"3IEE-WG-A4-g","outputId":"02bbb2de-055a-45c8-f447-b6519a11570f","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:38.610712Z","iopub.execute_input":"2021-06-25T16:10:38.611078Z","iopub.status.idle":"2021-06-25T16:10:39.989056Z","shell.execute_reply.started":"2021-06-25T16:10:38.611035Z","shell.execute_reply":"2021-06-25T16:10:39.988277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImages(visual_df,5,5, name = 'Dogs and Cat', subtitle = 'off')","metadata":{"id":"yo7z0IwmWtHx","outputId":"65df8ea8-8a82-4788-a9cd-835ae1755229","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:39.990163Z","iopub.execute_input":"2021-06-25T16:10:39.990583Z","iopub.status.idle":"2021-06-25T16:10:41.292396Z","shell.execute_reply.started":"2021-06-25T16:10:39.990549Z","shell.execute_reply":"2021-06-25T16:10:41.291424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets split data into training and validation dataset, and visualize the data distribution...</p>","metadata":{"id":"up4ajfD3Qbky"}},{"cell_type":"code","source":"# Data split into train data and validation data\ntrain_valid_df, test_df = train_test_split(train_image_df, test_size = 0.04)\ntrain_df, valid_df = train_test_split(train_valid_df, test_size = 0.2)\n\ntrain_images = train_df.shape[0]\nvalid_images = valid_df.shape[0]\nholdon_images = test_df.shape[0]\ntest_images = submission_image_df.shape[0]\n\nprint('\\n'+color.BOLD_COLOR + 'Number of Training Images: ' + color.END + color.BOLD+ str(train_images)+ color.END)\nprint('\\n'+color.BOLD_COLOR +  'Number of Validating Images: ' + color.END + color.BOLD+ str(valid_images)+ color.END)\nprint( '\\n'+color.BOLD_COLOR +  'Number of Holdon Images: ' + color.END +  color.BOLD+ str(holdon_images)+ color.END)\nprint('\\n'+color.BOLD_COLOR + 'Number of Testing Images: ' + color.END +  color.BOLD+str(test_images)+ color.END)\n","metadata":{"id":"FKcypyT2QYYP","outputId":"93b7bb55-989c-4cbf-fe1c-23a9f5c77b68","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:41.293784Z","iopub.execute_input":"2021-06-25T16:10:41.294095Z","iopub.status.idle":"2021-06-25T16:10:41.314391Z","shell.execute_reply.started":"2021-06-25T16:10:41.294063Z","shell.execute_reply":"2021-06-25T16:10:41.313511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize =(8,8), dpi = 100)\nfig.patch.set_facecolor('#f5f6f6')\ngs = fig.add_gridspec(10,10)\n\nax0 = fig.add_subplot(gs[2:5,1:5])\nax1 = fig.add_subplot(gs[2:5,6:10])\nax2 = fig.add_subplot(gs[6:9,3:7])\n\n\naxes = [ax0,ax1,ax2]\ndata  = [train_df['category'] ,  valid_df['category'], test_df['category']]\nlabels = ['Training Data','Validation Data','Testing Data']\n\nfor ax in axes:\n    ax.set_facecolor('#f5f6f6')\n    ax.axes.get_yaxis().set_visible(False)\n    \n    for loc in ['left','right','top','bottom']:\n        ax.spines[loc].set_visible(False)\n    \nfor ax,df, label in zip(axes,data,labels):\n    sns.countplot(df, ax = ax, palette = [colors[2],colors[3]], alpha =1)\n    ax.set_xlabel(xlabel = ' ')\n    for pa in ax.patches: \n        ax.text(pa.get_x(), pa.get_height(),'{}'.format(pa.get_height()), **{'fontfamily':'serif', 'size':10, 'weight':'bold'}, alpha = 1)\n\n    ax.text(0,0,label,**{'fontfamily':'serif', 'size':10, 'weight':'bold'})\n\nfig.text(0.1,0.82, 'Hey Siri!! is it a Cat or Dog?: Images Distribution',{'fontfamily':'serif','size':18,'weight':'bold'})\nfig.text(0.1,0.77, '''All the image distributions are fairly balanced so, hope we can\nget fair accuracy as well''',{'fontfamily':'serif','size':12,})\n\nfig.text(0.75,0.15,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\nfig.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:41.315626Z","iopub.execute_input":"2021-06-25T16:10:41.315942Z","iopub.status.idle":"2021-06-25T16:10:41.551087Z","shell.execute_reply.started":"2021-06-25T16:10:41.315912Z","shell.execute_reply":"2021-06-25T16:10:41.550117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id = '4.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >4. Classification with Vanilla CNN</h2> ","metadata":{"id":"A8gmnjNu6m9J"}},{"cell_type":"markdown","source":"Our datasets are evenly distributed. In this notebook, for the first benchmark model I will use a pretrained model and it can further improved upon. \nSince, our task is similar to ImageNet challenge with 2 class classification any pretrained model from [keras applcations](https://keras.io/api/applications/) can be used.\nMoreover, it's is not that practical to achieve a higher accurarcy with a custom build cnn from scartch. \n\nlet's get started with a simple vanila network without data augmentation (shown in figure below) first to see how good it can perform. Later, we will move towards other techniques.\n\n","metadata":{}},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" > Let prepared training, validation, testing data for vanilla CNN without any agumentations...</p>","metadata":{}},{"cell_type":"code","source":"img_size = 224\nbatch_size = 128\n\nprint(color.BOLD_COLOR + '\\nPreparing train and validation images for training...' + color.END)\n# dataframe iterators without data agumnetation\n\ntrain_map = ImageDataGenerator()\nvalid_map = ImageDataGenerator()\ntest_map =  ImageDataGenerator()\n\nprint(color.BOLD)\n        \n#Creatinga a dataframe iterators for fitting\nvani_train_data = train_map.flow_from_dataframe(\n            train_df,train_dir,\n            x_col = 'filename',\n            y_col = 'category',\n            target_size = (img_size, img_size),\n            batch_size = batch_size,\n            class_mode = 'categorical')\n\nvani_valid_data = valid_map.flow_from_dataframe(\n             valid_df, train_dir,\n             x_col = 'filename',\n             y_col = 'category',\n             target_size = (img_size, img_size),\n             batch_size = batch_size,\n             class_mode = 'categorical')\n\n\nvani_test_data = test_map.flow_from_dataframe(\n             test_df, train_dir,\n             x_col = 'filename',\n             y_col = None,\n             target_size = (img_size, img_size),\n             batch_size = batch_size,\n             class_mode = None,\n             shuffle = False)\n\nprint(color.BOLD_COLOR + '\\nDone!')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:41.552476Z","iopub.execute_input":"2021-06-25T16:10:41.552810Z","iopub.status.idle":"2021-06-25T16:10:41.807164Z","shell.execute_reply.started":"2021-06-25T16:10:41.552774Z","shell.execute_reply":"2021-06-25T16:10:41.806377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets build vanila CNN model ...</p>","metadata":{}},{"cell_type":"code","source":"#Building model computational graph\nvani_model = Sequential()\nvani_model.add(Conv2D(16, (3,3), activation = 'relu', padding = 'same', input_shape = (224,224,3)))\nvani_model.add(Conv2D(16, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2), strides=(2,2)))\n\nvani_model.add(Conv2D(32, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(32, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2), strides=(2,2)))\n\nvani_model.add(Conv2D(64, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(64, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2),strides=(2,2)))\n\nvani_model.add(Conv2D(128, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(128, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2),strides=(2,2)))\n\nvani_model.add(Dropout(0.3))\n\nvani_model.add(Conv2D(256, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(256, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2),strides=(2,2)))\n\nvani_model.add(Dropout(0.3))\n\nvani_model.add(Flatten())\n\nvani_model.add(Dense(512, activation = 'relu'))\n\nvani_model.add(Dropout(0.5))\n\nvani_model.add(Dense(2, activation = 'softmax'))\n\nprint(color.BOLD_COLOR + '\\nVanilla Model layers and output shapes with params...\\n'+color.END)\n\nprint(color.BOLD)\nvani_model.summary()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:41.808386Z","iopub.execute_input":"2021-06-25T16:10:41.808714Z","iopub.status.idle":"2021-06-25T16:10:44.261750Z","shell.execute_reply.started":"2021-06-25T16:10:41.808668Z","shell.execute_reply":"2021-06-25T16:10:44.260936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets See vanila CNN model Schematic diagram ...</p>","metadata":{}},{"cell_type":"code","source":"plot_model(vani_model, show_shapes = True,expand_nested = True,dpi = 80)\n#SVG(model_to_dot(vani_model).create(prog='dot', format='svg'))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:44.263025Z","iopub.execute_input":"2021-06-25T16:10:44.263377Z","iopub.status.idle":"2021-06-25T16:10:44.723309Z","shell.execute_reply.started":"2021-06-25T16:10:44.263326Z","shell.execute_reply":"2021-06-25T16:10:44.722368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets train and validate on vanila CNN model ...</p>","metadata":{}},{"cell_type":"code","source":"#compiling model with loss, opt, metrics\nloss = 'categorical_crossentropy'\nopt = tf.keras.optimizers.Adam(learning_rate= 0.0001,beta_1=0.9, beta_2=0.999,epsilon=1e-07)\nmetrics = ['accuracy']\n\nvani_model.compile(loss = loss, optimizer = opt, metrics = metrics)\n\nprint(color.BOLD_COLOR + 'Training on Vanilla CNN has started ....\\n'+ color.END)\nprint(color.BOLD)\n# fitting the model for training dataset\nvani_history = vani_model.fit(vani_train_data, epochs = 15,\n                          validation_data = vani_valid_data,\n                          validation_steps= valid_images//batch_size,\n                          steps_per_epoch= train_images//batch_size)\n\nprint(color.END)\nprint(color.BOLD_COLOR + '\\nDone!\\n'+ color.END)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:10:44.724926Z","iopub.execute_input":"2021-06-25T16:10:44.725297Z","iopub.status.idle":"2021-06-25T16:51:01.888148Z","shell.execute_reply.started":"2021-06-25T16:10:44.725256Z","shell.execute_reply":"2021-06-25T16:51:01.887191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets plot vanila CNN model change in loss and accuracys with epochs ...</p>","metadata":{}},{"cell_type":"code","source":"fig,ax  = plt.subplots(2,1, figsize =(8,8), dpi = 100)\nfig.patch.set_facecolor('#f5f6f6')\n\naxes  = ax.ravel()\n\nfor ax in axes:\n    ax.set_facecolor('#f5f6f6')\n    for loc in ['right','top',]:\n        ax.spines[loc].set_visible(False)\n        \nhist1 = vani_history.history\nEpochs =  range(len(hist1['loss']))\n\n## loss plot\nsns.lineplot(x = Epochs, y = hist1['val_loss'],  ax = axes[0], linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist1['loss'], ax  = axes[0], linewidth =4,  color = colors[4])\n\n\naxes[0].text(Epochs[-1]+0.25,hist1['val_loss'][-1],'Validation Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[0].text(Epochs[-1]+0.25,hist1['loss'][-1] ,'Training Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\n# accuracy plot\nsns.lineplot(x = Epochs, y = hist1['val_accuracy'],ax = axes[1],linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist1['accuracy'],ax = axes[1],linewidth =4,  color = colors[4])\naxes[1].text(Epochs[-1]+0.25,hist1['val_accuracy'][-1],'Validation Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[1].text(Epochs[-1]+0.25,hist1['accuracy'][-1] ,'Training Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\nfig.text(0,1.06, 'Hey Siri! is it a Cat or Dog?: Vanilla Loss and Accuracy ',{'fontfamily':'serif', 'size':18, 'weight':'bold'})\nfig.text(0,1.01, '''Clearly There is a overfitting with this model, may be transfer learning\nshould correct this issue.''',{'fontfamily':'serif', 'size':12})\n        \nfig.text(0.75,-0.05,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.tight_layout(h_pad = 5)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:01.889714Z","iopub.execute_input":"2021-06-25T16:51:01.890053Z","iopub.status.idle":"2021-06-25T16:51:02.342790Z","shell.execute_reply.started":"2021-06-25T16:51:01.890016Z","shell.execute_reply":"2021-06-25T16:51:02.342009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets see vanila CNN predictions with confusion matrix ...</p>","metadata":{}},{"cell_type":"code","source":"vani_pred = vani_model.predict_generator(vani_test_data)\ntest_df['vani_pred'] = np.argmax(vani_pred, axis = -1)\nlabels = dict((v,k) for k,v in vani_train_data.class_indices.items())\n\ntest_df['vani_pred'] = test_df['vani_pred'].map(labels)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:02.344026Z","iopub.execute_input":"2021-06-25T16:51:02.344382Z","iopub.status.idle":"2021-06-25T16:51:13.693073Z","shell.execute_reply.started":"2021-06-25T16:51:02.344345Z","shell.execute_reply":"2021-06-25T16:51:13.692184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_confusion_matrix(cf,\n                          group_names=None,\n                          categories='auto',\n                          count=True,\n                          percent=True,\n                          cbar=True,\n                          xyticks=True,\n                          xyplotlabels=True,\n                          sum_stats=True,\n                          figsize=None,\n                          cmap='Blues',\n                          title=None):\n\n\n    # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n    blanks = ['' for i in range(cf.size)]\n\n    if group_names and len(group_names)==cf.size:\n        group_labels = [\"{}\\n\".format(value) for value in group_names]\n    else:\n        group_labels = blanks\n\n    if count:\n        group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n    else:\n        group_counts = blanks\n\n    if percent:\n        group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n    else:\n        group_percentages = blanks\n\n    box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n    box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n\n\n    # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n    if sum_stats:\n        #Accuracy is sum of diagonal divided by total observations\n        accuracy  = np.trace(cf) / float(np.sum(cf))\n\n        #if it is a binary confusion matrix, show some more stats\n        if len(cf)==2:\n            #Metrics for Binary Confusion Matrices\n            precision = cf[1,1] / sum(cf[:,1])\n            recall    = cf[1,1] / sum(cf[1,:])\n            f1_score  = 2*precision*recall / (precision + recall)\n            stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(\n                accuracy,precision,recall,f1_score)\n        else:\n            stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n    else:\n        stats_text = \"\"\n\n\n    # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n    if figsize==None:\n        #Get default figure size if not set\n        figsize = plt.rcParams.get('figure.figsize')\n\n    if xyticks==False:\n        #Do not show categories if xyticks is False\n        categories=False\n\n\n    # MAKE THE HEATMAP VISUALIZATION\n    fig = plt.figure(figsize=figsize)\n    fig.patch.set_facecolor('#f5f6f6')\n    sns.heatmap(cf,annot=box_labels,fmt=\"\",linewidths = 1,square = True,linecolor= '#f5f6f6',\n                cmap=cmap,cbar=cbar,annot_kws={'fontfamily':'serif','size':18,'weight':'bold'},\n                xticklabels=categories,\n                yticklabels=categories,)\n\n    if xyplotlabels:\n        plt.ylabel('True label', **{'fontfamily':'serif','size':12,'weight':'bold'})\n        plt.xlabel('Predicted label' + stats_text,**{'fontfamily':'serif','size':12,'weight':'bold'})\n    else:\n        plt.xlabel(stats_text,**{'fontfamily':'serif','size':12,'weight':'bold'})\n    \n    plt.gca().set_xticklabels(categories, {'fontfamily':'serif','size':16,'weight':'bold'})\n    plt.gca().set_yticklabels(categories, {'fontfamily':'serif','size':16,'weight':'bold'})","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:13.694491Z","iopub.execute_input":"2021-06-25T16:51:13.694838Z","iopub.status.idle":"2021-06-25T16:51:13.710064Z","shell.execute_reply.started":"2021-06-25T16:51:13.694803Z","shell.execute_reply":"2021-06-25T16:51:13.709064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vani_cf_matrix = confusion_matrix(test_df['category'],test_df['vani_pred'])\nmy_cols = [colors[3],colors[2]]\n\nlabels = [ 'True Neg','False Pos','False Neg','True Pos']\ncategories = ['Cat', 'Dog']\nmake_confusion_matrix(vani_cf_matrix,figsize = (10,5),\n                      group_names=labels,cbar = False,cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\"\",my_cols),\n                      categories=categories, \n                      title = 'Vanila CNN comfusion matrix')\n\nplt.gcf().text(0,1.1,'Hey Siri! is it a Cat or Dog?: Vanilla CNN Test Data Evaluation',{'fontfamily':'serif', 'size':24,  'color':'black', 'weight':'bold'})\nplt.gcf().text(0,0.995,\"\"\"It seem even vanilla CNN did a fair job considering parameters trained.\nLets see how pre-trained model does the job...\"\"\",{'fontfamily':'serif', 'size':14,  'color':'black', })\n\nplt.gcf().text(0.85,-0.15,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.gcf().show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:13.711427Z","iopub.execute_input":"2021-06-25T16:51:13.711790Z","iopub.status.idle":"2021-06-25T16:51:13.866854Z","shell.execute_reply.started":"2021-06-25T16:51:13.711755Z","shell.execute_reply":"2021-06-25T16:51:13.866116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<a id = '5.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >5. Data Agumentation, Early Stopping, Learning Rate Schedule</h2> ","metadata":{}},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" > Lets code helper function for visualization of image agumentation...</p>","metadata":{}},{"cell_type":"code","source":"print(color.BOLD +'\\n'+'Helper funtions for Image Agumentation visualizations' +'\\n'+color.END)\n\ndef data_argumentation_show(n, grid_size):\n    sample_aug_map = ImageDataGenerator(\n            #zoom_range = 0.1,\n            rotation_range = 25,\n            horizontal_flip = True,\n            height_shift_range =0.2,\n            width_shift_range = 0.2,\n            fill_mode='nearest',\n            rescale = 1/255)\n    sample_data = sample_aug_map.flow_from_dataframe(\n            (train_df.sample(n)),\n            train_dir,\n            x_col = 'filename',\n            y_col = 'category',\n            target_size = (img_size, img_size),\n            class_mode = 'categorical')\n  \n  #subplot grid \n    fig = plt.figure(figsize = (10,10))\n    fig.patch.set_facecolor('#f5f6f6')\n    for i in range(0,grid_size*grid_size):\n        plt.subplot(grid_size,grid_size, i+1)\n        for x,y in sample_data:\n            img = x[0]\n            plt.imshow(img)\n            plt.axis('off')\n            break\n            plt.tight_layout()\n            del img\n    fig.show()\n\n     \n    fig.text(0.1,0.93, 'Hey Siri! is it cat or dog?: Image agumentation',{'fontfamily':'serif','size':20,'weight':'bold'})\n    \n    return None\n\n","metadata":{"id":"1xh9oi9dQYdu","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:13.868154Z","iopub.execute_input":"2021-06-25T16:51:13.868613Z","iopub.status.idle":"2021-06-25T16:51:13.878488Z","shell.execute_reply.started":"2021-06-25T16:51:13.868577Z","shell.execute_reply":"2021-06-25T16:51:13.877574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# To visulalize the effect of data argumentation \n#select number of samples to argument----> n = \n# total number of argumentation is grid_Size**2\n\ndata_argumentation_show(1, 5)","metadata":{"id":"VXw80kw6QYbi","outputId":"7c0ee447-836a-4198-8687-38d4bfc415f0","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:13.879653Z","iopub.execute_input":"2021-06-25T16:51:13.880158Z","iopub.status.idle":"2021-06-25T16:51:15.061991Z","shell.execute_reply.started":"2021-06-25T16:51:13.880121Z","shell.execute_reply":"2021-06-25T16:51:15.060370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_argumentation_show(2, 5)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:15.067198Z","iopub.execute_input":"2021-06-25T16:51:15.067558Z","iopub.status.idle":"2021-06-25T16:51:16.929189Z","shell.execute_reply.started":"2021-06-25T16:51:15.067523Z","shell.execute_reply":"2021-06-25T16:51:16.928245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" > Decaying learing rate setting function...</p>","metadata":{}},{"cell_type":"code","source":"print(color.BOLD + '\\nSetting a decay learning rate for learning rate schedule\\n'+ color.END)\nepoch = 50\nlearning_rate = 3e-5 \nlr_start = 0.00000001\nlr_min = 0.000001\nlr_max = 3e-5 \nlr_rampup_epochs = 1\nlr_sustain_epochs = 1\nlr_exp_decay = .8\n\ndef lrfn(epoch):\n    if epoch < lr_rampup_epochs:\n        lr = (lr_max - lr_start) / lr_rampup_epochs * epoch + lr_start\n    elif epoch < lr_rampup_epochs + lr_sustain_epochs:\n        lr = lr_max\n    else:\n        lr = (lr_max - lr_min) * lr_exp_decay**(epoch - lr_rampup_epochs - lr_sustain_epochs) + lr_min\n    return lr\n    \nprint(color.BOLD_COLOR + 'Done!' +color.END)\n","metadata":{"id":"Hdjed4u7oYx8","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:16.930974Z","iopub.execute_input":"2021-06-25T16:51:16.931311Z","iopub.status.idle":"2021-06-25T16:51:16.940300Z","shell.execute_reply.started":"2021-06-25T16:51:16.931277Z","shell.execute_reply":"2021-06-25T16:51:16.939434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 20\nepochs_range = [i for i in range(50 if epochs<50 else epochs)]\nlearn_rate = [lrfn(x) for x in epochs_range]\n\n\nfig,ax = plt.subplots(figsize = (10,5))\nfig.patch.set_facecolor('#f5f6f6')\nax.set_facecolor('#f5f6f6')\n\nfor loc in ['right','top',]:\n    ax.spines[loc].set_visible(False)\n\nax.plot(epochs_range, learn_rate, linewidth = 4, color= colors[2]) \nplt.xlabel('Range of epochs',{'fontfamily':'serif', 'size':14,  'color':'black', 'weight':'bold'})\nplt.ylabel('Learning rate in 10^-5',{'fontfamily':'serif', 'size':14,  'color':'black', 'weight':'bold'})\n\n\nplt.gcf().text(0,1.06,'Hey Siri! is it a cat or dog?: Learning Rate Schedule',{'fontfamily':'serif', 'size':24,  'color':'black', 'weight':'bold'})\nplt.gcf().text(0,0.975,\"\"\"Initially set a learning rate that linearly increase from 1e-08 to 3e-5 and later\nexponentially decreases from 3e-5 to 1e-6\"\"\",{'fontfamily':'serif', 'size':14,  'color':'black', })\n\nplt.gcf().text(0.75,0,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.gcf().show()","metadata":{"id":"v79OSrS0FWvK","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:16.941851Z","iopub.execute_input":"2021-06-25T16:51:16.942497Z","iopub.status.idle":"2021-06-25T16:51:17.107904Z","shell.execute_reply.started":"2021-06-25T16:51:16.942459Z","shell.execute_reply":"2021-06-25T16:51:17.107057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id = '6.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >6. Classification with ResNet50</h2> ","metadata":{"id":"b5wQCvt-njNa"}},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" > Image agumentation data preparation with ImageDataGenerator</p>","metadata":{}},{"cell_type":"code","source":"print(color.BOLD_COLOR + '\\n Agumenting Train, Validation images... and testing images just passing through... \\n'+ color.END)\n\nprint(color.BOLD)\n# using standard data augumentation\n\ntrain_aug_map = ImageDataGenerator(\n                    rotation_range=10,\n                    #zoom_range=0.1,\n                    horizontal_flip=True,\n                    fill_mode='nearest',\n                    #width_shift_range=0.1,\n                    #height_shift_range=0.1,\n                    preprocessing_function = preprocess_input)\nres_train_data = train_aug_map.flow_from_dataframe(\n            train_df, train_dir,\n            x_col = 'filename',\n            y_col = 'category',\n            target_size = (img_size, img_size),\n            batch_size = batch_size,\n            class_mode = 'categorical')\n\n#one should validate the generality of model on the actcual target images\n#so not supposed agumentation\nvalid_aug_map = ImageDataGenerator(preprocessing_function = preprocess_input)\n\nres_valid_data = valid_aug_map.flow_from_dataframe(\n             valid_df, train_dir,\n             x_col = 'filename',\n             y_col = 'category',\n             target_size = (img_size, img_size),\n             batch_size = batch_size,\n             class_mode = 'categorical')\n\n\n#test data rescaling images\n\ntest_aug_map = ImageDataGenerator(preprocessing_function = preprocess_input)\n\nres_test_data = test_aug_map.flow_from_dataframe(\n             test_df, train_dir,\n             x_col = 'filename',\n             y_col = None,\n             class_mode = None,\n             target_size = (img_size, img_size),\n             shuffle = False)\n           \n","metadata":{"id":"YXMZlhOfPQt5","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:17.109136Z","iopub.execute_input":"2021-06-25T16:51:17.109626Z","iopub.status.idle":"2021-06-25T16:51:17.356423Z","shell.execute_reply.started":"2021-06-25T16:51:17.109588Z","shell.execute_reply":"2021-06-25T16:51:17.355529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" > Building model for transfer learning on top of pretrained ResNet50 Model...</p>","metadata":{}},{"cell_type":"code","source":"#loading resent \nresNet = tf.keras.applications.ResNet50(weights = 'imagenet',\n                        include_top = False,\n                        input_shape = (224,224, 3))\n\nresNet.trainable = False # Freeze layers\nresNet_model = Sequential([\n        resNet,\n        Flatten(),\n        Dense(1024, activation = 'relu'),\n        Dropout(0.4),\n        Dense(2, activation = 'softmax')])\n     \n\noptimizer = optimizers.Adam(1e-5)\n\nprint(color.BOLD_COLOR + '\\nResNet based Transfer learning Model layers and output shapes with params...\\n'+color.END)\n\nprint(color.BOLD)\nresNet_model.summary()\n#plot_model(resNet_model, to_file='resNet_model.png')","metadata":{"id":"vf854PFUPQ0z","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:17.357687Z","iopub.execute_input":"2021-06-25T16:51:17.358175Z","iopub.status.idle":"2021-06-25T16:51:19.665993Z","shell.execute_reply.started":"2021-06-25T16:51:17.358126Z","shell.execute_reply":"2021-06-25T16:51:19.665077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(color.BOLD + '\\nSetting early stopping factor and learning rate schedule\\n' +color.END)\n\nearlystop = EarlyStopping(patience= 5)\n    \nlr_callback = LearningRateScheduler(lrfn, verbose = True)\n\ncallbacks = [earlystop, lr_callback]\nprint(color.BOLD_COLOR + 'Done!')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:19.667302Z","iopub.execute_input":"2021-06-25T16:51:19.667653Z","iopub.status.idle":"2021-06-25T16:51:19.676871Z","shell.execute_reply.started":"2021-06-25T16:51:19.667624Z","shell.execute_reply":"2021-06-25T16:51:19.674817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets train and validate Pre-trained ResNet50 model for top layers...</p>","metadata":{}},{"cell_type":"code","source":"resNet_model.compile(optimizer = optimizer,\n             loss = 'categorical_crossentropy',\n             metrics = ['accuracy'])\n\nprint(color.BOLD_COLOR + 'Training on ResNet50 has started ....\\n'+ color.END)\nprint(color.BOLD)\n\nresnet_history = resNet_model.fit_generator(res_train_data, epochs = 15,\n                          validation_data = res_valid_data,\n                          validation_steps= valid_images//batch_size,\n                          steps_per_epoch= train_images//batch_size,\n                          callbacks = callbacks)\nprint(color.END)\nprint(color.BOLD_COLOR + 'Done!\\n'+ color.END)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T16:51:19.678191Z","iopub.execute_input":"2021-06-25T16:51:19.678576Z","iopub.status.idle":"2021-06-25T17:51:29.580367Z","shell.execute_reply.started":"2021-06-25T16:51:19.678539Z","shell.execute_reply":"2021-06-25T17:51:29.579301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets plot Resnet models change in loss and accuracys with epochs ...</p>","metadata":{}},{"cell_type":"code","source":"fig,ax  = plt.subplots(2,1, figsize =(8,8), dpi = 100)\nfig.patch.set_facecolor('#f5f6f6')\n\naxes  = ax.ravel()\n\nfor ax in axes:\n    ax.set_facecolor('#f5f6f6')\n    for loc in ['right','top',]:\n        ax.spines[loc].set_visible(False)\n        \nhist2 = resnet_history.history\nEpochs =  range(len(hist2['loss']))\n\n## loss plot\nsns.lineplot(x = Epochs, y = hist2['val_loss'],  ax = axes[0], linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist2['loss'], ax  = axes[0], linewidth =4,  color = colors[4])\n\n\naxes[0].text(Epochs[-1]+0.25,hist2['val_loss'][-1],'Validation Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[0].text(Epochs[-1]+0.25,hist2['loss'][-1]-0.1 ,'Training Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\n# accuracy plot\nsns.lineplot(x = Epochs, y = hist2['val_accuracy'],ax = axes[1],linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist2['accuracy'],ax = axes[1],linewidth =4,  color = colors[4])\naxes[1].text(Epochs[-1]+0.25,hist2['val_accuracy'][-1]-0.04,'Validation Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[1].text(Epochs[-1]+0.25,hist2['accuracy'][-1] ,'Training Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\nfig.text(0,1.06, 'Hey Siri! is it a cat or dog?: ResNet Loss and Accuracy ',{'fontfamily':'serif', 'size':18, 'weight':'bold'})\nfig.text(0,1.01, '''As expected transfer learning did a good job with alomost negligable\ndifference between validtion and training loss and accuracies.''',{'fontfamily':'serif', 'size':12})\nfig.text(0.75,-0.05,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\n        \nplt.tight_layout(h_pad = 5)\n\nfig.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T17:51:29.581789Z","iopub.execute_input":"2021-06-25T17:51:29.582052Z","iopub.status.idle":"2021-06-25T17:51:30.025826Z","shell.execute_reply.started":"2021-06-25T17:51:29.582024Z","shell.execute_reply":"2021-06-25T17:51:30.024987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets see ResNet predictions with confusion matrix ...</p>","metadata":{}},{"cell_type":"code","source":"res_pred = resNet_model.predict_generator(res_test_data)\ntest_df['res_pred'] = np.argmax(res_pred, axis = -1)\nlabels = dict((v,k) for k,v in res_train_data.class_indices.items())\n\ntest_df['res_pred'] = test_df['res_pred'].map(labels)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T17:51:30.027069Z","iopub.execute_input":"2021-06-25T17:51:30.027432Z","iopub.status.idle":"2021-06-25T17:51:34.560366Z","shell.execute_reply.started":"2021-06-25T17:51:30.027396Z","shell.execute_reply":"2021-06-25T17:51:34.559496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res_cf_matrix = confusion_matrix(test_df['category'],test_df['res_pred'])\nmy_cols = [colors[3],colors[2]]\n\nlabels = [ 'True Neg','False Pos','False Neg','True Pos']\ncategories = ['Cat', 'Dog']\nmake_confusion_matrix(res_cf_matrix,figsize = (10,5),\n                      group_names=labels,cbar = False,cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\"\",my_cols),\n                      categories=categories, \n                      title = 'Vanila CNN comfusion matrix')\n\nplt.gcf().text(0,1.1,'Hey Siri! is it a cat or dog?: ResNet Test Data Evaluation',{'fontfamily':'serif', 'size':24,  'color':'black', 'weight':'bold'})\nplt.gcf().text(0,0.995,\"\"\"It is clear that resnet with tranfer learning did a splinded job, f1 score is 0.992 and \naccuracy is same as f1. Its a very fine result.\"\"\",{'fontfamily':'serif', 'size':14,  'color':'black', })\n\nplt.gcf().text(0.85,-0.15,'© Made by bhuvanchennoju/Kaggle',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.gcf().show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T17:51:34.561638Z","iopub.execute_input":"2021-06-25T17:51:34.561974Z","iopub.status.idle":"2021-06-25T17:51:34.724614Z","shell.execute_reply.started":"2021-06-25T17:51:34.561938Z","shell.execute_reply":"2021-06-25T17:51:34.723506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id = '7.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >7. Final predictions on Test Set</h2> ","metadata":{}},{"cell_type":"code","source":"print(color.BOLD_COLOR + '\\n Final test data preperation for both vanilla and resnet for final predictions \\n'+ color.END)\n# generating an dataframe iterator for test dataset\n\nprint(color.BOLD)\nvani_sub_aug_map = ImageDataGenerator()\nres_sub_aug_map = ImageDataGenerator(preprocessing_function = preprocess_input)\n\nvani_sub_data = vani_sub_aug_map.flow_from_dataframe(\n             submission_image_df, test_dir,\n             x_col = 'filename',\n             y_col = None,\n             class_mode = None,\n             target_size = (img_size, img_size),\n             shuffle = False)\n\n\nres_sub_data = res_sub_aug_map.flow_from_dataframe(\n             submission_image_df, test_dir,\n             x_col = 'filename',\n             y_col = None,\n             class_mode = None,\n             target_size = (img_size, img_size),\n             shuffle = False)","metadata":{"id":"-_YrpgMEPQhT","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T17:51:34.726031Z","iopub.execute_input":"2021-06-25T17:51:34.726425Z","iopub.status.idle":"2021-06-25T17:51:34.956012Z","shell.execute_reply.started":"2021-06-25T17:51:34.726387Z","shell.execute_reply":"2021-06-25T17:51:34.954951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(color.BOLD_COLOR + '\\n Making final predictions with both resnet and vanilla cnns for Test data'+color.END)\nvani_pred_sub = vani_model.predict_generator(vani_sub_data)\nsubmission_image_df['vani_pred_sub'] = np.argmax(vani_pred_sub, axis = -1)\nlabels = dict((v,k) for k,v in res_train_data.class_indices.items())\nsubmission_image_df['vani_pred_sub'] = submission_image_df['vani_pred_sub'].map(labels)\n\n\nres_pred_sub = resNet_model.predict_generator(res_sub_data)\nsubmission_image_df['res_pred_sub'] = np.argmax(res_pred_sub, axis = -1)\nlabels = dict((v,k) for k,v in res_train_data.class_indices.items())\nsubmission_image_df['res_pred_sub'] = submission_image_df['res_pred_sub'].map(labels)\n\nprint(color.BOLD)\nprint(submission_image_df.head())","metadata":{"id":"PXXnPlqpPQfQ","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T17:51:34.957451Z","iopub.execute_input":"2021-06-25T17:51:34.957891Z","iopub.status.idle":"2021-06-25T17:53:32.898371Z","shell.execute_reply.started":"2021-06-25T17:51:34.957851Z","shell.execute_reply":"2021-06-25T17:53:32.897557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = \"font-size: 25px; font-style: normal;color : #36609A;font-weight:bold\" >Lets see how our predictions are done on Test Data by both networks...</p>","metadata":{}},{"cell_type":"code","source":"pred_sample = submission_image_df.sample(18)\npred_sample.reset_index(drop = True, inplace = True)\n\nfig = plt.figure(figsize=(12,24))\nfig.patch.set_facecolor('#f5f6f6')\n\nfor index, row in pred_sample.iterrows():\n    filename = row['filename']\n    vani_pred = row['vani_pred_sub']\n    res_pred = row['res_pred_sub']\n    img = load_img( test_dir + filename, target_size= (img_size, img_size))\n    plt.subplot(6,3, index+1)\n    plt.imshow(img)\n    plt.gca().axis('off')\n    plt.text(130, 175, 'vanila_pred: {}'.format(vani_pred), color='lightgreen',fontsize= 11, bbox=dict(facecolor='black', alpha=0.9))\n    plt.text(130, 200, 'resNet_pred: {}'.format(res_pred), color='red',fontsize= 11, bbox=dict(facecolor='black', alpha=0.9))\n    #plt.title(filename.split('.')[0])\n    del img\nplt.tight_layout()\n#plt.subplots_adjust( wspace=0, hspace= 1)\nfig.text(0,1, 'Hey Siri! is it cat or dog?: Test data labels',{'fontfamily':'serif','size':24,'weight':'bold'})\nfig.show()\n   ","metadata":{"id":"yL1uQEtzPQdP","_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-06-25T17:53:32.901184Z","iopub.execute_input":"2021-06-25T17:53:32.901445Z","iopub.status.idle":"2021-06-25T17:53:34.775537Z","shell.execute_reply.started":"2021-06-25T17:53:32.901420Z","shell.execute_reply":"2021-06-25T17:53:34.774500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id = '8.0'></a>\n<h2 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color:#FFCE30 ; color : #36609A; border-radius: 5px 5px; padding:3px;text-align:center; font-weight: bold\" >8. Summary</h2> \n\n<p style = \"font-size: 30px; font-style: normal;color : #36609A;font-weight:bold\" >What happened so far?</p>\n\nSo far, I have tried to build a cat and dog classifier with help of deeplearning models, lets see the steps \n<ol>\n    <li>Data processing and visualization</li>\n    <li>Build a basic CNN and make prections</li>\n    <li>Explored Data Agumentation and Learning rate Schedule</li>\n    <li>Build a Resnet based Transfer leraning model and make prections</li>\n    <li>final comparision of both models results</li>\n</ol>\n\n<p style = \"font-size: 30px; font-style: normal;color : #36609A;font-weight:bold\" >Thank you so much for reading all the way here.....Hope you enjoyed my work.....!!! I am open to suggetions. Please do comment if you any advice or critical comments... Thanks again!!!</p>","metadata":{}}]}