{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"},{"sourceId":791828,"sourceType":"datasetVersion","datasetId":119698},{"sourceId":1003830,"sourceType":"datasetVersion","datasetId":550917}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Basic\nimport os\nfrom os import makedirs\nfrom os import listdir\nfrom shutil import copyfile\nfrom random import seed\nfrom random import random\nimport numpy as np\nimport pandas as pd\n\n# visuals\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom matplotlib.image import imread\nfrom PIL import Image\n\n# Scikit-learn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report,confusion_matrix,ConfusionMatrixDisplay\n\n# Tensorflow\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.layers import Dense,MaxPooling2D,Dropout,Flatten,BatchNormalization,Conv2D\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau,EarlyStopping","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-05-15T06:40:24.590535Z","iopub.execute_input":"2024-05-15T06:40:24.590855Z","iopub.status.idle":"2024-05-15T06:40:40.432981Z","shell.execute_reply.started":"2024-05-15T06:40:24.590829Z","shell.execute_reply":"2024-05-15T06:40:40.432049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='4'></a>\n<div class=\"alert alert-block alert-info\"><h2 style=\"text-align:center;color:black\"> Data Extraction </h2> </div>","metadata":{}},{"cell_type":"code","source":"train_path = \"../input/dogs-vs-cats/test1.zip\"\ntest_path = \"../input/dogs-vs-cats/train.zip\"\n\nfiles = \"/kaggle/working/\"\n\nimport zipfile\n\nwith zipfile.ZipFile(train_path, 'r') as zipp:\n    zipp.extractall(files)\n    \nwith zipfile.ZipFile(test_path, 'r') as zipp:\n    zipp.extractall(files)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:40.434685Z","iopub.execute_input":"2024-05-15T06:40:40.435194Z","iopub.status.idle":"2024-05-15T06:40:54.236515Z","shell.execute_reply.started":"2024-05-15T06:40:40.435169Z","shell.execute_reply":"2024-05-15T06:40:54.235741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_dir = \"../working/train/\"\n\nfilenames = os.listdir(image_dir)\nlabels = [x.split(\".\")[0] for x in filenames]\n\ndata = pd.DataFrame({\"filename\": filenames, \"label\": labels})\n\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:54.237638Z","iopub.execute_input":"2024-05-15T06:40:54.237922Z","iopub.status.idle":"2024-05-15T06:40:54.290396Z","shell.execute_reply.started":"2024-05-15T06:40:54.237898Z","shell.execute_reply":"2024-05-15T06:40:54.289517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,20)) # specifying the overall grid size\nplt.subplots_adjust(hspace=0.4)\n\n\nfor i in range(10):\n    \n    plt.subplot(1,10,i+1)    # the number of images in the grid is 10*10 (100)\n    filename = 'train/' + 'dog.' + str(i) + '.jpg'\n    image = imread(filename)\n    plt.imshow(image)\n    plt.title('Dog',fontsize=12)\n    plt.axis('off')\n\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T06:40:54.292791Z","iopub.execute_input":"2024-05-15T06:40:54.293093Z","iopub.status.idle":"2024-05-15T06:40:55.318102Z","shell.execute_reply.started":"2024-05-15T06:40:54.293067Z","shell.execute_reply":"2024-05-15T06:40:55.317221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train test split using dataframe\n\nlabels = data['label']\n\nX_train, X_temp = train_test_split(data, test_size=0.2, stratify=labels, random_state = 42)\n\nlabel_test_val = X_temp['label']\n\nX_test, X_val = train_test_split(X_temp, test_size=0.5, stratify=label_test_val, random_state = 42)\n\nprint('The shape of train data',X_train.shape)\nprint('The shape of test data',X_test.shape)\nprint('The shape of validation data',X_val.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:55.319147Z","iopub.execute_input":"2024-05-15T06:40:55.319412Z","iopub.status.idle":"2024-05-15T06:40:55.38395Z","shell.execute_reply.started":"2024-05-15T06:40:55.31939Z","shell.execute_reply":"2024-05-15T06:40:55.382919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = ['Cat','Dog']\n\nlabel1,count1 = np.unique(X_train.label,return_counts=True)\nlabel2,count2 = np.unique(X_val.label,return_counts=True)\nlabel3,count3 = np.unique(X_test.label,return_counts=True)\n\nuni1 = pd.DataFrame(data=count1,index=labels,columns=['Count1'])\nuni2 = pd.DataFrame(data=count2,index=labels,columns=['Count2'])\nuni3 = pd.DataFrame(data=count3,index=labels,columns=['Count3'])\n\n\nplt.figure(figsize=(20,6),dpi=200)\nsns.set_style('darkgrid')\n\nplt.subplot(131)\nsns.barplot(data=uni1,x=uni1.index,y='Count1',palette='icefire',width=0.2).set_title('Class distribution in Training set',fontsize=15)\nplt.xlabel('Labels',fontsize=12)\nplt.ylabel('Count',fontsize=12)\n\nplt.subplot(132)\nsns.barplot(data=uni2,x=uni2.index,y='Count2',palette='icefire',width=0.2).set_title('Class distribution in validation set',fontsize=15)\nplt.xlabel('Labels',fontsize=12)\nplt.ylabel('Count',fontsize=12)\n\n\nplt.subplot(133)\nsns.barplot(data=uni3,x=uni3.index,y='Count3',palette='icefire',width=0.2).set_title('Class distribution in Testing set',fontsize=15)\nplt.xlabel('Labels',fontsize=12)\nplt.ylabel('Count',fontsize=12)\n\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T06:40:55.38507Z","iopub.execute_input":"2024-05-15T06:40:55.38564Z","iopub.status.idle":"2024-05-15T06:40:56.138635Z","shell.execute_reply.started":"2024-05-15T06:40:55.385611Z","shell.execute_reply":"2024-05-15T06:40:56.137692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create directories\ndataset_home = 'dataset_dogs_vs_cats/'\nsubdirs = ['train/', 'test/']\n\nfor subdir in subdirs:\n    # create label subdirectories\n    labeldirs = ['dogs/', 'cats/']\n    for labldir in labeldirs:\n        newdir = dataset_home + subdir + labldir\n        makedirs(newdir, exist_ok=True)\n# seed random number generator\nseed(1)\n# define ratio of pictures to use for validation\nval_ratio = 0.2\n# copy training dataset images into subdirectories\nsrc_directory = 'train/'\nfor file in listdir(src_directory):\n        src = src_directory + '/' + file\n        dst_dir = 'train/'\n        if random() < val_ratio:\n            dst_dir = 'test/'\n        if file.startswith('cat'):\n            dst = dataset_home + dst_dir + 'cats/' + file\n            copyfile(src, dst)\n        elif file.startswith('dog'):\n            dst = dataset_home + dst_dir + 'dogs/' + file\n            copyfile(src, dst)\n\n            \npath1 = \"/kaggle/working/dataset_dogs_vs_cats/train/cats\"\npath2 = \"/kaggle/working/dataset_dogs_vs_cats/train/dogs\"\npath3 = \"/kaggle/working/dataset_dogs_vs_cats/test/cats\"\npath4 = \"/kaggle/working/dataset_dogs_vs_cats/test/dogs\"\n\n\nprint('Then number of cat images in training data is' ,len(os.listdir(path1)))\nprint('Then number of dog images in training data is' ,len(os.listdir(path2)))\nprint('Then number of cat images in validation data is' ,len(os.listdir(path3)))\nprint('Then number of dog images in validation data is' ,len(os.listdir(path4)))\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T06:40:56.139876Z","iopub.execute_input":"2024-05-15T06:40:56.140215Z","iopub.status.idle":"2024-05-15T06:40:58.599042Z","shell.execute_reply.started":"2024-05-15T06:40:56.140186Z","shell.execute_reply":"2024-05-15T06:40:58.598136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# parameters\nimage_size = 128\nimage_channel = 3\nbat_size = 32","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:58.600164Z","iopub.execute_input":"2024-05-15T06:40:58.600441Z","iopub.status.idle":"2024-05-15T06:40:58.604685Z","shell.execute_reply.started":"2024-05-15T06:40:58.600416Z","shell.execute_reply":"2024-05-15T06:40:58.603594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Creating image data generator\ntrain_datagen = ImageDataGenerator(rescale=1./255,\n                                    rotation_range = 15,\n                                    horizontal_flip = True,\n                                    zoom_range = 0.2,\n                                    shear_range = 0.1,\n                                    fill_mode = 'reflect',\n                                    width_shift_range = 0.1,\n                                    height_shift_range = 0.1)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:58.605839Z","iopub.execute_input":"2024-05-15T06:40:58.606261Z","iopub.status.idle":"2024-05-15T06:40:58.615689Z","shell.execute_reply.started":"2024-05-15T06:40:58.606238Z","shell.execute_reply":"2024-05-15T06:40:58.614942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Applying image data gernerator to train and test data\n\ntrain_generator = train_datagen.flow_from_dataframe(X_train,\n                                                    directory = 'train/',\n                                                    x_col= 'filename',\n                                                    y_col= 'label',\n                                                    batch_size = bat_size,\n                                                    target_size = (image_size,image_size)\n                                                   )\nval_generator = test_datagen.flow_from_dataframe(X_val, \n                                                 directory = 'train/',\n                                                 x_col= 'filename',\n                                                 y_col= 'label',\n                                                 batch_size = bat_size,\n                                                 target_size = (image_size,image_size),\n                                                 shuffle=False\n                                                )\n\ntest_generator = test_datagen.flow_from_dataframe(X_test, \n                                                  directory = 'train/',\n                                                  x_col= 'filename',\n                                                  y_col= 'label',\n                                                  batch_size = bat_size,\n                                                  target_size = (image_size,image_size),\n                                                  shuffle=False\n                                                 )","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:58.619382Z","iopub.execute_input":"2024-05-15T06:40:58.619663Z","iopub.status.idle":"2024-05-15T06:40:58.923682Z","shell.execute_reply.started":"2024-05-15T06:40:58.619641Z","shell.execute_reply":"2024-05-15T06:40:58.922874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_gen = train_datagen.flow_from_directory('/kaggle/working/dataset_dogs_vs_cats/train/', \n                                              class_mode='binary',\n                                              target_size = (image_size,image_size),\n                                              batch_size = bat_size,\n                                             )\n\nval_gen = test_datagen.flow_from_directory('/kaggle/working/dataset_dogs_vs_cats/test/', \n                                          class_mode='binary',\n                                          batch_size = bat_size,\n                                          target_size = (image_size,image_size),\n                                          shuffle = False\n                                         )","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:40:58.924785Z","iopub.execute_input":"2024-05-15T06:40:58.925058Z","iopub.status.idle":"2024-05-15T06:40:59.584263Z","shell.execute_reply.started":"2024-05-15T06:40:58.925034Z","shell.execute_reply":"2024-05-15T06:40:59.583398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential()\n\n# Input Layer\nmodel.add(Conv2D(32,(3,3),activation='relu',input_shape = (image_size,image_size,image_channel))) \nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n\n# Bloack 1 \nmodel.add(Conv2D(64,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n# Block 2\nmodel.add(Conv2D(128,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n# Block 3\nmodel.add(Conv2D(256,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n\n# Fully Connected layers \nmodel.add(Flatten())\nmodel.add(Dense(512,activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.2))\n\n# Output layer\nmodel.add(Dense(2,activation='softmax'))\n\nmodel.summary()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T06:40:59.585262Z","iopub.execute_input":"2024-05-15T06:40:59.585519Z","iopub.status.idle":"2024-05-15T06:41:00.741551Z","shell.execute_reply.started":"2024-05-15T06:40:59.585496Z","shell.execute_reply":"2024-05-15T06:41:00.740704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learning_rate_reduction = ReduceLROnPlateau(monitor = 'val_accuracy',\n                                            patience=2,\n                                            factor=0.5,\n                                            min_lr = 0.00001,\n                                            verbose = 1)\n\nearly_stoping = EarlyStopping(monitor='val_loss',patience= 3,restore_best_weights=True,verbose=0)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:41:00.742922Z","iopub.execute_input":"2024-05-15T06:41:00.743276Z","iopub.status.idle":"2024-05-15T06:41:00.748352Z","shell.execute_reply.started":"2024-05-15T06:41:00.743229Z","shell.execute_reply":"2024-05-15T06:41:00.747433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-05-15T06:41:00.749505Z","iopub.execute_input":"2024-05-15T06:41:00.749777Z","iopub.status.idle":"2024-05-15T06:41:00.772646Z","shell.execute_reply.started":"2024-05-15T06:41:00.749755Z","shell.execute_reply":"2024-05-15T06:41:00.771849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_dog = model.fit(train_generator,\n                    validation_data = val_generator, \n                    callbacks=[early_stoping,learning_rate_reduction],\n                    epochs = 10,\n                    # steps_per_epoch = len(train_generator),\n                    # validation_steps = len(val_generaotor),\n                   )","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-05-15T06:43:26.133412Z","iopub.execute_input":"2024-05-15T06:43:26.1343Z","iopub.status.idle":"2024-05-15T06:59:41.877098Z","shell.execute_reply.started":"2024-05-15T06:43:26.134264Z","shell.execute_reply":"2024-05-15T06:59:41.876111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plots for accuracy and Loss with epochs\n\nerror = pd.DataFrame(cat_dog.history)\n\nplt.figure(figsize=(18,5),dpi=200)\nsns.set_style('darkgrid')\n\nplt.subplot(121)\nplt.title('Cross Entropy Loss',fontsize=15)\nplt.xlabel('Epochs',fontsize=12)\nplt.ylabel('Loss',fontsize=12)\nplt.plot(error['loss'])\nplt.plot(error['val_loss'])\n\nplt.subplot(122)\nplt.title('Classification Accuracy',fontsize=15)\nplt.xlabel('Epochs',fontsize=12)\nplt.ylabel('Accuracy',fontsize=12)\nplt.plot(error['accuracy'])\nplt.plot(error['val_accuracy'])\n\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T06:59:52.474633Z","iopub.execute_input":"2024-05-15T06:59:52.475294Z","iopub.status.idle":"2024-05-15T06:59:53.48014Z","shell.execute_reply.started":"2024-05-15T06:59:52.475264Z","shell.execute_reply":"2024-05-15T06:59:53.479237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluvate for train generator\nloss,acc = model.evaluate(train_generator,batch_size = bat_size, verbose = 0)\n\nprint('The accuracy of the model for training data is:',acc*100)\nprint('The Loss of the model for training data is:',loss)\n\n# Evaluvate for validation generator\nloss,acc = model.evaluate(val_generator,batch_size = bat_size, verbose = 0)\n\nprint('The accuracy of the model for validation data is:',acc*100)\nprint('The Loss of the model for validation data is:',loss)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T07:04:04.645616Z","iopub.execute_input":"2024-05-15T07:04:04.64643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Finally, we will save the model for future use.","metadata":{}},{"cell_type":"code","source":"# prediction\nresult = model.predict(test_generator,batch_size = bat_size,verbose = 0)\n\ny_pred = np.argmax(result, axis = 1)\n\ny_true = test_generator.labels\n\n# Evaluvate\nloss,acc = model.evaluate(test_generator, batch_size = bat_size, verbose = 0)\n\nprint('The accuracy of the model for testing data is:',acc*100)\nprint('The Loss of the model for testing data is:',loss)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T07:00:49.478316Z","iopub.execute_input":"2024-05-15T07:00:49.479077Z","iopub.status.idle":"2024-05-15T07:00:57.181528Z","shell.execute_reply.started":"2024-05-15T07:00:49.479042Z","shell.execute_reply":"2024-05-15T07:00:57.180637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Classification report","metadata":{}},{"cell_type":"code","source":"labels =['Cat','Dog']\nprint(classification_report(y_true, y_pred,target_names=labels))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T07:01:02.147435Z","iopub.execute_input":"2024-05-15T07:01:02.147842Z","iopub.status.idle":"2024-05-15T07:01:02.16958Z","shell.execute_reply.started":"2024-05-15T07:01:02.147808Z","shell.execute_reply":"2024-05-15T07:01:02.16839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"confusioin matrix","metadata":{}},{"cell_type":"code","source":"confusion_mtx = confusion_matrix(y_true,y_pred) \n\nf,ax = plt.subplots(figsize = (8,4),dpi=200)\nsns.heatmap(confusion_mtx, annot=True, linewidths=0.1, cmap = \"gist_yarg_r\", linecolor=\"black\", fmt='.0f', ax=ax,cbar=False, xticklabels=labels, yticklabels=labels)\n\nplt.xlabel(\"Predicted Label\",fontsize=10)\nplt.ylabel(\"True Label\",fontsize=10)\nplt.title(\"Confusion Matrix\",fontsize=13)\n\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T06:43:19.379387Z","iopub.status.idle":"2024-05-15T06:43:19.379865Z","shell.execute_reply.started":"2024-05-15T06:43:19.379617Z","shell.execute_reply":"2024-05-15T06:43:19.379637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='21'></a>\n<div class=\"alert alert-block alert-danger\"><h3 style=\"text-align:center;color:black\"> Visualize Classified Images  </h3> </div>","metadata":{}},{"cell_type":"code","source":"fig, axes = plt.subplots(1, 10, figsize=(20, 4))\nfor idx in range(10):\n    image_path = os.path.join(test_dir, test_data.iloc[idx]['filename'])\n    image = Image.open(image_path)\n    axes[idx].imshow(image)\n    axes[idx].set_title(\"Label: \" + test_data.iloc[idx]['label'])\n    axes[idx].axis('off')\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-15T07:01:12.97636Z","iopub.execute_input":"2024-05-15T07:01:12.976728Z","iopub.status.idle":"2024-05-15T07:01:14.933397Z","shell.execute_reply.started":"2024-05-15T07:01:12.976695Z","shell.execute_reply":"2024-05-15T07:01:14.932059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"After watching the images we can see the our model is quite accurate with 94% accuracy.","metadata":{}},{"cell_type":"markdown","source":"\n<a id='22'></a>\n<div class=\"alert alert-block alert-info\"><h2 style=\"text-align:center;color:black\"> Conclusion </h2> </div>\n\n\nWe successfully built a deep neural network model by implementing Convolutional Neural Network (CNN) to classify dog and cat images with very high accuracy 97.32 %. \n\nThe model was used to predict the classes of the images from the independent test set and results were submitted to test the accuracy of the prediction with fresh data.\n\nThe Cat vs Dog Image Classification model demonstrates the successful implementation of a Convolutional Neural Network for image classification tasks. By accurately distinguishing between images of cats and dogs, this project showcases the potential of deep learning algorithms in solving real-world problems involving image analysis. Through this project, we aim to inspire further exploration of CNNs and their applications in various domains,","metadata":{}}]}