{"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":"import numpy as np\nimport pandas as pd\nimport os\nfrom pathlib import Path\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport random\n\n# keras\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization\nfrom keras.optimizers import Adam\nfrom keras.losses import SparseCategoricalCrossentropy\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# sklearn library\nfrom sklearn.preprocessing import StandardScaler \nfrom sklearn.model_selection import train_test_split \nfrom sklearn.metrics import classification_report ","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:11:59.139932Z","iopub.execute_input":"2021-06-18T18:11:59.140319Z","iopub.status.idle":"2021-06-18T18:12:04.700111Z","shell.execute_reply.started":"2021-06-18T18:11:59.140235Z","shell.execute_reply":"2021-06-18T18:12:04.699287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# unzipping data files\n\n! unzip \"../input/dogs-vs-cats-redux-kernels-edition/train.zip\" -d train\n! unzip \"../input/dogs-vs-cats-redux-kernels-edition/test.zip\" -d test","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:04.701571Z","iopub.execute_input":"2021-06-18T18:12:04.701920Z","iopub.status.idle":"2021-06-18T18:12:22.334788Z","shell.execute_reply.started":"2021-06-18T18:12:04.701874Z","shell.execute_reply":"2021-06-18T18:12:22.333795Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Pre-processig Data","metadata":{}},{"cell_type":"code","source":"# creating dataframe\n\n# labels\nfile = os.listdir(\"./train/train\")\nLabels = list(map(lambda x: x.split('.')[0], file))\n\n# for filenames\nf = Path(\"./train/train\")\nFile_Path = list(f.glob(r\"**/*.jpg\"))\n\n# dataframe\nFile_Path = pd.Series(File_Path).astype(str)\nLabels = pd.Series(Labels)\ndf = pd.concat([File_Path,Labels],axis=1)\ndf.columns = ['filename', 'category']","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:22.336655Z","iopub.execute_input":"2021-06-18T18:12:22.337038Z","iopub.status.idle":"2021-06-18T18:12:22.745488Z","shell.execute_reply.started":"2021-06-18T18:12:22.336992Z","shell.execute_reply":"2021-06-18T18:12:22.744663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:22.748666Z","iopub.execute_input":"2021-06-18T18:12:22.748924Z","iopub.status.idle":"2021-06-18T18:12:22.769067Z","shell.execute_reply.started":"2021-06-18T18:12:22.748899Z","shell.execute_reply":"2021-06-18T18:12:22.768162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ensuring data isn't biased\n\ndf['category'].value_counts().plot.bar(color=['green', 'orange']);","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:22.770648Z","iopub.execute_input":"2021-06-18T18:12:22.770991Z","iopub.status.idle":"2021-06-18T18:12:22.920720Z","shell.execute_reply.started":"2021-06-18T18:12:22.770956Z","shell.execute_reply":"2021-06-18T18:12:22.920014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Viewing dataframe images\n\nfig, axes = plt.subplots(nrows=3,ncols=3, figsize=(7, 7),\n                        subplot_kw={'xticks': [], 'yticks': []})\n\n# iterating over images\nfor name, ax, in enumerate(axes.flatten()):\n    ax.imshow(plt.imread(df.filename[name]))   # reading images\n    ax.set_title(df.category[name])            #labelling images\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:22.921799Z","iopub.execute_input":"2021-06-18T18:12:22.922118Z","iopub.status.idle":"2021-06-18T18:12:23.637643Z","shell.execute_reply.started":"2021-06-18T18:12:22.922092Z","shell.execute_reply":"2021-06-18T18:12:23.636727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# splitting the dataset\n# specified random state for split to give same output\n\ntrain_set, test_data = train_test_split(df, test_size= 0.2, random_state = 42)\ntrain_data, val_data = train_test_split(train_set, test_size= 0.2, random_state = 42)\n\n\nprint(train_data.shape)\nprint(test_data.shape)\nprint(val_data.shape)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:23.639415Z","iopub.execute_input":"2021-06-18T18:12:23.639805Z","iopub.status.idle":"2021-06-18T18:12:23.657894Z","shell.execute_reply.started":"2021-06-18T18:12:23.639759Z","shell.execute_reply":"2021-06-18T18:12:23.656692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# resetting index\n\ntrain_data = train_data.reset_index(drop=True)\ntest_data = test_data.reset_index(drop=True)\nval_data = val_data.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:23.659459Z","iopub.execute_input":"2021-06-18T18:12:23.659798Z","iopub.status.idle":"2021-06-18T18:12:23.665481Z","shell.execute_reply.started":"2021-06-18T18:12:23.659763Z","shell.execute_reply":"2021-06-18T18:12:23.664273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Augmentation and Generators","metadata":{}},{"cell_type":"code","source":"img_size = (128, 128)\ninput_shape = (128, 128, 3)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:23.667230Z","iopub.execute_input":"2021-06-18T18:12:23.667597Z","iopub.status.idle":"2021-06-18T18:12:23.678439Z","shell.execute_reply.started":"2021-06-18T18:12:23.667560Z","shell.execute_reply":"2021-06-18T18:12:23.677463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# image Generator\n\nimg_gen = ImageDataGenerator(    \n    rotation_range=10,\n    rescale=1./255,\n    horizontal_flip=True,\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:23.679753Z","iopub.execute_input":"2021-06-18T18:12:23.680238Z","iopub.status.idle":"2021-06-18T18:12:23.687555Z","shell.execute_reply.started":"2021-06-18T18:12:23.680174Z","shell.execute_reply":"2021-06-18T18:12:23.686677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# example generator\n\nexample_data = train_data.sample(n=1).reset_index(drop=True)\n\nexample_gen = img_gen.flow_from_dataframe(\n    dataframe = example_data,\n    x_col = 'filename', #name of the column containing the image in the test set\n    y_col ='category', #name of column containing the target in the test set\n    target_size = img_size,\n    class_mode ='categorical',\n    batch_size = 32,\n    shuffle = False # not to shuffle the given data\n)\n\nfor i in range(1, 10):\n    plt.subplot(3, 3, i)\n    for X_batch, Y_batch in example_gen:\n        image = X_batch[0]\n        plt.imshow(image)\n        plt.axis('Off')\n        break\n\nplt.tight_layout()  # for auto padding \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:24.966119Z","iopub.execute_input":"2021-06-18T18:12:24.966558Z","iopub.status.idle":"2021-06-18T18:12:25.505945Z","shell.execute_reply.started":"2021-06-18T18:12:24.966512Z","shell.execute_reply":"2021-06-18T18:12:25.505218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# training generator\ntrain_gen = img_gen.flow_from_dataframe(\n    train_data, \n    x_col='filename',\n    y_col='category',\n    target_size=img_size,\n    class_mode='categorical',\n    batch_size=32,\n    shuffle = False\n)\n\n# validation generator\nvalidation_gen = img_gen.flow_from_dataframe(\n    val_data, \n    x_col='filename',\n    y_col='category',\n    target_size=img_size,\n    class_mode='categorical',\n    batch_size=32,\n    shuffle = False\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:26.884404Z","iopub.execute_input":"2021-06-18T18:12:26.884807Z","iopub.status.idle":"2021-06-18T18:12:27.078274Z","shell.execute_reply.started":"2021-06-18T18:12:26.884773Z","shell.execute_reply":"2021-06-18T18:12:27.077317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CNN Model","metadata":{}},{"cell_type":"code","source":"# creating model\nmodel = Sequential()\n\n# Adding layers\n\n# input layer\nmodel.add(Conv2D(32, (3, 3), activation='relu', strides=(1, 1),input_shape=input_shape))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\n#flatten layer\nmodel.add(Flatten())\n\n# dense layers with dropout\nmodel.add(Dense(128, activation = 'relu'))\nmodel.add(Dropout(rate = 0.3))\nmodel.add(Dense(64, activation = 'relu'))\n\n#output layer\nmodel.add(Dense(2, activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:28.710429Z","iopub.execute_input":"2021-06-18T18:12:28.710773Z","iopub.status.idle":"2021-06-18T18:12:30.780066Z","shell.execute_reply.started":"2021-06-18T18:12:28.710732Z","shell.execute_reply":"2021-06-18T18:12:30.779257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creating model\nmodel = Sequential()\n\n# Adding layers\n\n# input layer\nmodel.add(Conv2D(32, (3, 3), activation='relu', strides=(1, 1),input_shape=input_shape))\n\nmodel.add(BatchNormalization())\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\n\n\nmodel.add(BatchNormalization())\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\n\nmodel.add(BatchNormalization())\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\n\nmodel.add(BatchNormalization())\n\nmodel.add(Dropout(0.5))\n# output layer\nmodel.add(Dense(2, activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:30.781501Z","iopub.execute_input":"2021-06-18T18:12:30.781850Z","iopub.status.idle":"2021-06-18T18:12:30.891504Z","shell.execute_reply.started":"2021-06-18T18:12:30.781803Z","shell.execute_reply":"2021-06-18T18:12:30.890747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:32.420499Z","iopub.execute_input":"2021-06-18T18:12:32.420822Z","iopub.status.idle":"2021-06-18T18:12:32.436980Z","shell.execute_reply.started":"2021-06-18T18:12:32.420791Z","shell.execute_reply":"2021-06-18T18:12:32.434450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile model\nmodel.compile(optimizer='adam',\n              loss=\"categorical_crossentropy\", \n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:34.967435Z","iopub.execute_input":"2021-06-18T18:12:34.967845Z","iopub.status.idle":"2021-06-18T18:12:34.994915Z","shell.execute_reply.started":"2021-06-18T18:12:34.967807Z","shell.execute_reply":"2021-06-18T18:12:34.993915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# preventing overfitting\n\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\n\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', \n                                            patience=2, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\n\nearlystop = EarlyStopping(patience=10)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:36.965788Z","iopub.execute_input":"2021-06-18T18:12:36.966116Z","iopub.status.idle":"2021-06-18T18:12:36.970347Z","shell.execute_reply.started":"2021-06-18T18:12:36.966083Z","shell.execute_reply":"2021-06-18T18:12:36.969534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fitting model\n\nhistory = model.fit(train_gen,\n                    validation_data = validation_gen,\n                    epochs = 20,\n                    verbose=1, #for animated bar during epoch\n                    callbacks = [earlystop, learning_rate_reduction])","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:12:39.607253Z","iopub.execute_input":"2021-06-18T18:12:39.607580Z","iopub.status.idle":"2021-06-18T18:50:42.606797Z","shell.execute_reply.started":"2021-06-18T18:12:39.607550Z","shell.execute_reply":"2021-06-18T18:50:42.605905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Evaluation","metadata":{}},{"cell_type":"code","source":"# Loss vs Accuracy\n\n#accuracy\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\n#loss\nloss = history.history['loss'] \nval_loss = history.history['val_loss']","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:50:42.609941Z","iopub.execute_input":"2021-06-18T18:50:42.610194Z","iopub.status.idle":"2021-06-18T18:50:42.616864Z","shell.execute_reply.started":"2021-06-18T18:50:42.610167Z","shell.execute_reply":"2021-06-18T18:50:42.616100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\n\n# visualising Accuracy \nplt.subplot(2, 1, 1)\n\nplt.plot(acc, label='Training Accuracy')\nplt.plot(val_acc, label='Validation Accuracy')\n\nplt.ylabel('Accuracy') \nplt.title('Training and Validation Accuracy') \n\n# Visualising Loss\nplt.subplot(2, 1, 2)\n\nplt.plot(loss, label='Training Loss')\nplt.plot(val_loss, label='Validation Loss')\n\nplt.ylabel('Loss')\nplt.title('Training and Validation Loss')\n\nlegend = plt.legend()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:50:42.618967Z","iopub.execute_input":"2021-06-18T18:50:42.619449Z","iopub.status.idle":"2021-06-18T18:50:42.928419Z","shell.execute_reply.started":"2021-06-18T18:50:42.619413Z","shell.execute_reply":"2021-06-18T18:50:42.927301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# checking accuracy on the test data we left aside\n\ntest_gen = img_gen.flow_from_dataframe(\n    test_data, \n    x_col='filename',\n    y_col='category',\n    target_size=img_size,\n    class_mode='categorical',\n    batch_size=32,\n    shuffle = False\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:50:42.930496Z","iopub.execute_input":"2021-06-18T18:50:42.930885Z","iopub.status.idle":"2021-06-18T18:50:43.022480Z","shell.execute_reply.started":"2021-06-18T18:50:42.930844Z","shell.execute_reply":"2021-06-18T18:50:43.021089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict the label of the test_images\npred = model.predict(test_gen)\npred = np.argmax(pred,axis = 1) # pick the class with highest probability\n\n# labelling data\nlabels = (train_gen.class_indices)\nlabels = dict((v,k) for k,v in labels.items())\npred2 = [labels[k] for k in pred]\n\n# expected output\ny_test = test_data.category\n\n# model accuracy\nprint(classification_report(y_test, pred2))","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:50:43.026367Z","iopub.execute_input":"2021-06-18T18:50:43.026740Z","iopub.status.idle":"2021-06-18T18:51:08.579790Z","shell.execute_reply.started":"2021-06-18T18:50:43.026700Z","shell.execute_reply":"2021-06-18T18:51:08.578892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Display 15 picture of the dataset with their labels --> EXTRAS\n\nfig, axes = plt.subplots(nrows=3, ncols=5, figsize=(15, 10),\n                        subplot_kw={'xticks': [], 'yticks': []})\n\ncolor = \"blue\" if pred2[i] == test_data.category.iloc[i] else \"red\"\nfor i, ax ,in enumerate(axes.flat):\n    ax.imshow(plt.imread(test_data.filename.iloc[i]))\n    ax.set_title(f\"True: {test_data.category.iloc[i]}\\nPredicted: {pred2[i]}\",color=color)\n    \nplt.subplots_adjust(hspace = 0.3)\nplt.suptitle(\"Model predictions (blue: correct, red: incorrect)\",y=0.98)\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:51:08.581015Z","iopub.execute_input":"2021-06-18T18:51:08.581528Z","iopub.status.idle":"2021-06-18T18:51:09.720827Z","shell.execute_reply.started":"2021-06-18T18:51:08.581489Z","shell.execute_reply":"2021-06-18T18:51:09.719964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"test_filenames = os.listdir(\"./test/test\")\ntest_df = pd.DataFrame({\n    'filename': test_filenames\n})","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:51:09.721924Z","iopub.execute_input":"2021-06-18T18:51:09.722344Z","iopub.status.idle":"2021-06-18T18:51:09.739173Z","shell.execute_reply.started":"2021-06-18T18:51:09.722310Z","shell.execute_reply":"2021-06-18T18:51:09.738512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# checking accuracy on the test data we left aside\n\ntest_gen = img_gen.flow_from_dataframe(\n    test_df, \n    \"./test/test\",\n    x_col='filename',\n    y_col=None,\n    target_size=img_size,\n    class_mode=None,\n    batch_size=32,\n    shuffle = False # not to shuffle the given data\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:51:09.740994Z","iopub.execute_input":"2021-06-18T18:51:09.741429Z","iopub.status.idle":"2021-06-18T18:51:09.856417Z","shell.execute_reply.started":"2021-06-18T18:51:09.741395Z","shell.execute_reply":"2021-06-18T18:51:09.855455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict the label of the test_images\npred = model.predict(test_gen)\npred = np.argmax(pred,axis = 1) # pick the class with highest probability\n\n# labelling data\nlabels = (train_gen.class_indices)\nlabels = dict((v,k) for k,v in labels.items())\npred2 = [labels[k] for k in pred]","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:51:09.858157Z","iopub.execute_input":"2021-06-18T18:51:09.858592Z","iopub.status.idle":"2021-06-18T18:52:13.117655Z","shell.execute_reply.started":"2021-06-18T18:51:09.858552Z","shell.execute_reply":"2021-06-18T18:52:13.116742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label = np.zeros(len(pred2), dtype='int')\n\npred2 = np.array(pred2)\npred2=='cat'\n\nlabel[pred2=='cat']= 0\nlabel[pred2=='dog']= 1","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:52:13.121154Z","iopub.execute_input":"2021-06-18T18:52:13.121436Z","iopub.status.idle":"2021-06-18T18:52:13.128894Z","shell.execute_reply.started":"2021-06-18T18:52:13.121408Z","shell.execute_reply":"2021-06-18T18:52:13.128067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label = pd.Series(label)\nind = np.arange(1, len(pred2)+1)\nmy_submission = pd.DataFrame({'id':ind, 'label':label})\nmy_submission","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:53:41.057675Z","iopub.execute_input":"2021-06-18T18:53:41.058008Z","iopub.status.idle":"2021-06-18T18:53:41.074394Z","shell.execute_reply.started":"2021-06-18T18:53:41.057976Z","shell.execute_reply":"2021-06-18T18:53:41.073472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:53:44.573296Z","iopub.execute_input":"2021-06-18T18:53:44.573625Z","iopub.status.idle":"2021-06-18T18:53:44.816506Z","shell.execute_reply.started":"2021-06-18T18:53:44.573595Z","shell.execute_reply":"2021-06-18T18:53:44.815686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Refresh the contents of the output directory '/kaggle/working' to find the csv file******","metadata":{}}]}