{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom keras.models import Sequential\nfrom keras.preprocessing.image import load_img\n\nfrom keras_preprocessing.image import ImageDataGenerator\n\nfrom keras.callbacks import EarlyStopping\nfrom keras.layers import Dense, Activation, Flatten, Dropout, BatchNormalization\nfrom keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D, Lambda, Input\nfrom tensorflow.keras.models import Model\nfrom keras import regularizers, optimizers\nfrom keras.utils import to_categorical\nimport pandas as pd\nimport numpy as np\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nimport gc\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-25T09:22:40.706662Z","iopub.execute_input":"2021-06-25T09:22:40.707042Z","iopub.status.idle":"2021-06-25T09:22:47.422618Z","shell.execute_reply.started":"2021-06-25T09:22:40.706933Z","shell.execute_reply":"2021-06-25T09:22:47.421536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Step 1 - Data Preprocessing","metadata":{}},{"cell_type":"code","source":"traindf=pd.read_csv('../input/dog-breed-identification/labels.csv',dtype=str)\ntestdf=pd.read_csv(\"../input/dog-breed-identification/sample_submission.csv\",dtype=str)","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:22:47.424360Z","iopub.execute_input":"2021-06-25T09:22:47.424818Z","iopub.status.idle":"2021-06-25T09:22:48.068783Z","shell.execute_reply.started":"2021-06-25T09:22:47.424762Z","shell.execute_reply":"2021-06-25T09:22:48.067726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def append_ext(fn):\n    return fn+\".jpg\"\n\ntraindf[\"id\"]=traindf[\"id\"].apply(append_ext)\ntestdf[\"id\"]=testdf[\"id\"].apply(append_ext)","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:22:48.070929Z","iopub.execute_input":"2021-06-25T09:22:48.071333Z","iopub.status.idle":"2021-06-25T09:22:48.093820Z","shell.execute_reply.started":"2021-06-25T09:22:48.071283Z","shell.execute_reply":"2021-06-25T09:22:48.091851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"traindf.head(5)","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:22:48.096101Z","iopub.execute_input":"2021-06-25T09:22:48.096594Z","iopub.status.idle":"2021-06-25T09:22:48.119866Z","shell.execute_reply.started":"2021-06-25T09:22:48.096551Z","shell.execute_reply":"2021-06-25T09:22:48.118410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Create list of alphabetically sorted labels.\nclasses = sorted(list(set(traindf['breed'])))\nn_classes = len(classes)\nprint('Total unique breed {}'.format(n_classes))\n\n#Map each label string to an integer label.\nclass_to_num = dict(zip(classes, range(n_classes)))\nclass_to_num","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:22:48.121789Z","iopub.execute_input":"2021-06-25T09:22:48.122240Z","iopub.status.idle":"2021-06-25T09:22:48.141792Z","shell.execute_reply.started":"2021-06-25T09:22:48.122198Z","shell.execute_reply":"2021-06-25T09:22:48.140171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (331,331,3)\n\n# Transform image to matrice\ndef images_to_array(directory, label_dataframe, target_size = input_shape):\n    \n    image_labels = label_dataframe['breed']\n    images = np.zeros([len(label_dataframe), target_size[0], target_size[1], target_size[2]],dtype=np.uint8) #as we have huge data and limited ram memory. uint8 takes less memory\n    y = np.zeros([len(label_dataframe),1],dtype = np.uint8)\n    \n    for ix, image_name in enumerate(tqdm(label_dataframe['id'].values)):\n        img_dir = os.path.join(directory, image_name)\n        img = load_img(img_dir, target_size = target_size)\n        images[ix]=img\n        del img\n        \n        dog_breed = image_labels[ix]\n        y[ix] = class_to_num[dog_breed]\n    \n    y = to_categorical(y)\n    \n    return images,y\n\nX,y = images_to_array('/kaggle/input/dog-breed-identification/train', traindf[:])","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:22:48.143855Z","iopub.execute_input":"2021-06-25T09:22:48.144339Z","iopub.status.idle":"2021-06-25T09:24:50.275465Z","shell.execute_reply.started":"2021-06-25T09:22:48.144262Z","shell.execute_reply":"2021-06-25T09:24:50.274414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = 0)","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:24:50.276910Z","iopub.execute_input":"2021-06-25T09:24:50.277289Z","iopub.status.idle":"2021-06-25T09:24:51.763450Z","shell.execute_reply.started":"2021-06-25T09:24:50.277247Z","shell.execute_reply":"2021-06-25T09:24:51.762413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del X,y #to free up some ram memory\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:24:51.766478Z","iopub.execute_input":"2021-06-25T09:24:51.766765Z","iopub.status.idle":"2021-06-25T09:24:52.076209Z","shell.execute_reply.started":"2021-06-25T09:24:51.766735Z","shell.execute_reply":"2021-06-25T09:24:52.075153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Step 2 - Transfer learning using InceptionV3","metadata":{"execution":{"iopub.status.busy":"2021-06-16T11:37:45.84131Z","iopub.execute_input":"2021-06-16T11:37:45.84178Z","iopub.status.idle":"2021-06-16T11:37:45.846364Z","shell.execute_reply.started":"2021-06-16T11:37:45.84169Z","shell.execute_reply":"2021-06-16T11:37:45.845302Z"}}},{"cell_type":"code","source":"from keras.applications.inception_v3 import InceptionV3, preprocess_input\nfrom keras.layers.experimental import preprocessing\n\nmodel1 = InceptionV3(weights='imagenet', include_top=False)\n\nfor layer in model1.layers:\n    layer.trainable = False\n    \ninputs = Input(shape=(331,331,3))\n\nmodel_in = Lambda(preprocess_input)(inputs) # normalize image according to InceptionV3 preprocess input \n\n# Apply some modifications to images present in dataset\nmodel_in = preprocessing.RandomFlip('horizontal')(model_in)\nmodel_in = preprocessing.RandomContrast(0.5)(model_in)\n\nmodel1_out = model1(model_in)\nmodel1_out= GlobalAveragePooling2D()(model1_out)\n\nx = Dropout(0.7)(model1_out)\n\nx = Dense(n_classes, activation='softmax')(x)\n\nmodel = Model(inputs=inputs,outputs=x)","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:28:47.828326Z","iopub.execute_input":"2021-06-25T09:28:47.828680Z","iopub.status.idle":"2021-06-25T09:28:51.256922Z","shell.execute_reply.started":"2021-06-25T09:28:47.828651Z","shell.execute_reply":"2021-06-25T09:28:51.255668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer = 'adam', loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:28:54.096243Z","iopub.execute_input":"2021-06-25T09:28:54.096684Z","iopub.status.idle":"2021-06-25T09:28:54.120531Z","shell.execute_reply.started":"2021-06-25T09:28:54.096628Z","shell.execute_reply":"2021-06-25T09:28:54.119178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EarlyStop = EarlyStopping(monitor='val_loss', patience = 3, restore_best_weights=True)\n\nhistory = model.fit(X_train,y_train,\n            validation_split=0.2,\n            batch_size = 32,\n            epochs=10,\n            callbacks=[EarlyStop])","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:28:56.751708Z","iopub.execute_input":"2021-06-25T09:28:56.752133Z","iopub.status.idle":"2021-06-25T09:32:59.301809Z","shell.execute_reply.started":"2021-06-25T09:28:56.752102Z","shell.execute_reply":"2021-06-25T09:32:59.300654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plot accuracy and loss performance\n\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nplt.figure(figsize=(8, 8))\nplt.subplot(2, 1, 1)\nplt.plot(acc, label='Training Accuracy')\nplt.plot(val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.ylabel('Accuracy')\nplt.ylim([min(plt.ylim()),1])\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(2, 1, 2)\nplt.plot(loss, label='Training Loss')\nplt.plot(val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.ylabel('Cross Entropy')\nplt.ylim([0,1.0])\nplt.title('Training and Validation Loss')\nplt.xlabel('epoch')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:33:00.507522Z","iopub.execute_input":"2021-06-25T09:33:00.507898Z","iopub.status.idle":"2021-06-25T09:33:00.848685Z","shell.execute_reply.started":"2021-06-25T09:33:00.507865Z","shell.execute_reply":"2021-06-25T09:33:00.847574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Step 3 - Confusion Matrix","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\n\ny_pred = model.predict(X_test)\ny_pred = np.argmax(y_pred, axis=1)\ny_test = np.argmax(y_test, axis=1)\n\ncm = confusion_matrix(y_test, y_pred)","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:33:05.656328Z","iopub.execute_input":"2021-06-25T09:33:05.656674Z","iopub.status.idle":"2021-06-25T09:33:13.115745Z","shell.execute_reply.started":"2021-06-25T09:33:05.656645Z","shell.execute_reply":"2021-06-25T09:33:13.114569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,20))\nsns.heatmap(cm, fmt=\"d\", xticklabels = classes, yticklabels = classes, annot = True, cmap='Blues', cbar=False)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:33:16.700167Z","iopub.execute_input":"2021-06-25T09:33:16.700794Z","iopub.status.idle":"2021-06-25T09:34:13.202745Z","shell.execute_reply.started":"2021-06-25T09:33:16.700740Z","shell.execute_reply":"2021-06-25T09:34:13.201675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Step 4 - Make predictions with custom images","metadata":{"execution":{"iopub.status.busy":"2021-06-16T11:38:42.073965Z","iopub.execute_input":"2021-06-16T11:38:42.074307Z","iopub.status.idle":"2021-06-16T11:38:42.078808Z","shell.execute_reply.started":"2021-06-16T11:38:42.074273Z","shell.execute_reply":"2021-06-16T11:38:42.077882Z"}}},{"cell_type":"code","source":"#Custom input\n\nfrom IPython.display import display, Image\n\ndef import_image(image_path, target_size = (331,331,3)):\n    display(Image(image_path))\n    \n    #reading the image and converting it into an np array\n    img_g = load_img(image_path,target_size = target_size)\n    img_g = np.expand_dims(img_g, axis=0) # as we trained our model in (row, img_height, img_width, img_rgb) format, np.expand_dims convert the image into this format\n    # img_g\n    \n    prediction = model.predict(img_g)\n\n    print(f\"Max value (probability of prediction): {np.max(prediction[0])}\") # the max probability value predicted by the model\n    print(f\"Max index: {np.argmax(prediction[0])}\") # the index of where the max value in predictions[0] occurs\n    print(f\"Predicted label: {classes[np.argmax(prediction[0])]}\")","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:34:24.828974Z","iopub.execute_input":"2021-06-25T09:34:24.829386Z","iopub.status.idle":"2021-06-25T09:34:24.837216Z","shell.execute_reply.started":"2021-06-25T09:34:24.829335Z","shell.execute_reply":"2021-06-25T09:34:24.835496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import_image('../input/dog-breed-identification/test/000621fb3cbb32d8935728e48679680e.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-06-25T09:34:27.560059Z","iopub.execute_input":"2021-06-25T09:34:27.560404Z","iopub.status.idle":"2021-06-25T09:34:27.957543Z","shell.execute_reply.started":"2021-06-25T09:34:27.560366Z","shell.execute_reply":"2021-06-25T09:34:27.956495Z"},"trusted":true},"execution_count":null,"outputs":[]}]}