{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30787,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Import Libraries**","metadata":{}},{"cell_type":"code","source":"import os              \nimport numpy as np      \nimport pandas as pd    \nimport random as rnd   \nimport matplotlib.pyplot as plt  \n%matplotlib inline      \n\n\nfrom sklearn.model_selection import train_test_split  \n\nimport keras                         \nfrom keras.models import Sequential  \nfrom keras.utils import to_categorical  \nfrom keras.preprocessing.image import load_img  \nfrom keras.layers import Flatten, Dense, Dropout  \nfrom keras.layers import Conv2D, MaxPool2D, BatchNormalization, Activation  \nimport cv2\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator \n\nprint(os.listdir(\"/kaggle/input/dogs-vs-cats\"))  ","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:33:13.845329Z","iopub.execute_input":"2024-10-16T08:33:13.845793Z","iopub.status.idle":"2024-10-16T08:33:27.282836Z","shell.execute_reply.started":"2024-10-16T08:33:13.845755Z","shell.execute_reply":"2024-10-16T08:33:27.281764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport io\nimport zipfile","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:33:27.285345Z","iopub.execute_input":"2024-10-16T08:33:27.286454Z","iopub.status.idle":"2024-10-16T08:33:27.291112Z","shell.execute_reply.started":"2024-10-16T08:33:27.286377Z","shell.execute_reply":"2024-10-16T08:33:27.289928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Preprocessing**","metadata":{}},{"cell_type":"code","source":"new_size = (128, 128)\n\ndef preprocess(input_zip, size=new_size):\n    images_processed = []\n    \n    with zipfile.ZipFile(input_zip, 'r') as archive_zip:\n        archives = archive_zip.namelist()\n        \n        images = [archive for archive in archives if archive.endswith(('.png', '.jpg', '.jpeg'))]\n        \n        for img_path in images:\n            with archive_zip.open(img_path) as image_zip:\n                img = Image.open(io.BytesIO(image_zip.read()))\n                \n                img = img.convert('L')\n                \n                # Apply Gaussian blur to reduce noise\n                img_array = np.array(img)\n                img_array = cv2.GaussianBlur(img_array, (5, 5), 0)\n                img = Image.fromarray(img_array)\n                \n                img = img.resize(size)\n                \n                img_array = np.array(img) / 255.0\n                \n                images_processed.append(img_array)\n    \n    dataset = np.array(images_processed)\n    \n    return dataset","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:33:27.292665Z","iopub.execute_input":"2024-10-16T08:33:27.293091Z","iopub.status.idle":"2024-10-16T08:33:27.327941Z","shell.execute_reply.started":"2024-10-16T08:33:27.293037Z","shell.execute_reply":"2024-10-16T08:33:27.326853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = preprocess(\"/kaggle/input/dogs-vs-cats/train.zip\")","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:33:27.329469Z","iopub.execute_input":"2024-10-16T08:33:27.330232Z","iopub.status.idle":"2024-10-16T08:35:03.961360Z","shell.execute_reply.started":"2024-10-16T08:33:27.330178Z","shell.execute_reply":"2024-10-16T08:35:03.960438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[0]","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:03.964996Z","iopub.execute_input":"2024-10-16T08:35:03.965328Z","iopub.status.idle":"2024-10-16T08:35:03.978138Z","shell.execute_reply.started":"2024-10-16T08:35:03.965293Z","shell.execute_reply":"2024-10-16T08:35:03.977022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = preprocess(\"/kaggle/input/dogs-vs-cats/test1.zip\")","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:03.979698Z","iopub.execute_input":"2024-10-16T08:35:03.980032Z","iopub.status.idle":"2024-10-16T08:35:49.798165Z","shell.execute_reply.started":"2024-10-16T08:35:03.979996Z","shell.execute_reply":"2024-10-16T08:35:49.797012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test[0]","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:49.799742Z","iopub.execute_input":"2024-10-16T08:35:49.800068Z","iopub.status.idle":"2024-10-16T08:35:49.807190Z","shell.execute_reply.started":"2024-10-16T08:35:49.800035Z","shell.execute_reply":"2024-10-16T08:35:49.806032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Visualisation**","metadata":{}},{"cell_type":"code","source":"imgplot = plt.imshow(train[0])","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:49.808326Z","iopub.execute_input":"2024-10-16T08:35:49.808684Z","iopub.status.idle":"2024-10-16T08:35:50.115142Z","shell.execute_reply.started":"2024-10-16T08:35:49.808641Z","shell.execute_reply":"2024-10-16T08:35:50.114154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10,10)) \n\nfor i in range(25):\n    plt.subplot(5,5,i+1)    # the number of images in the grid is 5*5 (25)\n    plt.imshow(train[i])\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:50.116508Z","iopub.execute_input":"2024-10-16T08:35:50.116821Z","iopub.status.idle":"2024-10-16T08:35:53.321519Z","shell.execute_reply.started":"2024-10-16T08:35:50.116787Z","shell.execute_reply":"2024-10-16T08:35:53.320315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10,10)) \n\nfor i in range(25):\n    plt.subplot(5,5,i+1)    # the number of images in the grid is 5*5 (25)\n    plt.imshow(test[i])\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:53.322971Z","iopub.execute_input":"2024-10-16T08:35:53.323376Z","iopub.status.idle":"2024-10-16T08:35:56.283069Z","shell.execute_reply.started":"2024-10-16T08:35:53.323316Z","shell.execute_reply":"2024-10-16T08:35:56.282029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# extract class tags\ndef extract_tags(input_zip):\n    results = []\n    with zipfile.ZipFile(input_zip, 'r') as archive_zip:\n        archives = archive_zip.namelist()\n        \n        images = [archive for archive in archives if archive.endswith(('.png', '.jpg', '.jpeg'))]\n        \n        for img_path in images:\n            if 'dog' in img_path.lower():\n                results.append(('dog', img_path))\n            elif 'cat' in img_path.lower():\n                results.append(('cat', img_path))\n            else:\n                results.append(('unknown', img_path))\n        \n    return results","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:56.284498Z","iopub.execute_input":"2024-10-16T08:35:56.284827Z","iopub.status.idle":"2024-10-16T08:35:56.292937Z","shell.execute_reply.started":"2024-10-16T08:35:56.284791Z","shell.execute_reply":"2024-10-16T08:35:56.291861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels = extract_tags(\"/kaggle/input/dogs-vs-cats/train.zip\")","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:56.294310Z","iopub.execute_input":"2024-10-16T08:35:56.294678Z","iopub.status.idle":"2024-10-16T08:35:56.885846Z","shell.execute_reply.started":"2024-10-16T08:35:56.294646Z","shell.execute_reply":"2024-10-16T08:35:56.884944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_labels = extract_tags(\"/kaggle/input/dogs-vs-cats/test1.zip\")","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:56.887029Z","iopub.execute_input":"2024-10-16T08:35:56.887332Z","iopub.status.idle":"2024-10-16T08:35:57.039069Z","shell.execute_reply.started":"2024-10-16T08:35:56.887300Z","shell.execute_reply":"2024-10-16T08:35:57.037970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels[0:10]","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:57.043314Z","iopub.execute_input":"2024-10-16T08:35:57.043630Z","iopub.status.idle":"2024-10-16T08:35:57.050461Z","shell.execute_reply.started":"2024-10-16T08:35:57.043598Z","shell.execute_reply":"2024-10-16T08:35:57.049395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Train Test Split**","metadata":{}},{"cell_type":"code","source":"train_binary = np.array([1 if label == 'dog' else 0 for label, _ in train_labels])\n\n# Train split\nX_train, X_test, y_train, y_test = train_test_split(train, train_binary, test_size=0.2, random_state=42, stratify = train_binary)\n\n# Validation-Test Split\nX_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42, stratify = y_train)","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:57.051860Z","iopub.execute_input":"2024-10-16T08:35:57.052194Z","iopub.status.idle":"2024-10-16T08:35:58.796102Z","shell.execute_reply.started":"2024-10-16T08:35:57.052160Z","shell.execute_reply":"2024-10-16T08:35:58.795164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Stratify** - Ensures that the distribution of classes within the training and testing sets reflect the original dataset’s composition","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\n\nplt.figure(figsize=(6, 4))\nsns.countplot(x=y_train, palette='Set2')\n\nplt.title(\"Frequency Distribution of Labels in y_train\")\nplt.xlabel(\"Label\")\nplt.ylabel(\"Frequency\")\nplt.xticks([0, 1], ['Class 0', 'Class 1'])\n\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:58.797237Z","iopub.execute_input":"2024-10-16T08:35:58.797580Z","iopub.status.idle":"2024-10-16T08:35:59.073031Z","shell.execute_reply.started":"2024-10-16T08:35:58.797547Z","shell.execute_reply":"2024-10-16T08:35:59.072028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(6, 4))\nsns.countplot(x=y_val, palette='Set2')\n\nplt.title(\"Frequency Distribution of Labels in y_val\")\nplt.xlabel(\"Label\")\nplt.ylabel(\"Frequency\")\nplt.xticks([0, 1], ['Class 0', 'Class 1'])\n\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:59.074499Z","iopub.execute_input":"2024-10-16T08:35:59.074972Z","iopub.status.idle":"2024-10-16T08:35:59.337145Z","shell.execute_reply.started":"2024-10-16T08:35:59.074914Z","shell.execute_reply":"2024-10-16T08:35:59.336256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test_labels[0:20]","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:59.338232Z","iopub.execute_input":"2024-10-16T08:35:59.338546Z","iopub.status.idle":"2024-10-16T08:35:59.342801Z","shell.execute_reply.started":"2024-10-16T08:35:59.338512Z","shell.execute_reply":"2024-10-16T08:35:59.341869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check number of channel in image\n# len(X_train.shape)","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:59.343818Z","iopub.execute_input":"2024-10-16T08:35:59.344099Z","iopub.status.idle":"2024-10-16T08:35:59.352926Z","shell.execute_reply.started":"2024-10-16T08:35:59.344054Z","shell.execute_reply":"2024-10-16T08:35:59.352121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Model**","metadata":{}},{"cell_type":"code","source":"from keras.layers import Input\nfrom keras.optimizers import Adam\n\n\nmodel = Sequential()\n\nmodel.add(Input(shape=(128, 128, 1)))  \n\n\nmodel.add(Conv2D(32, (3, 3), padding='same'))\nmodel.add(BatchNormalization())  \nmodel.add(Activation('relu'))    \nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(64, (3, 3), padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\n\nmodel.add(Conv2D(128, (3, 3), padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(256, (3, 3), padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\n# model.add(MaxPool2D(pool_size=(2, 2)))\n\n\nmodel.add(Flatten())\n\nmodel.add(Dense(512))  \nmodel.add(Activation('relu'))\n# model.add(Dropout(0.2))  \n\nmodel.add(Dense(256))  \nmodel.add(Activation('relu'))\n# model.add(Dropout(0.2)) \n\nmodel.add(Dense(1))       \nmodel.add(Activation('sigmoid'))  \n\n\nmodel.summary()\n\nmodel.compile(\n    loss='binary_crossentropy',\n    optimizer=Adam(learning_rate=1e-4),                       \n    metrics=['accuracy']                  \n)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:35:59.354105Z","iopub.execute_input":"2024-10-16T08:35:59.354516Z","iopub.status.idle":"2024-10-16T08:36:00.365766Z","shell.execute_reply.started":"2024-10-16T08:35:59.354449Z","shell.execute_reply":"2024-10-16T08:36:00.364953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train.shape)","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:36:00.367010Z","iopub.execute_input":"2024-10-16T08:36:00.367405Z","iopub.status.idle":"2024-10-16T08:36:00.372498Z","shell.execute_reply.started":"2024-10-16T08:36:00.367361Z","shell.execute_reply":"2024-10-16T08:36:00.371597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_test.shape)","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:36:00.373604Z","iopub.execute_input":"2024-10-16T08:36:00.373925Z","iopub.status.idle":"2024-10-16T08:36:00.383532Z","shell.execute_reply.started":"2024-10-16T08:36:00.373893Z","shell.execute_reply":"2024-10-16T08:36:00.382795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Early Stopping**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.callbacks import EarlyStopping\n\nearly_stopping = EarlyStopping(\n    monitor='val_loss',  \n    patience=3,         \n    restore_best_weights=True \n)","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:36:00.384709Z","iopub.execute_input":"2024-10-16T08:36:00.385031Z","iopub.status.idle":"2024-10-16T08:36:00.395145Z","shell.execute_reply.started":"2024-10-16T08:36:00.384997Z","shell.execute_reply":"2024-10-16T08:36:00.394364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(X_train, y_train, epochs=20, \n                    validation_data=(X_val, y_val),\n                       batch_size=8, \n    callbacks=[early_stopping])","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:36:00.396441Z","iopub.execute_input":"2024-10-16T08:36:00.396856Z","iopub.status.idle":"2024-10-16T08:38:27.411124Z","shell.execute_reply.started":"2024-10-16T08:36:00.396794Z","shell.execute_reply":"2024-10-16T08:38:27.409983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nimport seaborn as sns\n\ny_pred = model.predict(X_test)\n\nif len(y_pred.shape) > 1 and y_pred.shape[1] > 1:\n    y_pred_classes = np.argmax(y_pred, axis=1)  \nelse:\n    y_pred_classes = (y_pred > 0.5).astype(int)  \n\n\nif len(y_test.shape) > 1 and y_test.shape[1] > 1:\n    y_true = np.argmax(y_test, axis=1)  \nelse:\n    y_true = y_test  \n\nconf_matrix = confusion_matrix(y_true, y_pred_classes)\n\nplt.figure(figsize=(10, 8))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')\nplt.xlabel('Predicted Labels')\nplt.ylabel('True Labels')\nplt.title('Confusion Matrix')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:40:53.159229Z","iopub.execute_input":"2024-10-16T08:40:53.160612Z","iopub.status.idle":"2024-10-16T08:40:54.621130Z","shell.execute_reply.started":"2024-10-16T08:40:53.160555Z","shell.execute_reply":"2024-10-16T08:40:54.620169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['accuracy'], label='accuracy')\nplt.plot(history.history['val_accuracy'], label = 'val_accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.ylim([0.5, 1])\nplt.legend(loc='lower right')\n\ntest_loss, test_acc = model.evaluate(X_test,  y_test, verbose=2)","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:39:56.349455Z","iopub.execute_input":"2024-10-16T08:39:56.349895Z","iopub.status.idle":"2024-10-16T08:39:58.742007Z","shell.execute_reply.started":"2024-10-16T08:39:56.349854Z","shell.execute_reply":"2024-10-16T08:39:58.740962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_acc","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:40:04.227920Z","iopub.execute_input":"2024-10-16T08:40:04.228282Z","iopub.status.idle":"2024-10-16T08:40:04.234977Z","shell.execute_reply.started":"2024-10-16T08:40:04.228247Z","shell.execute_reply":"2024-10-16T08:40:04.233865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualising Predictions**","metadata":{}},{"cell_type":"code","source":"import random\nnum_images = 25\n\nrandom_indices = random.sample(range(len(X_test)), num_images)\n\nplt.figure(figsize=(10, 10))\n\nfor i, idx in enumerate(random_indices):\n    plt.subplot(5, 5, i + 1)\n    plt.imshow(X_test[idx])\n    plt.axis('off')\n\n    img = np.expand_dims(X_test[idx], axis=0)\n    prediction = model.predict(img)\n    predicted_label = np.argmax(prediction, axis=-1)\n\n    plt.title(f'Pred: {predicted_label[0]}')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-16T08:42:38.457183Z","iopub.execute_input":"2024-10-16T08:42:38.457890Z","iopub.status.idle":"2024-10-16T08:42:43.018744Z","shell.execute_reply.started":"2024-10-16T08:42:38.457846Z","shell.execute_reply":"2024-10-16T08:42:43.017695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}