{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"\n<h1  id=\"2\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:Red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Importing Libraries </h1>\n           \n \n\n<span style=\"font-family:cursive; font-size:15px;\">\nWe are Importing Libraries. </span>\n\n\n<span style=\"font-family:cursive; font-size:15px;\">Libraries which need for\n </span>\n\n\n<span style=\"font-family:cursive; font-size:15px;\">Data visualization </span>\n\n\n<span style=\"font-family:cursive; font-size:15px;\">Making Model Architecture. </span>\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport tensorflow as tf\nimport random\nimport zipfile\nimport os\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:22:42.854769Z","iopub.execute_input":"2023-09-10T12:22:42.855419Z","iopub.status.idle":"2023-09-10T12:22:42.861290Z","shell.execute_reply.started":"2023-09-10T12:22:42.855385Z","shell.execute_reply":"2023-09-10T12:22:42.860429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport numpy as np\nimport sys\nimport tensorflow as tf\nimport os\nimport sys\nimport pandas as pd\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n\n%matplotlib inline\nimport matplotlib.image as img\nimport matplotlib.pyplot as plt\n\nfrom sklearn.metrics import confusion_matrix\nimport plotly.graph_objects as go\nimport itertools\nimport plotly.express as px","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:24:46.512413Z","iopub.execute_input":"2023-09-10T12:24:46.512920Z","iopub.status.idle":"2023-09-10T12:24:47.203582Z","shell.execute_reply.started":"2023-09-10T12:24:46.512887Z","shell.execute_reply":"2023-09-10T12:24:47.202628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1  id=\"2.1\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">  Setting Path and Extracting Files </h1>","metadata":{}},{"cell_type":"code","source":"\n\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats/train.zip', 'r') as train_zip:\n    train_zip.extractall('.')  \nimage_dir = \"../working/train/\"\nfilenames = os.listdir(image_dir)\nlabels = [x.split(\".\")[0] for x in filenames]\ndata = pd.DataFrame({\"filename\": filenames, \"label\": labels})\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:22:32.475944Z","iopub.execute_input":"2023-09-10T12:22:32.478162Z","iopub.status.idle":"2023-09-10T12:22:42.852004Z","shell.execute_reply.started":"2023-09-10T12:22:32.478130Z","shell.execute_reply":"2023-09-10T12:22:42.848554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_FOLDER_PATH = \"../working/train\"\nFILE_NAMES = os.listdir(IMAGE_FOLDER_PATH)\nWIDTH = 150\nHEIGHT = 150\n# empty list\ntargets = list()\nfull_paths = list()\ntrain_cats_dir = list()\ntrain_dogs_dir = list()\n\n# finding each file's target\nfor file_name in FILE_NAMES:\n    target = file_name.split(\".\")[0] # target name\n    full_path = os.path.join(IMAGE_FOLDER_PATH, file_name)\n    \n    if(target == \"dog\"):\n        train_dogs_dir.append(full_path)\n    if(target == \"cat\"):\n        train_cats_dir.append(full_path)\n    \n    full_paths.append(full_path)\n    targets.append(target)\n\ndataset = pd.DataFrame() # make dataframe\ndataset['image_path'] = full_paths # file path\ndataset['target'] = targets # file's target\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:31:30.137162Z","iopub.execute_input":"2023-09-10T12:31:30.137540Z","iopub.status.idle":"2023-09-10T12:31:30.249628Z","shell.execute_reply.started":"2023-09-10T12:31:30.137501Z","shell.execute_reply":"2023-09-10T12:31:30.248551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1  id=\"3\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">  Data distribuation of all data </h1>","metadata":{}},{"cell_type":"code","source":"print(data['label'].value_counts())\ncounts = data['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:26:12.011350Z","iopub.execute_input":"2023-09-10T12:26:12.012240Z","iopub.status.idle":"2023-09-10T12:26:12.027014Z","shell.execute_reply.started":"2023-09-10T12:26:12.012206Z","shell.execute_reply":"2023-09-10T12:26:12.026063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Data is balanced and has only two categories.","metadata":{}},{"cell_type":"code","source":"fig = go.Figure(go.Bar(\n            x= counts.values,\n            y=counts.index,\n            orientation='h'))\n\nfig.update_layout(title='Data Distribution in Bars',font_size=15,title_x=0.45)\n\n\nfig.show()\n\nfig=px.pie(counts.head(10),values= 'label', names=data['label'].unique(),hole=0.425)\nfig.update_layout(title='Data Distribution of Data',font_size=15,title_x=0.45,annotations=[dict(text='Cat vs Dog',font_size=18, showarrow=False,height=800,width=700)])\nfig.update_traces(textfont_size=15,textinfo='percent')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:26:52.146603Z","iopub.execute_input":"2023-09-10T12:26:52.146963Z","iopub.status.idle":"2023-09-10T12:26:53.509122Z","shell.execute_reply.started":"2023-09-10T12:26:52.146934Z","shell.execute_reply":"2023-09-10T12:26:53.506910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Displaying Images of Cat & Dog </h1>","metadata":{}},{"cell_type":"code","source":"\ngrouped_data = data.groupby(\"label\")\n\nnum_images_per_category = 5\n\nfig, axes = plt.subplots(len(grouped_data), num_images_per_category, figsize=(20, 20))\n\nfor i, (category, group) in enumerate(grouped_data):\n  \n    random_indices = random.sample(range(len(group)), num_images_per_category)\n\n    for j, index in enumerate(random_indices):\n        filename = group.iloc[index][\"filename\"]\n        label = group.iloc[index][\"label\"]\n        image_path = os.path.join(image_dir, filename)\n        image = Image.open(image_path)\n\n        axes[i, j].imshow(image)\n        axes[i, j].set_title(\"Label: \" + label, fontsize = 30)\n        \n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:22:49.728295Z","iopub.execute_input":"2023-09-10T12:22:49.728650Z","iopub.status.idle":"2023-09-10T12:22:54.307277Z","shell.execute_reply.started":"2023-09-10T12:22:49.728619Z","shell.execute_reply":"2023-09-10T12:22:54.305963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport matplotlib.image as img\n\ndef plot_images(directory, title):\n    rows = 4\n    cols = 4\n    axes = []\n    fig = plt.figure(figsize=(10, 10))\n    i = 0\n\n    for a in range(rows * cols):\n        b = img.imread(directory[i])\n        axes.append(fig.add_subplot(rows, cols, a + 1))\n        plt.imshow(b)\n        i += 1\n    fig.tight_layout()\n    plt.suptitle(title, fontsize=16)\n    plt.show()\n\n# Assuming you have directories train_cats_dir and train_dogs_dir\n\n# For cats\nplot_images(train_cats_dir, \"Cat Images\")\n\n# For dogs\nplot_images(train_dogs_dir, \"Dog Images\")\n","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:31:40.037264Z","iopub.execute_input":"2023-09-10T12:31:40.037622Z","iopub.status.idle":"2023-09-10T12:31:45.837906Z","shell.execute_reply.started":"2023-09-10T12:31:40.037593Z","shell.execute_reply":"2023-09-10T12:31:45.837067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Images are of varying size.\n\nEvery time the cell is run different set of images will be displayed, one can scan the images of both categories. Presence of humans in some images could be a challenge for the model to classify. \n\nSome images have more than one cats or dogs respectively.\n","metadata":{}},{"cell_type":"markdown","source":"\n<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Find median size of image for model building </h1>","metadata":{}},{"cell_type":"code","source":" \nimage_paths = [os.path.join(image_dir, filename) for filename in os.listdir(image_dir)]\n\nimage_width = []\nimage_height = []\nfor image_path in image_paths:\n    image = cv2.imread(image_path)\n    height, width, _ = image.shape\n    image_width.append(width)\n    image_height.append(height)\n\nmedian_width = np.median(image_width)\nmedian_height = np.median(image_height)\n\n\nprint('median_size:', median_width,  'X', median_height)","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:23:01.953158Z","iopub.execute_input":"2023-09-10T12:23:01.953549Z","iopub.status.idle":"2023-09-10T12:23:46.638888Z","shell.execute_reply.started":"2023-09-10T12:23:01.953511Z","shell.execute_reply":"2023-09-10T12:23:46.637732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Since CNN models can process square images thus setting the image size for processing as \n370 X 370. ","metadata":{}},{"cell_type":"markdown","source":"\n\n<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Create train, validation and test datasets </h1>","metadata":{}},{"cell_type":"code","source":"labels = data['label']\nX_train, X_temp = train_test_split(data, test_size=0.2, stratify=labels, random_state = 23)\n\nlabel_test_val = X_temp['label']\nX_test, X_val = train_test_split(X_temp, test_size=0.5, stratify=label_test_val, random_state = 23)\n\nprint ('X_train:', X_train['label'].value_counts())\n\nprint ('X_val:', X_val['label'].value_counts())\n\nprint ('X_test:', X_test['label'].value_counts())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"All three splits of data has both categories in the same proportion (equally distributed) as that in the original data. ","metadata":{}},{"cell_type":"markdown","source":"<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Create image data generator\n </h1>","metadata":{}},{"cell_type":"code","source":"batch_size = 64\nsize = (370, 370)\nidg = tf.keras.preprocessing.image.ImageDataGenerator(preprocessing_function = tf.keras.applications.vgg16.preprocess_input)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_idg = idg.flow_from_dataframe(X_train, \"train/\", x_col= \"filename\", y_col= \"label\",\n                                    batch_size = batch_size,\n                                    target_size=size)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_idg = idg.flow_from_dataframe(X_val, \"train/\", x_col=\"filename\", y_col=\"label\",\n                                  batch_size = batch_size,\n                                  target_size = size, shuffle = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_idg = idg.flow_from_dataframe(X_test, \"train/\", x_col= \"filename\", y_col= \"label\",\n                                    batch_size = batch_size,\n                                    target_size=size, shuffle = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Set shuffle = False for validation and test dataset. By setting shuffle=False, the samples will be processed in the same order as they appear in the dataframe.","metadata":{}},{"cell_type":"markdown","source":"<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Download vgg16 model and freeze the weights\n </h1>","metadata":{}},{"cell_type":"code","source":"vgg16_model = tf.keras.applications.vgg16.VGG16(include_top=False, input_shape=(370, 370, 3))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in vgg16_model.layers:\n  layer.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"By setting layer.trainable = False, freezing the weights of all the layers in the VGG16 model.The vgg16 derived weights will not be trained during the training of final model.","metadata":{}},{"cell_type":"markdown","source":"\n<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Define functional model\n </h1>","metadata":{}},{"cell_type":"code","source":"flat = tf.keras.layers.Flatten() (vgg16_model.output)\ndropout1 = tf.keras.layers.Dropout(0.2, name=\"Dropout1\") (flat)\ndense1 = tf.keras.layers.Dense(128, activation=\"relu\") (dropout1)\ndropout2 = tf.keras.layers.Dropout(0.2, name=\"Dropout2\")(dense1)\noutput = tf.keras.layers.Dense(2, activation=\"softmax\") (dropout2)\n\nfinal_model = tf.keras.models.Model(inputs=[vgg16_model.input], outputs=[output])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Plot the final model\n </h1>","metadata":{}},{"cell_type":"code","source":"tf.keras.utils.plot_model(final_model, show_shapes = True, show_layer_names=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install visualkeras\nimport visualkeras\nvisualkeras.layered_view(final_model, legend=True) ","metadata":{"execution":{"iopub.status.busy":"2023-09-10T12:50:43.893188Z","iopub.execute_input":"2023-09-10T12:50:43.893565Z","iopub.status.idle":"2023-09-10T12:50:55.530835Z","shell.execute_reply.started":"2023-09-10T12:50:43.893532Z","shell.execute_reply":"2023-09-10T12:50:55.529438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\"> Compile the model\n </h1>","metadata":{}},{"cell_type":"code","source":"final_model.compile(optimizer='adam',\n                    loss=tf.keras.losses.categorical_crossentropy,\n                    metrics = [\"acc\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" <h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">Create callback\n </h1>","metadata":{}},{"cell_type":"code","source":"model_ckpt = tf.keras.callbacks.ModelCheckpoint(\"DogCat\",\n                                                monitor=\"val_loss\",\n                                                save_best_only=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The ModelCheckpoint callback will save the best model during training based on the validation loss. \n\nThe saved model will be stored with the prefix \"DogCat\".","metadata":{}},{"cell_type":"markdown","source":" <h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">Train the model\n </h1>","metadata":{}},{"cell_type":"code","source":"history = final_model.fit(train_idg, batch_size=batch_size, validation_data=val_idg, epochs = 8, callbacks=[model_ckpt])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" <h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">Evaluate accuracy and loss for the model\n </h1>","metadata":{}},{"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs_range = range(8)\n\nplt.figure(figsize=(8, 8))\nplt.subplot(1, 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(1, 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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Validation loss start increasing after 3 epochs.","metadata":{}},{"cell_type":"markdown","source":"\n<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">Check the accuracy of the model on test subset\n </h1>","metadata":{}},{"cell_type":"code","source":"cat_dog_model = tf.keras.models.load_model(\"DogCat\")\n\nresult = cat_dog_model.predict(test_idg)\n\nresult_argmax = np.argmax(result, axis=1)\n\ny_true = test_idg.labels\n\ny_pred = result_argmax\n\naccuracy = (y_pred == y_true).mean()\n\nprint(\"Test Accuracy:\", accuracy)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Vgg16 rocks! 98% accuracy  in our test subset that we split from training data.","metadata":{}},{"cell_type":"code","source":"print(classification_report(y_true, y_pred))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Both the classes are classified well.","metadata":{}},{"cell_type":"markdown","source":"\n\n<h1  id=\"5\" style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:red;\n           font-size:350%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">Make predictions on kaggle test data for submission.\n </h1>","metadata":{}},{"cell_type":"markdown","source":"Unzip and extract test data","metadata":{}},{"cell_type":"code","source":"\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats/test1.zip', 'r') as test1_zip:\n    test1_zip.extractall('.')  \ntest_dir = \"../working/test1/\"\nfilenames = os.listdir(test_dir)\ntest_data = pd.DataFrame({\"filename\": filenames})\ntest_data['label'] = 'unknown'\ntest_data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Create data genenerator for test data","metadata":{}},{"cell_type":"code","source":"\ntest1_idg =  idg.flow_from_dataframe(test_data, \"test1/\", x_col= \"filename\",y_col = 'label',\n                                    batch_size = batch_size,\n                                    target_size=size, shuffle = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Make predictions on test data","metadata":{}},{"cell_type":"code","source":"test1_predict = cat_dog_model.predict(test1_idg)\n\ntest1_predict_argmax = np.argmax(test1_predict, axis=1)\n\ny_test_pred = test1_predict_argmax\n\ntest_data['label'] = y_test_pred\n\ntest_data.head()\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_idg.class_indices","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_mapping = {0: 'cat', 1: 'dog'}\ntest_data['label'] = test_data['label'].map(label_mapping)\ntest_data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Visualize the predicted results","metadata":{}},{"cell_type":"code","source":"fig, axes = plt.subplots(1, 5, figsize=(20, 4))\nfor idx in range(5):\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()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Made quite well predictions!","metadata":{}},{"cell_type":"markdown","source":"If you find the notebook helpful - Upvote","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"}}