{"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":"### **Importing Required Libraries**","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport seaborn as sns\nimport random\nimport os\nfrom zipfile import ZipFile\nfrom skimage.io import imread, imshow\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential,load_model \nfrom tensorflow.keras.layers import Conv2D,MaxPooling2D,Flatten,Dense, Dropout, Activation, BatchNormalization\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint,ReduceLROnPlateau\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\n\nimport warnings\nwarnings.filterwarnings('ignore')\n","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:58:56.469722Z","iopub.execute_input":"2021-06-28T04:58:56.470033Z","iopub.status.idle":"2021-06-28T04:59:02.264919Z","shell.execute_reply.started":"2021-06-28T04:58:56.469961Z","shell.execute_reply":"2021-06-28T04:59:02.264071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Import Train and Test Data**","metadata":{}},{"cell_type":"code","source":"# extracting images from train and test zip files.\ntrainDataPath = \"/kaggle/input/dogs-vs-cats/train.zip\"\ntestDataPath = \"/kaggle/input/dogs-vs-cats/test1.zip\"\nZipFile(trainDataPath,mode = \"r\").extractall()\nZipFile(testDataPath,mode =  \"r\").extractall()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:02.266290Z","iopub.execute_input":"2021-06-28T04:59:02.266597Z","iopub.status.idle":"2021-06-28T04:59:20.049609Z","shell.execute_reply.started":"2021-06-28T04:59:02.266565Z","shell.execute_reply":"2021-06-28T04:59:20.048763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# extracted train and test images path\ntrain_path = './train'\ntest_path = './test1'","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.051227Z","iopub.execute_input":"2021-06-28T04:59:20.051528Z","iopub.status.idle":"2021-06-28T04:59:20.058186Z","shell.execute_reply.started":"2021-06-28T04:59:20.051501Z","shell.execute_reply":"2021-06-28T04:59:20.057373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Defining some variables\nsize  = 128\nchannels = 3\nbatch_size = 32\nepochs = 50\nwidth=128\nheight=128","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.059729Z","iopub.execute_input":"2021-06-28T04:59:20.060072Z","iopub.status.idle":"2021-06-28T04:59:20.070437Z","shell.execute_reply.started":"2021-06-28T04:59:20.060039Z","shell.execute_reply":"2021-06-28T04:59:20.069490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Preparing Training Data**","metadata":{}},{"cell_type":"code","source":"# adding images names in dataframe with category.\nfilenames = os.listdir(train_path)\ncategories = []\nfor filename in filenames:\n    category = filename.split('.')[0]\n    if category == 'cat':\n        categories.append(category)\n    else:\n        categories.append(category)\n\ndf = pd.DataFrame({\n    'Image': filenames,\n    'Category': categories})\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.071774Z","iopub.execute_input":"2021-06-28T04:59:20.072162Z","iopub.status.idle":"2021-06-28T04:59:20.132322Z","shell.execute_reply.started":"2021-06-28T04:59:20.072127Z","shell.execute_reply":"2021-06-28T04:59:20.131421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Preparing Testing Data**","metadata":{}},{"cell_type":"code","source":"test_files = os.listdir(test_path)\ndf_test = pd.DataFrame({'Image':test_files})\n\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.133492Z","iopub.execute_input":"2021-06-28T04:59:20.133860Z","iopub.status.idle":"2021-06-28T04:59:20.152062Z","shell.execute_reply.started":"2021-06-28T04:59:20.133827Z","shell.execute_reply":"2021-06-28T04:59:20.151370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Checking the Total Count","metadata":{}},{"cell_type":"code","source":"sns.countplot(x='Category',data=df)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.153208Z","iopub.execute_input":"2021-06-28T04:59:20.153546Z","iopub.status.idle":"2021-06-28T04:59:20.292950Z","shell.execute_reply.started":"2021-06-28T04:59:20.153513Z","shell.execute_reply":"2021-06-28T04:59:20.292027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**We can see that We have 12000 cats and 12000 dogs images.**","metadata":{}},{"cell_type":"markdown","source":"### Let us view some of the images of **Cat** ","metadata":{}},{"cell_type":"code","source":"cat_files = [file for file in filenames if file.split('.')[0] == 'cat']\n\ndef plotImages(file):\n    r = random.sample(file, 9)\n        \n    a = 3  # number of rows\n    b = 3  # number of columns\n    c = 1  # initialize plot counter\n\n    fig = plt.figure(figsize=(14,10))\n\n    for i in range(len(r)):\n        plt.subplot(a, b, c)\n        img = mpimg.imread('./train/'+ r[i])\n        plt.imshow(img)\n        plt.axis('off')\n        c = c + 1\n\n    plt.show()\n    ","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.295656Z","iopub.execute_input":"2021-06-28T04:59:20.296052Z","iopub.status.idle":"2021-06-28T04:59:20.310222Z","shell.execute_reply.started":"2021-06-28T04:59:20.296018Z","shell.execute_reply":"2021-06-28T04:59:20.309291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plotImages(cat_files)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.312141Z","iopub.execute_input":"2021-06-28T04:59:20.312673Z","iopub.status.idle":"2021-06-28T04:59:20.957558Z","shell.execute_reply.started":"2021-06-28T04:59:20.312617Z","shell.execute_reply":"2021-06-28T04:59:20.956747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Let us view some of the images of **Dog** ","metadata":{}},{"cell_type":"code","source":"dog_files = [file for file in filenames if file.split('.')[0] == 'dog']\nplotImages(dog_files)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:20.958550Z","iopub.execute_input":"2021-06-28T04:59:20.958871Z","iopub.status.idle":"2021-06-28T04:59:21.627587Z","shell.execute_reply.started":"2021-06-28T04:59:20.958840Z","shell.execute_reply":"2021-06-28T04:59:21.626701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Train & Validation Split**","metadata":{}},{"cell_type":"code","source":"train_df, validation_df = train_test_split(df, test_size=0.20, random_state=50)\ntrain_df = train_df.reset_index(drop=True)\nvalidation_df = validation_df.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:21.628931Z","iopub.execute_input":"2021-06-28T04:59:21.629254Z","iopub.status.idle":"2021-06-28T04:59:21.643088Z","shell.execute_reply.started":"2021-06-28T04:59:21.629221Z","shell.execute_reply":"2021-06-28T04:59:21.642104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Data Augmentation**","metadata":{}},{"cell_type":"code","source":"# Augmentation on training data and only scaling validation and test data.\ntrain_datagen = ImageDataGenerator(\n    rotation_range=40,\n    rescale=1./255,\n    shear_range=0.1,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    width_shift_range=0.2,\n    height_shift_range=0.2\n)\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:21.644346Z","iopub.execute_input":"2021-06-28T04:59:21.644671Z","iopub.status.idle":"2021-06-28T04:59:21.651242Z","shell.execute_reply.started":"2021-06-28T04:59:21.644639Z","shell.execute_reply":"2021-06-28T04:59:21.650340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = train_datagen.flow_from_dataframe(\n    train_df, \n    directory = train_path, \n    x_col='Image',\n    y_col='Category',\n    target_size=(size,size),\n    class_mode='categorical',\n    batch_size=batch_size\n)\n\nvalidation_dataset = validation_datagen.flow_from_dataframe(\n    validation_df, \n    directory = train_path, \n    x_col = 'Image',\n    y_col = 'Category',\n    target_size= (size,size),\n    class_mode = 'categorical',\n    batch_size = batch_size)\n\ntest_dataset = test_datagen.flow_from_dataframe(\n    df_test, \n    directory=test_path, \n    x_col='Image',\n    y_col=None,\n    class_mode=None,\n    target_size= (size,size),\n    batch_size=batch_size,\n    shuffle=False\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:21.652765Z","iopub.execute_input":"2021-06-28T04:59:21.653181Z","iopub.status.idle":"2021-06-28T04:59:22.000845Z","shell.execute_reply.started":"2021-06-28T04:59:21.653145Z","shell.execute_reply":"2021-06-28T04:59:21.999944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Model Building**","metadata":{}},{"cell_type":"markdown","source":"#### CNN Model","metadata":{}},{"cell_type":"code","source":"\n### Initializing the CNN\n\nmodel = Sequential()\n\n### Step 1 - Convolution 32x3x3\n\nmodel.add(Conv2D(32, (3, 3),                            ## 32 - number of feature detectors, 3-rows and 3-cols                  \n                             input_shape=(128, 128, 3),      ## fixed size of image to standardize dataset + 3d array for color img (reverse order for Tensorflow backend)\n                             activation = 'relu'))         ## to make sure there is no negative values in pixel maps to have non-linearity\n\n\n### Step 2 - Max Pooling\n\nmodel.add(MaxPooling2D(pool_size = (2,2)))            ## dims 2x2\n\nmodel.add(Dropout(rate = 0.25))\n\n### Step 2b - add additional convolutional layer for better result (from 50% to 80% accuracy)\n\nmodel.add(Conv2D(32, (3, 3), activation = 'relu'))      ## No input shape as it was already done\nmodel.add(MaxPooling2D(pool_size = (2,2)))            ## dims 2x2\n\nmodel.add(Dropout(rate = 0.2))\n\n\n### Step 2c - add additional convolutional layer for better result (from 80% to 90% accuracy)\n\nmodel.add(Conv2D(64, (3, 3), activation = 'relu'))      ## No input shape as it was already done\nmodel.add(MaxPooling2D(pool_size = (2,2)))            ## dims 2x2\n\nmodel.add(Dropout(rate = 0.3))\n\n\n### Step 2d - add additional convolutional layer for better result (from 80% to 90% accuracy)\n\nmodel.add(Conv2D(128, (3, 3), activation = 'relu'))      ## No input shape as it was already done\nmodel.add(MaxPooling2D(pool_size = (2,2)))            ## dims 2x2\n\nmodel.add(Dropout(rate = 0.4))\n\n\n### Step 3 - Flattening to one single vector\n\nmodel.add(Flatten())\n\n\n### Step 4 - Full connection\n\n# Hidden layer - 128 as a experience guess\n\nmodel.add(Dense(activation = 'relu', units = 128))\n\n\n# Output layer \n\nmodel.add(Dense(2, activation='softmax'))\n","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:22.002224Z","iopub.execute_input":"2021-06-28T04:59:22.002754Z","iopub.status.idle":"2021-06-28T04:59:24.147860Z","shell.execute_reply.started":"2021-06-28T04:59:22.002718Z","shell.execute_reply":"2021-06-28T04:59:24.146980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The following is the model summary of the model:\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:24.149925Z","iopub.execute_input":"2021-06-28T04:59:24.150170Z","iopub.status.idle":"2021-06-28T04:59:24.163016Z","shell.execute_reply.started":"2021-06-28T04:59:24.150147Z","shell.execute_reply":"2021-06-28T04:59:24.162236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Specifying the optimizers and compile the model","metadata":{}},{"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:24.165746Z","iopub.execute_input":"2021-06-28T04:59:24.165979Z","iopub.status.idle":"2021-06-28T04:59:25.571401Z","shell.execute_reply.started":"2021-06-28T04:59:24.165956Z","shell.execute_reply":"2021-06-28T04:59:25.570558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Setup Callbacks","metadata":{}},{"cell_type":"code","source":"checkpoint_filepath = 'best_weights.hdf5'\n\nearlyStop = EarlyStopping(monitor='val_accuracy', patience=4, \n                        verbose=1, mode='auto',restore_best_weights=True)\n\ncheckpoint = ModelCheckpoint(filepath=checkpoint_filepath, \n                                      save_weights_only=False, \n                                      monitor='val_accuracy',\n                                      mode='auto', \n                                      save_best_only=True)\n# learningrate = ReduceLROnPlateau(monitor='val_accuracy',\n#                                           mode='max',\n#                                           min_delta=0.03, patience=3, \n#                                           factor=.5,\n#                                           min_lr=0.00001, verbose=1)\n\ncallbacks = [earlyStop, checkpoint]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:25.572790Z","iopub.execute_input":"2021-06-28T04:59:25.573129Z","iopub.status.idle":"2021-06-28T04:59:25.932396Z","shell.execute_reply.started":"2021-06-28T04:59:25.573095Z","shell.execute_reply":"2021-06-28T04:59:25.931320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"###  Model Fitting","metadata":{}},{"cell_type":"code","source":"history = model.fit(train_dataset, \n                        validation_data = validation_dataset,\n                        epochs=epochs, \n                        callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T04:59:25.936261Z","iopub.execute_input":"2021-06-28T04:59:25.936671Z","iopub.status.idle":"2021-06-28T06:27:32.249884Z","shell.execute_reply.started":"2021-06-28T04:59:25.936616Z","shell.execute_reply":"2021-06-28T06:27:32.249000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs_range = range(len(acc))\n\nplt.figure(figsize=(15, 15))\nplt.subplot(2, 2, 1)\nplt.plot(epochs_range, acc, label='Training Accuracy')\nplt.plot(epochs_range, val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(2, 2, 2)\nplt.plot(epochs_range, loss, label='Training Loss')\nplt.plot(epochs_range, val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.title('Training and Validation Loss')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T06:27:32.252619Z","iopub.execute_input":"2021-06-28T06:27:32.252904Z","iopub.status.idle":"2021-06-28T06:27:32.537319Z","shell.execute_reply.started":"2021-06-28T06:27:32.252874Z","shell.execute_reply":"2021-06-28T06:27:32.536435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Prediction**","metadata":{}},{"cell_type":"code","source":"predict = model.predict(test_dataset)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T06:27:32.538656Z","iopub.execute_input":"2021-06-28T06:27:32.538986Z","iopub.status.idle":"2021-06-28T06:28:00.941464Z","shell.execute_reply.started":"2021-06-28T06:27:32.538950Z","shell.execute_reply":"2021-06-28T06:28:00.940600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# For categoral classication the prediction will come with probability of each category. \n# So we will pick the category that have the highest probability with numpy average max\ndf_test['category'] = np.argmax(predict, axis=-1)\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T06:28:00.944677Z","iopub.execute_input":"2021-06-28T06:28:00.944941Z","iopub.status.idle":"2021-06-28T06:28:00.959039Z","shell.execute_reply.started":"2021-06-28T06:28:00.944915Z","shell.execute_reply":"2021-06-28T06:28:00.958266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_map = dict((v,k) for k,v in train_dataset.class_indices.items())\ndf_test['category'] = df_test['category'].replace(label_map)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T06:28:00.962176Z","iopub.execute_input":"2021-06-28T06:28:00.962664Z","iopub.status.idle":"2021-06-28T06:28:00.970279Z","shell.execute_reply.started":"2021-06-28T06:28:00.962613Z","shell.execute_reply":"2021-06-28T06:28:00.969507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### See predicted result ","metadata":{}},{"cell_type":"code","source":"sample_test = df_test.head(15)\nsample_test.head()\nplt.figure(figsize=(12, 24))\nfor index, row in sample_test.iterrows():\n    filename = row['Image']\n    category = row['category']\n    img = load_img(test_path+'/' + filename, target_size=(size,size))\n    plt.subplot(6, 3, index+1)\n    plt.imshow(img)\n    plt.xlabel(filename + '(' + \"{}\".format(category) + ')' )\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T06:28:00.974666Z","iopub.execute_input":"2021-06-28T06:28:00.974911Z","iopub.status.idle":"2021-06-28T06:28:03.367611Z","shell.execute_reply.started":"2021-06-28T06:28:00.974888Z","shell.execute_reply":"2021-06-28T06:28:03.366787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Submission**","metadata":{}},{"cell_type":"code","source":"submission_df = df_test.copy()\nsubmission_df['id'] = submission_df['Image'].str.split('.').str[0]\nsubmission_df['label'] = submission_df['category']\nsubmission_df.drop(['Image', 'category'], axis=1, inplace=True)\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T06:28:03.368928Z","iopub.execute_input":"2021-06-28T06:28:03.369373Z","iopub.status.idle":"2021-06-28T06:28:03.661135Z","shell.execute_reply.started":"2021-06-28T06:28:03.369337Z","shell.execute_reply":"2021-06-28T06:28:03.660347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}