{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"accelerator":"GPU","colab":{"collapsed_sections":[],"name":"Flower Recognition-VGG16(1).ipynb","provenance":[],"version":"0.3.2"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"},{"sourceId":9896,"sourceType":"datasetVersion","datasetId":6302},{"sourceId":23812,"sourceType":"datasetVersion","datasetId":17810},{"sourceId":44567,"sourceType":"datasetVersion","datasetId":10449},{"sourceId":155859,"sourceType":"datasetVersion","datasetId":71821},{"sourceId":2431805,"sourceType":"datasetVersion","datasetId":8782},{"sourceId":2609027,"sourceType":"datasetVersion","datasetId":5857}],"dockerImageVersionId":18199,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## A Comprehensive Guide to Transfer Learning \n\nIn this kernel I have demonstrated the general techniques that can be used with Transfer Learning. \n\nFor this kernel I have used the **Flower Recognition** dataset but the basic TL principles remains the same.\n\n**Basically , you need to watch two things**\n\n**1) The simalarity of your dataset with that of the pre-trained model and **\n\n**2) The amount of the data that you have.**\n\nDepending on these two conditions you can choose to either fine tune the weights or just train a classifier on top of the pre-trained model.","metadata":{"_uuid":"3b61a89492cdbed65fb1ceff914b9fd4f75c81ac"}},{"cell_type":"markdown","source":"## [ Please star / upvote if you like the kernel. ]","metadata":{"_uuid":"5807aead695b00a404422c68571c74c08fda1c65"}},{"cell_type":"markdown","source":"## CONTENTS ::->¶","metadata":{"_uuid":"edc9dc1fab5d6e7f7b7eb55beff4c4b6eda504f3"}},{"cell_type":"markdown","source":"[ **1 ) Importing Various Modules**](#content1)","metadata":{"_uuid":"b7ae07e196045117a1dd89921e943fd9b0295838"}},{"cell_type":"markdown","source":"[ **2 ) Preparing the Data**](#content2)","metadata":{"_uuid":"424911f54eb33b22ab285672a9379a5c97b534fb"}},{"cell_type":"markdown","source":"[ **3 ) Modelling**](#content3)","metadata":{"_uuid":"9c2ade7ceb8b950eb65b7ecadc24c294b459d111"}},{"cell_type":"markdown","source":"[ **4 ) Visualizing Predictons on the Validation Set**](#content4)","metadata":{"_uuid":"9b9d83431a7e347418e83238b3938cf4162aa70b"}},{"cell_type":"markdown","source":"<a id=\"content1\"></a>\n## 1 ) Importing Various Modules.","metadata":{"_uuid":"77c9b4cc1efaa0a4544f0e8ae2844264df1f0e90"}},{"cell_type":"code","source":"# Ignore  the warnings\nimport warnings\nwarnings.filterwarnings('always')\nwarnings.filterwarnings('ignore')\n\n# data visualisation and manipulation\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom matplotlib import style\nimport seaborn as sns\n \n#configure\n# sets matplotlib to inline and displays graphs below the corressponding cell.\n%matplotlib inline  \nstyle.use('fivethirtyeight')\nsns.set(style='whitegrid',color_codes=True)\n\n#model selection\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import accuracy_score,precision_score,recall_score,confusion_matrix,roc_curve,roc_auc_score\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn.preprocessing import LabelEncoder\n\n#preprocess.\nfrom keras.preprocessing.image import ImageDataGenerator\n\n#dl libraraies\nfrom keras import backend as K\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nfrom keras.optimizers import Adam,SGD,Adagrad,Adadelta,RMSprop\nfrom keras.utils import to_categorical\nfrom keras.callbacks import ReduceLROnPlateau\n\n# specifically for cnn\nfrom keras.layers import Dropout, Flatten,Activation\nfrom keras.layers import Conv2D, MaxPooling2D, BatchNormalization\n \nimport tensorflow as tf\nimport random as rn\n\n# specifically for manipulating zipped images and getting numpy arrays of pixel values of images.\nimport cv2                  \nimport numpy as np  \nfrom tqdm import tqdm\nimport os                   \nfrom random import shuffle  \nfrom zipfile import ZipFile\nfrom PIL import Image\n\n#TL pecific modules\nfrom keras.applications.vgg16 import VGG16","metadata":{"id":"z19bVm7o9zeu","_uuid":"4902ee7b7f4d66a42d59b971180bba213d0133c9","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nprint(os.listdir('../input/flowers-recognition/flowers/flowers'))","metadata":{"_uuid":"346f2fdc1b809eb19158d411af4288d83c79f389","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<a id=\"content2\"></a>\n## 2 ) Preparing the Data","metadata":{"_uuid":"1fa0f050be4d3796a3253bc22c0d87393d55902a"}},{"cell_type":"markdown","source":"## 2.1) Making the functions to get the training and validation set from the Images","metadata":{"_uuid":"192e68db5329da0e491aba8f12a6ca5cda534ce9"}},{"cell_type":"code","source":"X=[]\nZ=[]\nIMG_SIZE=150\nFLOWER_DAISY_DIR='../input/flowers-recognition/flowers/flowers/daisy'\nFLOWER_SUNFLOWER_DIR='../input/flowers-recognition/flowers/flowers/sunflower'\nFLOWER_TULIP_DIR='../input/flowers-recognition/flowers/flowers/tulip'\nFLOWER_DANDI_DIR='../input/flowers-recognition/flowers/flowers/dandelion'\nFLOWER_ROSE_DIR='../input/flowers-recognition/flowers/flowers/rose'\nweights_path='../input/trans-learn-weights/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'\n","metadata":{"id":"abZS8dPk9ze1","_uuid":"7b0c13e69deaf6449739ba2104bb6238be376f05","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def assign_label(img,flower_type):\n    return flower_type\n    ","metadata":{"id":"2qPgwo1d9ze4","_uuid":"1c467392d43ee29671c5498bd1feea5db5ef862d","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def make_train_data(flower_type,DIR):\n    for img in tqdm(os.listdir(DIR)):\n        label=assign_label(img,flower_type)\n        path = os.path.join(DIR,img)\n        img = cv2.imread(path,cv2.IMREAD_COLOR)\n        img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n        \n        X.append(np.array(img))\n        Z.append(str(label))\n        \n        \n        ","metadata":{"id":"vlY8PywM9ze7","_uuid":"861b4e251d97f7601a3bc2c3077183de4122e3d9","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"make_train_data('Daisy',FLOWER_DAISY_DIR)\nprint(len(X))","metadata":{"id":"9hn_RjL29ze_","outputId":"2644a55d-f469-44dc-d49b-d3bddfcfc401","_uuid":"04ee1723256e1836f56600bf041e67d1d8370314","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"make_train_data('Sunflower',FLOWER_SUNFLOWER_DIR)\nprint(len(X))","metadata":{"id":"6XZpRkLK9zfC","outputId":"eb5b40d1-6676-43d8-a470-f220bf4ced98","_uuid":"d4cd8f4d88756086d747d72cad465433c7e1e0ff","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"make_train_data('Tulip',FLOWER_TULIP_DIR)\nprint(len(X))","metadata":{"id":"YvJMmnNx9zfH","outputId":"fd0173f8-a1a6-4458-bec0-60f32159c0ea","_uuid":"9c86247c9d3651de45e3f6883df1453cf594b65b","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"make_train_data('Dandelion',FLOWER_DANDI_DIR)\nprint(len(X))","metadata":{"id":"KgYj8x-H9zfL","outputId":"0bc60c65-8d2d-416b-e4b7-05dc3306889f","_uuid":"0ff3f7e5d2aae2b06fe87a49cf89007833d5c83d","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"make_train_data('Rose',FLOWER_ROSE_DIR)\nprint(len(X))","metadata":{"id":"3mtQH6Vg9zfQ","outputId":"48d6fb59-7c40-4536-b9ca-5b71b9333a8d","_uuid":"8e6a148321afbfaa53dfc05a5d700c5a24fed336","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.2 ) Visualizing some Random Images","metadata":{"_uuid":"997bc5f5a06532e466cabe21ff7cf3fa482f7eb9"}},{"cell_type":"code","source":"fig,ax=plt.subplots(5,2)\nfig.set_size_inches(15,15)\nfor i in range(5):\n    for j in range (2):\n        l=rn.randint(0,len(Z))\n        ax[i,j].imshow(X[l])\n        ax[i,j].set_title('Flower: '+Z[l])\n        \nplt.tight_layout()\n        ","metadata":{"id":"gPolpADLYv9p","outputId":"fdce75db-8b63-466f-e1cf-0e92f191b029","_uuid":"8ad3563c162ea79510b967f9c2a53c0cd6fbc2d4","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.3 ) Label Encoding the Y array (i.e. Daisy->0, Rose->1 etc...) & then One Hot Encoding ","metadata":{"_uuid":"963b723dd10cb918fa045588a5dfa07d55007db3"}},{"cell_type":"code","source":"le=LabelEncoder()\nY=le.fit_transform(Z)\nY=to_categorical(Y,5)\nX=np.array(X)\nX=X/255","metadata":{"id":"_Gug0CHU9zfe","_uuid":"1f006ba66f46d8c3355ecdd3b27b37bdea635944","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.4 ) Splitting into Training and Validation Sets","metadata":{"_uuid":"d6a8f93a1446fa61e9c89a61be3a0fbb4328ad15"}},{"cell_type":"code","source":"x_train,x_test,y_train,y_test=train_test_split(X,Y,test_size=0.25,random_state=42)\n","metadata":{"id":"4xogXfvm9zfg","_uuid":"e9b04ed0a732e99941d6a347a14d66eb2cb4727b","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.5 ) Setting the Random Seeds","metadata":{"_uuid":"10556b8fcdde09321078b4fa4df9e9dc651f877a"}},{"cell_type":"code","source":"np.random.seed(42)\nrn.seed(42)\ntf.set_random_seed(42)","metadata":{"id":"S_nM3vLf9zfj","_uuid":"f0e2ae22e3bca8e3143d5b4d312460283b833878","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<a id=\"content3\"></a>\n## 3 ) Modelling","metadata":{"_uuid":"82aa7c88a3fac8f8596ce70653900664f2b61ad4"}},{"cell_type":"markdown","source":"## 3.1 ) Specifying the Base Model","metadata":{"_uuid":"550936cbbc153229adb624c2c31050c5d93c2a8e"}},{"cell_type":"markdown","source":"Transfer learning refers to using a pretrained model on some other task for your own task. Hence we need to specify the particular model which we are deploying in our task and thus needs to specify the base model.\n\nIn our case we are using the VGG16 model from the Keras.Applications library as the base model.","metadata":{"_uuid":"42730871d9f28580dab21b9e15c6b65c67e8a5e6"}},{"cell_type":"code","source":"base_model=VGG16(include_top=False, weights=None,input_shape=(150,150,3), pooling='avg')\n ","metadata":{"id":"SERVVhIgkxXV","_uuid":"33b31b3df570b37c968f4c4e81ea24b48c864caa","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model.load_weights(weights_path)","metadata":{"_uuid":"9155aceff9ad2d42cbd5b9151389d2f15e8c7abd","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### BREAKING IT DOWN--\n\n1) Firstly we import the VGG16 module from the Keras library.\n\n2) Next we need to specify if we want  to use the fully connected layers of the VGG16 module or own layers. Since our task is different and we have only 5 target classes we need to have our own layers and I have specified the 'include_top' arguement as 'False'.\n\n3) Next we need to specify the weights to be used by the model. Since I want it to use the weights it was trained on in ImageNet competition, I have loaded the weights from the corressponding file. You can directly specify the weights arguement as 'imagenet' in VGG16( )  but it didn't work in my case so I have to explicitily load the weghts from a file.\n \n4) Lastly we just need to specify the shape of the imput that our model need to expect and also specify the 'pooling' type.","metadata":{"_uuid":"0113e4773b50a6aa8434865fe1657d6859d25d71"}},{"cell_type":"code","source":"base_model.summary()","metadata":{"id":"xHOoktp-k4tw","outputId":"93071b24-7020-4978-d509-7b6d17debb7d","_uuid":"3bca9ce0ba74b4bec90b228d7805ce6d64e00062","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Note that this is NOT the summary of our model and this is the summary or the ARCHITECTURE of the VGG16 model that we are deploying as the base model.","metadata":{"_uuid":"33a8724542cdac2b9002fbbd3db0400ebedcac0d"}},{"cell_type":"markdown","source":"## 3.2 ) Adding our Own Fully Connected Layers","metadata":{"_uuid":"fe17a74b47da287a0b8763096d1e47beac1be85f"}},{"cell_type":"markdown","source":"Now we need to add at the top of the base model some fully connected layers. Alsowe can use the BatchNormalization and the Dropout layers as usual in case we want to.\n\nFor this I have used a Keras sequential model and build our entire model on top of it; comprising of the VGG model as the base model + our own fully connected layers.","metadata":{"_uuid":"c1285074e54048895fa46f28ce94327dcb1fd2a7"}},{"cell_type":"code","source":"model=Sequential()\nmodel.add(base_model)\n\nmodel.add(Dense(256,activation='relu'))\nmodel.add(Dense(5,activation='softmax'))\n\n\n","metadata":{"id":"gGgMscM_eIYS","_uuid":"61461000564043bcdd7dcafc2f99bf931eaecfa0","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 3.3 ) Data Augmentation to prevent Overfitting","metadata":{"_uuid":"3d14eeca7ad5f8e01a4d868a2dda5dc4111387fb"}},{"cell_type":"code","source":"datagen = ImageDataGenerator(\n        featurewise_center=False,  # set input mean to 0 over the dataset\n        samplewise_center=False,  # set each sample mean to 0\n        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n        samplewise_std_normalization=False,  # divide each input by its std\n        zca_whitening=False,  # apply ZCA whitening\n        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)\n        zoom_range = 0.1, # Randomly zoom image \n        width_shift_range=0.2,  # randomly shift images horizontally (fraction of total width)\n        height_shift_range=0.2,  # randomly shift images vertically (fraction of total height)\n        horizontal_flip=True,  # randomly flip images\n        vertical_flip=False)  # randomly flip images\n\n\ndatagen.fit(x_train)","metadata":{"id":"lH038cfsgkvZ","_uuid":"5859d726c293f373e7ee955bb931bd28f39db8d5","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 3.4 ) Using a Learning Rate Annealer & the Summary","metadata":{"_uuid":"fe28d78ca7d6f7af58b8bbaa6c4cf6a377f725b5"}},{"cell_type":"code","source":"epochs=50\nbatch_size=128\nred_lr=ReduceLROnPlateau(monitor='val_acc', factor=0.1, epsilon=0.0001, patience=2, verbose=1)","metadata":{"id":"B_6-fsX6gky4","_uuid":"0953cdcd6425381a3551aeb28af6c4b61654849d","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.summary()","metadata":{"id":"IVxD9F-TeIdi","outputId":"ce03edc5-3e80-4662-9039-ac0ebb285606","_uuid":"c18c97375cbdde67228b22780bff5a0230598c71","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"This is now the complete summary of our model that we shall use to classify the images.","metadata":{"_uuid":"9e930633508ea7464b06a0e6081f3d162537de46"}},{"cell_type":"markdown","source":"## 3.5 ) Compiling & Training the Model","metadata":{"_uuid":"5a36c2ecfbc0b8dc2407be3e685ce235e420a198"}},{"cell_type":"markdown","source":"#### 3.5.1 ) USING BASE MODEL AS A FEATURE EXTRACTOR.","metadata":{"_uuid":"73afda7629edabaed5ed8d2853c78b4f6f08aa61"}},{"cell_type":"markdown","source":"While using transfer learning in ConvNet; we have basically have 3 main approaches-->\n\n1) To use the pretrained model as a feature extractor and just train your classifier on top of it. In this method we do not tune any weights of the model.\n\n2) Fine Tuning- In this approach we tune the weights of the pretrained model. This can be done by unfreezing the layers that we want to train.In that case these layers will be initialised with their trained weights on imagenet.\n\n3) Lasty we can use a pretrained model.\n\nNote that in this section I have used the first approach ie I have just use the conv layers and added my own fully connected layers on top of VGG model. Thus I have trained a classifier on top of the CNN codes.","metadata":{"_uuid":"3a91c19dfbb62a2a063e1a946b7cf0489782c9be"}},{"cell_type":"code","source":"base_model.trainable=False # setting the VGG model to be untrainable.","metadata":{"id":"CqU7SQXzTNof","_uuid":"d2bc03ec5faf3e57a7504680d065a8ba30e403e3","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-4),loss='categorical_crossentropy',metrics=['accuracy'])\n\n","metadata":{"id":"Hx2arlHIeIhS","_uuid":"b5fc67aea4c22dec0cf54adc0d475a9aa49e3dc7","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"History = model.fit_generator(datagen.flow(x_train,y_train, batch_size=batch_size),\n                              epochs = 50, validation_data = (x_test,y_test),\n                              verbose = 1, steps_per_epoch=x_train.shape[0] // batch_size)","metadata":{"id":"cS9WpEjOeIjz","outputId":"3e114b06-c24c-4504-c590-c335fd8c7d2a","_uuid":"2dc473930156c22f817d91349cd3aa233e623d65","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 3.5.2 ) FINE TUNING BY UNFREEZING THE LAST BLOCK OF VGG16","metadata":{"_uuid":"7957e2a9e323de85d99f72cf1af44f078ccc5e11"}},{"cell_type":"markdown","source":"In this section I have done fine tuning. To see the effect of the fine tuning I have first unfreezed the last block of the VGG16 model and have set it to trainable.","metadata":{"_uuid":"0deafdf0a87be6b94cf8e34e4e69e0c525afd1b0"}},{"cell_type":"code","source":"for i in range (len(base_model.layers)):\n    print (i,base_model.layers[i])\n  \nfor layer in base_model.layers[15:]:\n    layer.trainable=True\nfor layer in base_model.layers[0:15]:\n    layer.trainable=False\n  ","metadata":{"id":"ZcwBRzYYPVx8","outputId":"b339aed4-c074-4139-9c55-653cd21709fa","_uuid":"1efcc1bd4b8c809998052b4edf9bfd72a7467ad9","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-4),loss='categorical_crossentropy',metrics=['accuracy'])\n\n","metadata":{"id":"U6-PRjikXAoK","_uuid":"67f268c689a28c44745f42658b1937d54ea2504c","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"History = model.fit_generator(datagen.flow(x_train,y_train, batch_size=batch_size),\n                              epochs = 50, validation_data = (x_test,y_test),\n                              verbose = 1, steps_per_epoch=x_train.shape[0] // batch_size)","metadata":{"id":"8HOQuHdyTfj9","outputId":"35be571e-cbde-4cd5-8384-38f6f30fa354","_uuid":"21fbf26cc0c2aab15e7c5903c2f92ef6a736c213","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Note that the validation accuracy on fine tuning by unfreezing the last block of the VGG16 model has increased to about 81% ; almost by 3% as compared to the case when we run a classifier on the top of the CNN codes in previous section.","metadata":{"_uuid":"9545f9161aa1643df2c00753121bb87b7a7c87d6"}},{"cell_type":"code","source":"plt.plot(History.history['acc'])\nplt.plot(History.history['val_acc'])\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epochs')\nplt.legend(['train', 'test'])\nplt.show()","metadata":{"id":"fhEnWLenslUN","outputId":"66ffc68f-fd74-4e91-886c-dce3801eae5a","_uuid":"131a4ba19320a3fde1e5a485cd1d77e2af48ae88","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(History.history['loss'])\nplt.plot(History.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epochs')\nplt.legend(['train', 'test'])\nplt.show()","metadata":{"id":"QYuLuLAQslnF","outputId":"a7134113-dbaf-4ad1-b4b3-0405d2497704","_uuid":"954611cab64452acf57fb7dd4c08c4ffc6e1812f","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 3.5.3) UNFREEZING THE LAST 2 BLOCKS","metadata":{"_uuid":"4f05de21b7a21287091274b00365d470f3acae3b"}},{"cell_type":"markdown","source":"Similarly unffreezing the last 2 blocks of the VGG16model.","metadata":{"_uuid":"1073c9b152e75cd68a88b4b224a409c0c7c60f0c"}},{"cell_type":"code","source":"for i in range (len(base_model.layers)):\n    print (i,base_model.layers[i])\n  \nfor layer in base_model.layers[11:]:\n    layer.trainable=True\nfor layer in base_model.layers[0:11]:\n    layer.trainable=False\n  ","metadata":{"id":"mPW6EdQ6zsVG","outputId":"9b3604e4-f4cf-4e52-cd05-27b821e264aa","_uuid":"9244d358ff5774c52799bd2009a9b27cce6ce00c","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-4),loss='categorical_crossentropy',metrics=['accuracy'])\n\n","metadata":{"id":"8r2vkhzxzri4","_uuid":"82a58b8e1b1a8bf539377e53d3e9129f9dfa838c","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"History = model.fit_generator(datagen.flow(x_train,y_train, batch_size=batch_size),\n                              epochs = 50, validation_data = (x_test,y_test),\n                              verbose = 1, steps_per_epoch=x_train.shape[0] // batch_size)","metadata":{"id":"Mu4-v7Tl0JnF","outputId":"9be6d8e4-5f91-4b85-ba4f-d85d719926e0","_uuid":"af35be1c41a5b83459a9ea7f1b544ec62fcee54f","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Note that there is still an increse in validation accuracy of about 1.5% and the same has now reached to about 81.5%.","metadata":{"_uuid":"2e2aed33b9f03da420eea3eaea02f2d19f8c78b7"}},{"cell_type":"code","source":"plt.plot(History.history['loss'])\nplt.plot(History.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epochs')\nplt.legend(['train', 'test'])\nplt.show()","metadata":{"id":"uVG9lwNqahjL","outputId":"c577edd1-d2ac-4bc9-8d1f-aac373f4b3de","_uuid":"e662853bfaf2f12c0bba1a311a5498d3eea618bc","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(History.history['acc'])\nplt.plot(History.history['val_acc'])\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epochs')\nplt.legend(['train', 'test'])\nplt.show()","metadata":{"id":"7_R7EV33ahsp","outputId":"a981a3d3-edcc-4b82-e9ec-b8d13b58260a","_uuid":"3a6beed19c34da7cbd224bc733b23bc81bc232ce","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 3.5.4 ) TRAINING THE ENTIRE MODEL FROM SCRATCH","metadata":{"_uuid":"4792c7b10230461e4bac5080185188bc29edddc2"}},{"cell_type":"markdown","source":"Finally I have tried to train the model from scratch. Note this is not reasonable though as our data is also not much similar with the imagenet data plus we are quite short of data as we only have around 4200 images.\n\nHence this model is quite prone to overfitting and I have done this just to check that the results validate with the though-process.","metadata":{"_uuid":"77ba60ecd1669bc44a948a71c282b15fe7443829"}},{"cell_type":"code","source":"model=Sequential()\nmodel.add(base_model)\n\nmodel.add(Dense(256,activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dense(5,activation='softmax'))\n\n\nfor layer in base_model.layers:\n    layer.trainable=True\n\nmodel.compile(optimizer=Adam(lr=1e-4),loss='categorical_crossentropy',metrics=['accuracy'])\n\n","metadata":{"id":"NoEsKBey0Yiw","_uuid":"764f67047b47d9f9c2fea3fad5630cc2fd60f377","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"History = model.fit_generator(datagen.flow(x_train,y_train, batch_size=batch_size),\n                              epochs = 50, validation_data = (x_test,y_test),\n                              verbose = 1, steps_per_epoch=x_train.shape[0] // batch_size)","metadata":{"id":"pFbqDROC0Zqv","outputId":"87f19382-2573-46bb-a430-20554b8b1496","_uuid":"adba788f8da8644c9e268bfe4063ecf8623e5e3b","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(History.history['acc'])\nplt.plot(History.history['val_acc'])\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epochs')\nplt.legend(['train', 'test'])\nplt.show()","metadata":{"id":"w44nLg9rZ7oY","outputId":"e15fbaaf-35ea-4e41-b7fb-772e26690979","_uuid":"9f55b5b6a11cb49117b92960ff7925a8a03b836e"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Note that the graphs as well as the results clearly show that there is significant overfitting. Also note that despite the overfitting the overall validartion accuracy has though increased from previous best of about 0.815 to a whopping 0.93.","metadata":{"_uuid":"f7abdc1be979a2e325c6dc2b2c4b5ef2b786d350"}},{"cell_type":"markdown","source":"<a id=\"content4\"></a>\n## 4 ) Visualizing Predictons on the Validation Set","metadata":{"_uuid":"f5e070bcec135a62ace22eecce508f6599459f3c"}},{"cell_type":"code","source":"# getting predictions on val set.\npred=model.predict(x_test)\npred_digits=np.argmax(pred,axis=1)","metadata":{"id":"7ozBQTvNeIxE","_uuid":"5e432418128f23165b56338b57be998da2e1d3a7"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# now storing some properly as well as misclassified indexes'.\ni=0\nprop_class=[]\nmis_class=[]\n\nfor i in range(len(y_test)):\n    if(np.argmax(y_test[i])==pred_digits[i]):\n        prop_class.append(i)\n    if(len(prop_class)==8):\n        break\n\ni=0\nfor i in range(len(y_test)):\n    if(not np.argmax(y_test[i])==pred_digits[i]):\n        mis_class.append(i)\n    if(len(mis_class)==8):\n        break","metadata":{"id":"2JouGgHHeI0f","_uuid":"c3e12af455fa0ef0ff5466c186a83e0a5489a2e9"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### CORRECTLY CLASSIFIED FLOWER IMAGES","metadata":{"_uuid":"5024d50471de5995166542ffa9580e7609431527"}},{"cell_type":"code","source":"warnings.filterwarnings('ignore')\n\ncount=0\nfig,ax=plt.subplots(4,2)\nfig.set_size_inches(15,15)\nfor i in range (4):\n    for j in range (2):\n        ax[i,j].imshow(x_test[prop_class[count]])\n        ax[i,j].set_title(\"Predicted Flower : \"+str(le.inverse_transform([pred_digits[prop_class[count]]]))+\"\\n\"+\"Actual Flower : \"+str(le.inverse_transform(np.argmax([y_test[prop_class[count]]]))))\n        plt.tight_layout()\n        count+=1","metadata":{"id":"HMJGc9SH8VFP","outputId":"39981dee-3baf-4a97-f7c1-df135b305cbf","_uuid":"61a5c64c0b8d5581d3acf6b35e7092ad36bb1d54"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### MISCLASSIFIED IMAGES OF FLOWERS","metadata":{"_uuid":"0775db9256a74c432b30c3410c8b6263aa9cc15f"}},{"cell_type":"code","source":"warnings.filterwarnings('always')\nwarnings.filterwarnings('ignore')\n\ncount=0\nfig,ax=plt.subplots(4,2)\nfig.set_size_inches(15,15)\nfor i in range (4):\n    for j in range (2):\n        ax[i,j].imshow(x_test[mis_class[count]])\n        ax[i,j].set_title(\"Predicted Flower : \"+str(le.inverse_transform([pred_digits[mis_class[count]]]))+\"\\n\"+\"Actual Flower : \"+str(le.inverse_transform(np.argmax([y_test[mis_class[count]]]))))\n        plt.tight_layout()\n        count+=1","metadata":{"id":"BpAAENzv8X7F","outputId":"44e0fbf2-6e6a-49bf-a462-0bd3c0e7d3e8","_uuid":"3b1783ea4d983c0426b18ea1d740d5f44ca43650"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"id":"5KnJJlkMNrpO","_uuid":"2845b3a1a171aa0d9398444037f355a22ea25b9e"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## THE END.","metadata":{"id":"PWwASowbba12","_uuid":"927a9385f09a0a24d15bb7c77155462a5fabaa8c"}},{"cell_type":"markdown","source":"## [ Please star/upvote if u like it. ]","metadata":{"_uuid":"9e3f20b1bcdba6df317b4327c330a92535185459"}},{"cell_type":"code","source":"","metadata":{"_uuid":"52eb4c22f88ffa062c479d1114ebb9c856eb14b6"},"outputs":[],"execution_count":null}]}