{"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":"# Import library","metadata":{}},{"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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-14T01:27:39.328906Z","iopub.execute_input":"2022-03-14T01:27:39.329619Z","iopub.status.idle":"2022-03-14T01:27:47.673179Z","shell.execute_reply.started":"2022-03-14T01:27:39.329488Z","shell.execute_reply":"2022-03-14T01:27:47.672148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nprint(os.listdir(\"../input/dog-vs-cat-classification\"))","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:27:50.643502Z","iopub.execute_input":"2022-03-14T01:27:50.64382Z","iopub.status.idle":"2022-03-14T01:27:50.649767Z","shell.execute_reply.started":"2022-03-14T01:27:50.643769Z","shell.execute_reply":"2022-03-14T01:27:50.649128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define contants","metadata":{}},{"cell_type":"code","source":"IMG_WID = 456\nIMG_HEI = 456\nIMG_SIZE = (IMG_WID, IMG_HEI)\nIMG_CHANNELS = 3","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:27:54.380059Z","iopub.execute_input":"2022-03-14T01:27:54.380485Z","iopub.status.idle":"2022-03-14T01:27:54.38475Z","shell.execute_reply.started":"2022-03-14T01:27:54.380451Z","shell.execute_reply":"2022-03-14T01:27:54.383697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare Training (detect data to DataFrame)","metadata":{}},{"cell_type":"markdown","source":"### Read folder dogs","metadata":{}},{"cell_type":"code","source":"filenames_dogs = os.listdir(\"../input/dog-vs-cat-classification/train/train/dogs\")\ncategories = ['1'] * len(filenames_dogs)\n\ndf_dog = pd.DataFrame({\n    'filename': filenames_dogs,\n    'category': categories\n}\n)\n\nfilenames_cats = os.listdir(\"../input/dog-vs-cat-classification/train/train/cats\")\ncategories = ['0'] * len(filenames_cats)\n\ndf_cat = pd.DataFrame({\n    'filename': filenames_cats,\n    'category': categories\n}\n)\ndf = pd.concat([df_dog, df_cat])\ndf = df.sample(frac=1).reset_index(drop=True)\n\nfilenames = list(df['filename'])","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:27:56.431517Z","iopub.execute_input":"2022-03-14T01:27:56.432551Z","iopub.status.idle":"2022-03-14T01:27:57.057982Z","shell.execute_reply.started":"2022-03-14T01:27:56.432507Z","shell.execute_reply":"2022-03-14T01:27:57.056857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:27:59.435693Z","iopub.execute_input":"2022-03-14T01:27:59.435993Z","iopub.status.idle":"2022-03-14T01:27:59.455225Z","shell.execute_reply.started":"2022-03-14T01:27:59.435964Z","shell.execute_reply":"2022-03-14T01:27:59.454038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.tail()","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:28:01.167675Z","iopub.execute_input":"2022-03-14T01:28:01.16828Z","iopub.status.idle":"2022-03-14T01:28:01.178414Z","shell.execute_reply.started":"2022-03-14T01:28:01.168242Z","shell.execute_reply":"2022-03-14T01:28:01.177313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['category'].value_counts().plot.bar();","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:28:03.099275Z","iopub.execute_input":"2022-03-14T01:28:03.09974Z","iopub.status.idle":"2022-03-14T01:28:03.291842Z","shell.execute_reply.started":"2022-03-14T01:28:03.099701Z","shell.execute_reply":"2022-03-14T01:28:03.290931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have 12500 dogs and 12500 cats","metadata":{}},{"cell_type":"markdown","source":"### See sample img","metadata":{}},{"cell_type":"code","source":"import random\nsample_name = random.choice(filenames)\nif sample_name.split('.')[0] == 'dog':\n    img = load_img(\"../input/dog-vs-cat-classification/train/train/dogs/\" + sample_name)\nelse: \n    img = load_img(\"../input/dog-vs-cat-classification/train/train/cats/\" + sample_name)\n\nplt.imshow(img);","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:28:05.312572Z","iopub.execute_input":"2022-03-14T01:28:05.312879Z","iopub.status.idle":"2022-03-14T01:28:05.617521Z","shell.execute_reply.started":"2022-03-14T01:28:05.312845Z","shell.execute_reply":"2022-03-14T01:28:05.616839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Traning data generator","metadata":{}},{"cell_type":"code","source":"train_df, valid_df = train_test_split(df, test_size=0.20, random_state=42)\ntrain_df = train_df.reset_index(drop=True)\nvalid_df = valid_df.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:28:10.835586Z","iopub.execute_input":"2022-03-14T01:28:10.836396Z","iopub.status.idle":"2022-03-14T01:28:10.846236Z","shell.execute_reply.started":"2022-03-14T01:28:10.836345Z","shell.execute_reply":"2022-03-14T01:28:10.845229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['category'].value_counts().plot.bar();","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:28:12.595829Z","iopub.execute_input":"2022-03-14T01:28:12.596127Z","iopub.status.idle":"2022-03-14T01:28:12.788579Z","shell.execute_reply.started":"2022-03-14T01:28:12.596098Z","shell.execute_reply":"2022-03-14T01:28:12.78762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Combine two folder cats and dogs to generate training set ","metadata":{}},{"cell_type":"code","source":"from distutils.dir_util import copy_tree\n\nfromDirectory = '../input/dog-vs-cat-classification/train/train/dogs'\ntoDirectory = 'temp'\ncopy_tree(fromDirectory, toDirectory)\n\nfromDirectory = '../input/dog-vs-cat-classification/train/train/cats'\ntoDirectory = 'temp'\ncopy_tree(fromDirectory, toDirectory)","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:28:14.699618Z","iopub.execute_input":"2022-03-14T01:28:14.699926Z","iopub.status.idle":"2022-03-14T01:30:11.863323Z","shell.execute_reply.started":"2022-03-14T01:28:14.699895Z","shell.execute_reply":"2022-03-14T01:30:11.862472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training data generator\ntrain_data_generator = ImageDataGenerator(rotation_range=15,\n    rescale=1./255,\n    shear_range=0.1,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\ntrain_generator = train_data_generator.flow_from_dataframe(\n    train_df,\n    \"temp\",\n    x_col='filename',\n    y_col='category',\n    target_size=IMG_SIZE,\n    class_mode='categorical',\n    batch_size=15,\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:30:55.265446Z","iopub.execute_input":"2022-03-14T01:30:55.265952Z","iopub.status.idle":"2022-03-14T01:30:55.503987Z","shell.execute_reply.started":"2022-03-14T01:30:55.265918Z","shell.execute_reply":"2022-03-14T01:30:55.502657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Generate Validation data","metadata":{"execution":{"iopub.status.busy":"2022-03-10T13:57:45.450223Z","iopub.execute_input":"2022-03-10T13:57:45.450471Z","iopub.status.idle":"2022-03-10T13:57:56.926754Z","shell.execute_reply.started":"2022-03-10T13:57:45.450441Z","shell.execute_reply":"2022-03-10T13:57:56.926118Z"}}},{"cell_type":"code","source":"# Training data generator\nvalid_data_generator = ImageDataGenerator(\n    rescale=1./255,\n)\nvalid_generator = valid_data_generator.flow_from_dataframe(\n    valid_df,\n    \"temp\",\n    x_col='filename',\n    y_col='category',\n    target_size=IMG_SIZE,\n    class_mode='categorical',\n    batch_size=15,\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:30:57.163731Z","iopub.execute_input":"2022-03-14T01:30:57.164072Z","iopub.status.idle":"2022-03-14T01:30:57.23436Z","shell.execute_reply.started":"2022-03-14T01:30:57.164032Z","shell.execute_reply":"2022-03-14T01:30:57.23337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Check how generate","metadata":{}},{"cell_type":"code","source":"example_df = train_df.sample(n=1).reset_index(drop=True)\nexample_generate = train_data_generator.flow_from_dataframe(\n    example_df,\n    \"temp\",\n    x_col='filename',\n    y_col='category',\n    target_size=IMG_SIZE,\n    class_mode='categorical',\n    batch_size=15,\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:30:58.951717Z","iopub.execute_input":"2022-03-14T01:30:58.952025Z","iopub.status.idle":"2022-03-14T01:30:58.964037Z","shell.execute_reply.started":"2022-03-14T01:30:58.951985Z","shell.execute_reply":"2022-03-14T01:30:58.962685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(12, 12))\nfor i in range(0, 15):\n    plt.subplot(5, 3, i+1)\n    for X_batch, Y_batch in example_generate:\n        image = X_batch[0]\n        plt.imshow(image)\n        break\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:31:00.623545Z","iopub.execute_input":"2022-03-14T01:31:00.624351Z","iopub.status.idle":"2022-03-14T01:31:03.844049Z","shell.execute_reply.started":"2022-03-14T01:31:00.624306Z","shell.execute_reply":"2022-03-14T01:31:03.843116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build model\nThe model we will build is CNN which references idea from [notebook](https://www.kaggle.com/uysimty/keras-cnn-dog-or-cat-classification/notebook#See-sample-image)","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, Flatten, Dense, Dropout, BatchNormalization, MaxPool2D, Activation\n\nmodel = Sequential()\n\n# define layer_1, layer_2, layer_3 which have Conv, BatchNorm, Pooling, Dropout\nmodel.add(Conv2D(32, (3, 3), activation='relu', \n                 input_shape=(IMG_WID, IMG_HEI, IMG_CHANNELS)))\nmodel.add(BatchNormalization())\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, (3, 3), activation='relu', \n                 input_shape=(IMG_WID, IMG_HEI, IMG_CHANNELS)))\nmodel.add(BatchNormalization())\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(128, (3, 3), activation='relu', \n                 input_shape=(IMG_WID, IMG_HEI, IMG_CHANNELS)))\nmodel.add(BatchNormalization())\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# define Fully Connected Layer which has Flatten, Dense, Drop, Dense\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.5))\nmodel.add(Dense(2, activation='softmax')) # two label dogs and cats\n\n# Configures the model for training\nmodel.compile(loss='categorical_crossentropy', optimizer='rmsprop', \n              metrics=['accuracy'])\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:31:07.872125Z","iopub.execute_input":"2022-03-14T01:31:07.872414Z","iopub.status.idle":"2022-03-14T01:31:09.994313Z","shell.execute_reply.started":"2022-03-14T01:31:07.872384Z","shell.execute_reply":"2022-03-14T01:31:09.992981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define callbacks\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n\n# To prevent over fitting we will stop the learning after 10 epochs and val_loss value not decreased\nearlystop = EarlyStopping(patience=10)\n\n# Reduce learning rate when accuracy does not raise for 2 steps\nreduce_learning_rate = ReduceLROnPlateau(monitor='val_acc', \n                                            patience=2, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\ncallbacks = [earlystop, reduce_learning_rate]","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:31:12.979896Z","iopub.execute_input":"2022-03-14T01:31:12.980179Z","iopub.status.idle":"2022-03-14T01:31:12.986591Z","shell.execute_reply.started":"2022-03-14T01:31:12.980147Z","shell.execute_reply":"2022-03-14T01:31:12.985795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Fit model","metadata":{"execution":{"iopub.status.busy":"2022-03-10T14:18:32.884922Z","iopub.execute_input":"2022-03-10T14:18:32.885257Z","iopub.status.idle":"2022-03-10T14:18:32.889378Z","shell.execute_reply.started":"2022-03-10T14:18:32.885209Z","shell.execute_reply":"2022-03-10T14:18:32.888406Z"}}},{"cell_type":"code","source":"epochs = 15\nhistory = model.fit(\n    train_generator, \n    epochs=epochs,\n    validation_data=valid_generator,\n    validation_steps=valid_df.shape[0]//15,\n    steps_per_epoch=train_df.shape[0]//15,\n    callbacks=callbacks\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-14T01:31:14.783535Z","iopub.execute_input":"2022-03-14T01:31:14.783858Z","iopub.status.idle":"2022-03-14T01:32:01.002835Z","shell.execute_reply.started":"2022-03-14T01:31:14.783823Z","shell.execute_reply":"2022-03-14T01:32:01.001746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save_weights(\"model.h5\")","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.392355Z","iopub.status.idle":"2022-03-13T04:59:21.398016Z","shell.execute_reply.started":"2022-03-13T04:59:21.397766Z","shell.execute_reply":"2022-03-13T04:59:21.397793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))\nax1.plot(history.history['loss'], color='b', label=\"Training loss\")\nax1.plot(history.history['val_loss'], color='r', label=\"validation loss\")\nax1.set_xticks(np.arange(1, epochs, 1))\nax1.set_yticks(np.arange(0, 1, 0.1))\n\nax2.plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\nax2.plot(history.history['val_accuracy'], color='r',label=\"Validation accuracy\")\nax2.set_xticks(np.arange(1, epochs, 1))\n\nlegend = plt.legend(loc='best', shadow=True)\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.399149Z","iopub.status.idle":"2022-03-13T04:59:21.399585Z","shell.execute_reply.started":"2022-03-13T04:59:21.399332Z","shell.execute_reply":"2022-03-13T04:59:21.399355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history.history","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.400803Z","iopub.status.idle":"2022-03-13T04:59:21.401203Z","shell.execute_reply.started":"2022-03-13T04:59:21.400977Z","shell.execute_reply":"2022-03-13T04:59:21.400998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare Test set","metadata":{}},{"cell_type":"code","source":"filenames = os.listdir(\"../input/dog-vs-cat-classification/test/test\")\n\ntest_df = pd.DataFrame({\n    'filename': filenames,\n}\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.405556Z","iopub.status.idle":"2022-03-13T04:59:21.406086Z","shell.execute_reply.started":"2022-03-13T04:59:21.405825Z","shell.execute_reply":"2022-03-13T04:59:21.40585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data_generator = ImageDataGenerator(\n    rescale=1./255,\n)\ntest_generator = test_data_generator.flow_from_dataframe(\n    test_df,\n    \"../input/dog-vs-cat-classification/test/test\",\n    x_col='filename',\n    target_size=IMG_SIZE,\n    class_mode=None,\n    batch_size=15,\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.407313Z","iopub.status.idle":"2022-03-13T04:59:21.407682Z","shell.execute_reply.started":"2022-03-13T04:59:21.407477Z","shell.execute_reply":"2022-03-13T04:59:21.407498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict","metadata":{}},{"cell_type":"code","source":"predict = model.predict(test_generator, steps=np.ceil(test_df.shape[0]/15))","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.409379Z","iopub.status.idle":"2022-03-13T04:59:21.410458Z","shell.execute_reply.started":"2022-03-13T04:59:21.410206Z","shell.execute_reply":"2022-03-13T04:59:21.410231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['category'] = np.argmax(predict, axis=-1)","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.416531Z","iopub.status.idle":"2022-03-13T04:59:21.416947Z","shell.execute_reply.started":"2022-03-13T04:59:21.416732Z","shell.execute_reply":"2022-03-13T04:59:21.416754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['category'].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.418062Z","iopub.status.idle":"2022-03-13T04:59:21.418561Z","shell.execute_reply.started":"2022-03-13T04:59:21.418303Z","shell.execute_reply":"2022-03-13T04:59:21.418328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Sample predict","metadata":{}},{"cell_type":"code","source":"sample_test = test_df.head(18)\nsample_test.head()\nplt.figure(figsize=(12, 24))\nfor index, row in sample_test.iterrows():\n    filename = row['filename']\n    category = row['category']\n    img = load_img(\"../input/dog-vs-cat-classification/test/test/\"+filename, target_size=IMG_SIZE)\n    plt.subplot(6, 3, index+1)\n    plt.imshow(img)\n    plt.xlabel(category)\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.419747Z","iopub.status.idle":"2022-03-13T04:59:21.420238Z","shell.execute_reply.started":"2022-03-13T04:59:21.419986Z","shell.execute_reply":"2022-03-13T04:59:21.420011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submit","metadata":{}},{"cell_type":"code","source":"submit_df = test_df.copy()\nsubmit_df = submit_df.rename(columns={'filename': 'id', 'category': 'labels'})","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.421427Z","iopub.status.idle":"2022-03-13T04:59:21.422306Z","shell.execute_reply.started":"2022-03-13T04:59:21.421617Z","shell.execute_reply":"2022-03-13T04:59:21.42164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-03-13T04:59:21.429419Z","iopub.status.idle":"2022-03-13T04:59:21.429903Z","shell.execute_reply.started":"2022-03-13T04:59:21.429675Z","shell.execute_reply":"2022-03-13T04:59:21.429709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}