{"cells":[{"metadata":{},"cell_type":"markdown","source":"In [Cats vs Dogs 1 | Learning from scratch](https://www.kaggle.com/sejalkshirsagar/cats-vs-dogs-1-learning-from-scratch) notebook we explored training data, built CNN Model and trained it from scratch. In this notebook we will be implementing Transfer Learning using the pretrained model InceptionV3.\n# 1. Importing Libraries"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport zipfile\nimport numpy as np \nimport pandas as pd\nimport seaborn as sns\n\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix\n\nimport tensorflow as tf\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import Model\nfrom tensorflow.keras.optimizers import RMSprop\nfrom tensorflow.keras.applications.inception_v3 import InceptionV3\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"np.random.seed(9)\ntf.random.set_seed(9)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. Loading Pretrained Model\nWhile working in Kaggle kernel, to add any Keras Pretrained Models data click on the kernel's Data tab, search and add it."},{"metadata":{"trusted":true},"cell_type":"code","source":"for dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's instantiate our pretrained model. By setting include_top to False we are ignoring the fully connected layer at the top of Inception V3 so that we straightly get to convolutional layers."},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_file = '/kaggle/input/inceptionv3/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'\n\npre_trained_model = InceptionV3(input_shape = (150, 150, 3), \n                                include_top = False, \n                                weights = None)\n\npre_trained_model.load_weights(weights_file)\n#pre_trained_model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We take the layers from the existing model, and freeze/lock (by setting layer.trainable = False) the already learned convolutions into our model so that their weight don't get updated while training. "},{"metadata":{"trusted":true},"cell_type":"code","source":"for layer in pre_trained_model.layers:\n    layer.trainable = False\n\nlast_layer = pre_trained_model.get_layer('mixed7')\nprint('last layer output shape: ', last_layer.output_shape)\nlast_output = last_layer.output","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. Extracting Training Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"with zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\"../kaggle/working/train_unzip\")\n    \nprint(f\"We have total {len(os.listdir('../kaggle/working/train_unzip/train'))} images in our training data.\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filenames = os.listdir('../kaggle/working/train_unzip/train')\nlabels = [str(fname)[:3] for fname in filenames]\ntrain_df = pd.DataFrame({'filename': filenames, 'label': labels})\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print((train_df['label']).value_counts())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4. Splitting Training Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_set_df, dev_set_df = train_test_split(train_df[['filename', 'label']], test_size=0.3, random_state = 42, shuffle=True, stratify=train_df['label'])\nprint(train_set_df.shape, dev_set_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Training Set image counts:')\nprint(train_set_df['label'].value_counts())\nprint('Validation Set image counts:')\nprint(dev_set_df['label'].value_counts())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. Image Augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale = 1./255.,\n                                   rotation_range = 40,\n                                   width_shift_range = 0.2,\n                                   height_shift_range = 0.2,\n                                   shear_range = 0.2,\n                                   zoom_range = 0.2,\n                                   horizontal_flip = True)\n\nvalidation_datagen  = ImageDataGenerator( rescale = 1.0/255 )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(\n    train_set_df, \n    directory=\"../kaggle/working/train_unzip/train/\", \n    x_col='filename',\n    y_col='label',\n    target_size=(150, 150),\n    class_mode='binary',\n    batch_size=32,\n    validate_filenames=False \n)\n\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    dev_set_df, \n    directory=\"../kaggle/working/train_unzip/train/\", \n    x_col='filename',\n    y_col='label',\n    target_size=(150, 150),\n    class_mode='binary',\n    batch_size=32,\n    validate_filenames=False \n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 6. Adding DNN\nNow we'll need to add our own DNN at the bottom of pretrained layers, which we can retrain to our data."},{"metadata":{"trusted":true},"cell_type":"code","source":"x = layers.Flatten()(last_output)\nx = layers.Dense(1024, activation='relu')(x)\nx = layers.Dropout(0.2)(x)                  \nx = layers.Dense  (1, activation='sigmoid')(x)           \n\nmodel = Model( pre_trained_model.input, x ) \n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer = RMSprop(lr=0.0001), \n              loss = 'binary_crossentropy', \n              metrics = ['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 7. Model Fitting"},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(\n            train_generator,\n            validation_data = validation_generator,\n            steps_per_epoch = 100,\n            epochs = 20,\n            validation_steps = 50)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 8. Accuracy and Loss Curves"},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs   = range(len(acc))\n\nplt.plot(epochs, acc, label=\"Training accuracy\")\nplt.plot(epochs, val_acc, label=\"Validation accuracy\")\nplt.title('Training and validation accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(epochs, loss, label=\"Training loss\")\nplt.plot(epochs, val_loss, label=\"Validation loss\")\nplt.title('Training and validation loss')\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 9. Model Evaluation"},{"metadata":{"trusted":true},"cell_type":"code","source":"loss, accuracy = model.evaluate_generator(validation_generator)\nprint(\"Test: accuracy = %f  ;  loss = %f \" % (accuracy, loss))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dev_true = dev_set_df['label'].map({'dog': 1, \"cat\": 0})\ndev_predictions =  model.predict_generator(validation_generator)\ndev_set_df['pred'] = np.where(dev_predictions>0.5, 1, 0)\ndev_pred = dev_set_df['pred']\ndev_set_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dev_set_predictions_plot = dev_set_df['pred'].value_counts().plot.bar(title='Predicted number of Dog vs Cat Images in dev set')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"confusion_mtx = confusion_matrix(dev_true, dev_pred) \n\nf,ax = plt.subplots(figsize=(8, 8))\nsns.heatmap(confusion_mtx, annot=True, linewidths=0.01,cmap=\"Blues\",linecolor=\"gray\", fmt= '.1f',ax=ax)\nplt.xlabel(\"Predicted Label\")\nplt.ylabel(\"True Label\")\nplt.title(\"Confusion Matrix\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 8. Predictions and Submission File\nWe first extract test data from test1.zip"},{"metadata":{"trusted":true},"cell_type":"code","source":"with zipfile.ZipFile(\"../input/dogs-vs-cats/test1.zip\",\"r\") as z:\n    z.extractall(\"../kaggle/working/test1_unzip\")\n    \nprint(f\"We have total {len(os.listdir('../kaggle/working/test1_unzip/test1'))} images in our test1.zip\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_filenames = os.listdir('../kaggle/working/test1_unzip/test1')\ntest_df = pd.DataFrame({'filename': test_filenames})\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator = validation_datagen.flow_from_dataframe(\n    test_df, \n    directory=\"../kaggle/working/test1_unzip/test1/\", \n    x_col='filename',\n    y_col=None,\n    target_size=(150, 150),\n    class_mode=None,\n    batch_size=32,\n    validate_filenames=False \n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Making predictions on test data:"},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = model.predict_generator(test_generator, steps=np.ceil(len(test_filenames)/32))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df['id'] = test_df['filename'].str.split('.').str[0]\ntest_df['label'] = np.where(predictions>0.5, 1, 0)\nresult_df = test_df[['id','label']]\nresult_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set_predictions_plot = dev_set_df['pred'].value_counts().plot.bar(title='Predicted number of Dog vs Cat Images in test set')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Saving results in cats_vs_dogs.csv file:"},{"metadata":{"trusted":true},"cell_type":"code","source":"result_df.to_csv(\"cats_vs_dogs.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"And finally let's look at some predictions made by our model:"},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_test = test_df.sample(n=9)\n\nplt.figure(figsize=(12, 12))\nlabels ={0:'cat', 1:'dog'}\nfor i, row in sample_test.reset_index(drop=True).iterrows():\n    filename = row['filename']\n    category = labels[row['label']]\n    img = load_img(\"../kaggle/working/test1_unzip/test1/\"+filename, target_size=(150, 150))\n    plt.subplot(3, 3, i+1)\n    plt.imshow(img)   \n    plt.xlabel('(' + \"{}\".format(category) + ')')\n \n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}