{"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":"code","source":"import os\nimport zipfile\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import load_img\nfrom tensorflow.keras.preprocessing.image import img_to_array\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, GlobalAveragePooling2D\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-11-16T20:44:33.694784Z","iopub.execute_input":"2024-11-16T20:44:33.695175Z","iopub.status.idle":"2024-11-16T20:44:33.701835Z","shell.execute_reply.started":"2024-11-16T20:44:33.695131Z","shell.execute_reply":"2024-11-16T20:44:33.700794Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(tf.test.gpu_device_name())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:33.706120Z","iopub.execute_input":"2024-11-16T20:44:33.706453Z","iopub.status.idle":"2024-11-16T20:44:33.718330Z","shell.execute_reply.started":"2024-11-16T20:44:33.706420Z","shell.execute_reply":"2024-11-16T20:44:33.717481Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Extract datasets\ndata_path = \"/kaggle/input/dogs-vs-cats/\"\ntrain_zip = os.path.join(data_path, \"train.zip\")\ntest_zip = os.path.join(data_path, \"test1.zip\")\noutput_dir = \"/kaggle/working/dataset\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:33.719949Z","iopub.execute_input":"2024-11-16T20:44:33.720256Z","iopub.status.idle":"2024-11-16T20:44:33.727300Z","shell.execute_reply.started":"2024-11-16T20:44:33.720223Z","shell.execute_reply":"2024-11-16T20:44:33.726516Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Extract train.zip\nif not os.path.exists(output_dir):\n    os.makedirs(output_dir)\nwith zipfile.ZipFile(train_zip, 'r') as zip_ref:\n    zip_ref.extractall(output_dir)\n\ntrain_dir = os.path.join(output_dir, \"train\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:33.728686Z","iopub.execute_input":"2024-11-16T20:44:33.728984Z","iopub.status.idle":"2024-11-16T20:44:40.476763Z","shell.execute_reply.started":"2024-11-16T20:44:33.728953Z","shell.execute_reply":"2024-11-16T20:44:40.475922Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Organize data into subfolders for dogs and cats\norganized_dir = \"/kaggle/working/organized_dataset\"\ntrain_organized_dir = os.path.join(organized_dir, \"train\")\nval_organized_dir = os.path.join(organized_dir, \"validation\")\nif not os.path.exists(train_organized_dir):\n    os.makedirs(os.path.join(train_organized_dir, \"dogs\"))\n    os.makedirs(os.path.join(train_organized_dir, \"cats\"))\n    os.makedirs(os.path.join(val_organized_dir, \"dogs\"))\n    os.makedirs(os.path.join(val_organized_dir, \"cats\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:40.478422Z","iopub.execute_input":"2024-11-16T20:44:40.478731Z","iopub.status.idle":"2024-11-16T20:44:40.484908Z","shell.execute_reply.started":"2024-11-16T20:44:40.478697Z","shell.execute_reply":"2024-11-16T20:44:40.484082Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Split data into training and validation sets\nfrom sklearn.model_selection import train_test_split\nall_images = os.listdir(train_dir)\ndogs = [img for img in all_images if img.startswith(\"dog\")]\ncats = [img for img in all_images if img.startswith(\"cat\")]\n\ndog_train, dog_val = train_test_split(dogs, test_size=0.2, random_state=42)\ncat_train, cat_val = train_test_split(cats, test_size=0.2, random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:40.486114Z","iopub.execute_input":"2024-11-16T20:44:40.486433Z","iopub.status.idle":"2024-11-16T20:44:41.477244Z","shell.execute_reply.started":"2024-11-16T20:44:40.486399Z","shell.execute_reply":"2024-11-16T20:44:41.476458Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Copy files to organized directories\nimport shutil\ndef copy_files(file_list, src_dir, dest_dir):\n    for file in file_list:\n        shutil.copy(os.path.join(src_dir, file), dest_dir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:41.479176Z","iopub.execute_input":"2024-11-16T20:44:41.479504Z","iopub.status.idle":"2024-11-16T20:44:41.484247Z","shell.execute_reply.started":"2024-11-16T20:44:41.479470Z","shell.execute_reply":"2024-11-16T20:44:41.483386Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"copy_files(dog_train, train_dir, os.path.join(train_organized_dir, \"dogs\"))\ncopy_files(dog_val, train_dir, os.path.join(val_organized_dir, \"dogs\"))\ncopy_files(cat_train, train_dir, os.path.join(train_organized_dir, \"cats\"))\ncopy_files(cat_val, train_dir, os.path.join(val_organized_dir, \"cats\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:41.485232Z","iopub.execute_input":"2024-11-16T20:44:41.485544Z","iopub.status.idle":"2024-11-16T20:44:45.399662Z","shell.execute_reply.started":"2024-11-16T20:44:41.485509Z","shell.execute_reply":"2024-11-16T20:44:45.398616Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Count the number of images in each class\ndog_count = len(os.listdir(os.path.join(train_organized_dir, 'dogs')))\ncat_count = len(os.listdir(os.path.join(train_organized_dir, 'cats')))\n\nprint(f\"Number of Dog Images: {dog_count}\")\nprint(f\"Number of Cat Images: {cat_count}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:45.400923Z","iopub.execute_input":"2024-11-16T20:44:45.401267Z","iopub.status.idle":"2024-11-16T20:44:45.419487Z","shell.execute_reply.started":"2024-11-16T20:44:45.401223Z","shell.execute_reply":"2024-11-16T20:44:45.418608Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Collect 20 random images (10 dogs + 10 cats)\ndog_images = np.random.choice(os.listdir(os.path.join(train_organized_dir, 'dogs')), 10, replace=False)\ncat_images = np.random.choice(os.listdir(os.path.join(train_organized_dir, 'cats')), 10, replace=False)\n\nsample_images = []\nsample_labels = []\nfor img_name in dog_images:\n    sample_images.append(os.path.join(train_organized_dir, 'dogs', img_name))\n    sample_labels.append('Dog')\n\nfor img_name in cat_images:\n    sample_images.append(os.path.join(train_organized_dir, 'cats', img_name))\n    sample_labels.append('Cat')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:45.420670Z","iopub.execute_input":"2024-11-16T20:44:45.421468Z","iopub.status.idle":"2024-11-16T20:44:46.441591Z","shell.execute_reply.started":"2024-11-16T20:44:45.421419Z","shell.execute_reply":"2024-11-16T20:44:46.440764Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Display the images\nplt.figure(figsize=(20, 10))\nfor i in range(20):\n    plt.subplot(4, 5, i + 1)\n    img = load_img(sample_images[i], target_size=(128, 128))\n    plt.imshow(img)\n    plt.axis('off')\n    plt.title(sample_labels[i])\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:46.442709Z","iopub.execute_input":"2024-11-16T20:44:46.443033Z","iopub.status.idle":"2024-11-16T20:44:48.577319Z","shell.execute_reply.started":"2024-11-16T20:44:46.443000Z","shell.execute_reply":"2024-11-16T20:44:48.576215Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Data preprocessing\ntrain_datagen = ImageDataGenerator(\n    rescale=1.0/255,\n    rotation_range=30,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:48.578737Z","iopub.execute_input":"2024-11-16T20:44:48.579109Z","iopub.status.idle":"2024-11-16T20:44:48.584477Z","shell.execute_reply.started":"2024-11-16T20:44:48.579070Z","shell.execute_reply":"2024-11-16T20:44:48.583478Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_datagen = ImageDataGenerator(rescale=1.0/255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:48.587732Z","iopub.execute_input":"2024-11-16T20:44:48.588053Z","iopub.status.idle":"2024-11-16T20:44:48.594210Z","shell.execute_reply.started":"2024-11-16T20:44:48.588020Z","shell.execute_reply":"2024-11-16T20:44:48.593304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(\n    train_organized_dir,\n    target_size=(224, 224),\n    batch_size=32,\n    class_mode='binary'\n)\n\nvalidation_generator = val_datagen.flow_from_directory(\n    val_organized_dir,\n    target_size=(224, 224),\n    batch_size=32,\n    class_mode='binary'\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:48.595397Z","iopub.execute_input":"2024-11-16T20:44:48.595700Z","iopub.status.idle":"2024-11-16T20:44:49.268251Z","shell.execute_reply.started":"2024-11-16T20:44:48.595663Z","shell.execute_reply":"2024-11-16T20:44:49.267534Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Fine-tune a pre-trained model\nbase_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\nbase_model.trainable = False  # Freeze base layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:44:49.269471Z","iopub.execute_input":"2024-11-16T20:44:49.269850Z","iopub.status.idle":"2024-11-16T20:44:50.042735Z","shell.execute_reply.started":"2024-11-16T20:44:49.269800Z","shell.execute_reply":"2024-11-16T20:44:50.039905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_sequential = Sequential([\n    base_model,  # Add pre-trained MobileNetV2 as the first layer\n    Conv2D(256, (3, 3), activation='relu', padding='same'),\n    MaxPooling2D(pool_size=(2, 2)),\n    \n    Conv2D(512, (3, 3), activation='relu', padding='same'),\n    MaxPooling2D(pool_size=(2, 2)),\n    \n    # Global Average Pooling to reduce the spatial dimensions\n    GlobalAveragePooling2D(),\n    \n    # MLP layers for classification\n    Dense(512, activation='relu'),\n    Dropout(0.5),\n    Dense(128, activation='relu'),\n    Dropout(0.5),\n    \n    # Output layer with sigmoid activation for binary classification\n    Dense(1, activation='sigmoid')\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:45:46.416881Z","iopub.execute_input":"2024-11-16T20:45:46.417799Z","iopub.status.idle":"2024-11-16T20:45:46.439371Z","shell.execute_reply.started":"2024-11-16T20:45:46.417739Z","shell.execute_reply":"2024-11-16T20:45:46.438227Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_sequential.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n    loss='binary_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:45:47.228999Z","iopub.execute_input":"2024-11-16T20:45:47.229814Z","iopub.status.idle":"2024-11-16T20:45:47.239146Z","shell.execute_reply.started":"2024-11-16T20:45:47.229775Z","shell.execute_reply":"2024-11-16T20:45:47.238370Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_sequential.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:45:48.371684Z","iopub.execute_input":"2024-11-16T20:45:48.372030Z","iopub.status.idle":"2024-11-16T20:45:48.402486Z","shell.execute_reply.started":"2024-11-16T20:45:48.371997Z","shell.execute_reply":"2024-11-16T20:45:48.401636Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Train the Model\nwith tf.device('/GPU:0'):\n    model_sequential.fit(\n        train_generator,\n        validation_data=validation_generator,\n        epochs=5,\n        steps_per_epoch=train_generator.samples // train_generator.batch_size,\n        validation_steps=validation_generator.samples // validation_generator.batch_size)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:45:50.049754Z","iopub.execute_input":"2024-11-16T20:45:50.050706Z","iopub.status.idle":"2024-11-16T20:59:48.580976Z","shell.execute_reply.started":"2024-11-16T20:45:50.050646Z","shell.execute_reply":"2024-11-16T20:59:48.580065Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Unfreeze the base model for fine-tuning\nbase_model.trainable = True\nmodel_sequential.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5),\n    loss='binary_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:59:48.583065Z","iopub.execute_input":"2024-11-16T20:59:48.584015Z","iopub.status.idle":"2024-11-16T20:59:48.597047Z","shell.execute_reply.started":"2024-11-16T20:59:48.583964Z","shell.execute_reply":"2024-11-16T20:59:48.596258Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train the model and save the training history\nwith tf.device('/GPU:0'):\n    history = model_sequential.fit(\n        train_generator,\n        validation_data=validation_generator,\n        epochs=5,\n        steps_per_epoch=train_generator.samples // train_generator.batch_size,\n        validation_steps=validation_generator.samples // validation_generator.batch_size)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T20:59:48.598308Z","iopub.execute_input":"2024-11-16T20:59:48.598812Z","iopub.status.idle":"2024-11-16T21:14:28.011093Z","shell.execute_reply.started":"2024-11-16T20:59:48.598767Z","shell.execute_reply":"2024-11-16T21:14:28.010263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot training and validation loss\nepochs = range(1, len(history.history['loss']) + 1)\n\nplt.figure(figsize=(14, 5))\n\n# Plot loss\nplt.subplot(1, 2, 1)\nplt.plot(epochs, history.history['loss'], label='Training Loss')\nplt.plot(epochs, history.history['val_loss'], label='Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.title('Training and Validation Loss')\nplt.legend()\n\n# Plot accuracy\nplt.subplot(1, 2, 2)\nplt.plot(epochs, history.history['accuracy'], label='Training Accuracy')\nplt.plot(epochs, history.history['val_accuracy'], label='Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:28.013342Z","iopub.execute_input":"2024-11-16T21:14:28.013676Z","iopub.status.idle":"2024-11-16T21:14:28.547565Z","shell.execute_reply.started":"2024-11-16T21:14:28.013642Z","shell.execute_reply":"2024-11-16T21:14:28.546632Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Save the model\nmodel_sequential.save('/kaggle/working/dog_cat_classifier_sequential.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:28.548812Z","iopub.execute_input":"2024-11-16T21:14:28.549131Z","iopub.status.idle":"2024-11-16T21:14:29.109739Z","shell.execute_reply.started":"2024-11-16T21:14:28.549099Z","shell.execute_reply":"2024-11-16T21:14:29.108254Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Randomly select 10 images from each class in the validation set\ndog_val_images = np.random.choice(os.listdir(os.path.join(val_organized_dir, 'dogs')), 20, replace=False)\ncat_val_images = np.random.choice(os.listdir(os.path.join(val_organized_dir, 'cats')), 20, replace=False)\n\nimg_paths = []\ntrue_labels = []\n\nfor img_name in dog_val_images:\n    img_paths.append(os.path.join(val_organized_dir, 'dogs', img_name))\n    true_labels.append(0)  # Dog = 0\n\nfor img_name in cat_val_images:\n    img_paths.append(os.path.join(val_organized_dir, 'cats', img_name))\n    true_labels.append(1)  # Cat = 1\n\n# Prepare the images for the model\nimg_arrays = []\nfor img_path in img_paths:\n    img = load_img(img_path, target_size=(224, 224))\n    img_array = img_to_array(img) / 255.0\n    img_arrays.append(img_array)\n\nimg_arrays = np.array(img_arrays)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:29.111405Z","iopub.execute_input":"2024-11-16T21:14:29.111815Z","iopub.status.idle":"2024-11-16T21:14:29.184583Z","shell.execute_reply.started":"2024-11-16T21:14:29.111769Z","shell.execute_reply":"2024-11-16T21:14:29.183538Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Predict using the model\npredictions = model_sequential.predict(img_arrays)\npredicted_labels = (predictions > 0.5).astype(int)\n\n# Display images with actual and predicted labels\nplt.figure(figsize=(20, 10))\nfor i in range(20):\n    plt.subplot(4, 5, i + 1)\n    img = load_img(img_paths[i], target_size=(128, 128))\n    plt.imshow(img)\n    plt.axis('off')\n    true_label = \"Dog\" if true_labels[i] == 0 else \"Cat\"\n    pred_label = \"Dog\" if predicted_labels[i] == 0 else \"Cat\"\n    plt.title(f\"T: {true_label}, P: {pred_label}\")\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:29.185840Z","iopub.execute_input":"2024-11-16T21:14:29.186142Z","iopub.status.idle":"2024-11-16T21:14:36.602478Z","shell.execute_reply.started":"2024-11-16T21:14:29.186111Z","shell.execute_reply":"2024-11-16T21:14:36.601330Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Generate predictions on the entire validation dataset\nvalidation_generator.reset()  # Reset to ensure all data is processed\npredictions = model_sequential.predict(validation_generator, steps=validation_generator.samples // validation_generator.batch_size + 1)\n\n# Convert probabilities to binary predictions\npredicted_labels = (predictions > 0.5).astype(int).flatten()\n\n# Get true labels from the validation generator\ntrue_labels = validation_generator.classes[:len(predicted_labels)]  # Ensure matching lengths\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:36.603949Z","iopub.execute_input":"2024-11-16T21:14:36.604311Z","iopub.status.idle":"2024-11-16T21:14:49.346453Z","shell.execute_reply.started":"2024-11-16T21:14:36.604272Z","shell.execute_reply":"2024-11-16T21:14:49.345517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nimport seaborn as sns\n\n# Compute the confusion matrix\ncm = confusion_matrix(true_labels, predicted_labels)\n\n# Plot the confusion matrix\nplt.figure(figsize=(8, 6))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['Dog', 'Cat'], yticklabels=['Dog', 'Cat'])\nplt.xlabel('Predicted Labels')\nplt.ylabel('True Labels')\nplt.title('Confusion Matrix')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:49.347734Z","iopub.execute_input":"2024-11-16T21:14:49.348060Z","iopub.status.idle":"2024-11-16T21:14:49.612101Z","shell.execute_reply.started":"2024-11-16T21:14:49.348025Z","shell.execute_reply":"2024-11-16T21:14:49.611223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import classification_report\n\n# Generate the classification report\nreport = classification_report(true_labels, predicted_labels, target_names=['Dog', 'Cat'])\nprint(\"Classification Report:\\n\")\nprint(report)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-16T21:14:49.615213Z","iopub.execute_input":"2024-11-16T21:14:49.615587Z","iopub.status.idle":"2024-11-16T21:14:49.630602Z","shell.execute_reply.started":"2024-11-16T21:14:49.615552Z","shell.execute_reply":"2024-11-16T21:14:49.629731Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}