{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "private_outputs": true,
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "source": [
        "# ==========================================================\n",
        "# 1. IMPORT LIBRARIES\n",
        "# ==========================================================\n",
        "import tensorflow as tf\n",
        "from tensorflow.keras import layers, models\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "import os\n",
        "import zipfile\n",
        "import seaborn as sns\n",
        "from sklearn.metrics import confusion_matrix, classification_report\n",
        "\n",
        "print(\"TensorFlow Version:\", tf.__version__)\n",
        "\n",
        "# ==========================================================\n",
        "# 2. UPLOAD AND EXTRACT DATASET (COLAB)\n",
        "# ==========================================================\n",
        "from google.colab import files\n",
        "uploaded = files.upload()\n",
        "\n",
        "zip_file = None\n",
        "for file in uploaded.keys():\n",
        "    if file.endswith(\".zip\"):\n",
        "        zip_file = file\n",
        "\n",
        "if zip_file is None:\n",
        "    raise ValueError(\"Upload a ZIP dataset.\")\n",
        "\n",
        "extract_path = \"/content/intel_dataset2\"\n",
        "os.makedirs(extract_path, exist_ok=True)\n",
        "\n",
        "with zipfile.ZipFile(zip_file, 'r') as zip_ref:\n",
        "    zip_ref.extractall(extract_path)\n",
        "\n",
        "print(\"Dataset extracted to:\", extract_path)"
      ],
      "metadata": {
        "id": "FJjdJdPyR7OJ"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "\n",
        "# ==========================================================\n",
        "# 3. DATASET PARAMETERS\n",
        "# ==========================================================\n",
        "IMG_SIZE = (150,150)\n",
        "BATCH_SIZE = 32\n",
        "SEED = 42\n",
        "\n",
        "# ==========================================================\n",
        "# 4. LOAD DATASET\n",
        "# ==========================================================\n",
        "extract_path_test = \"/content/intel_dataset2/seg_test/seg_test\"\n",
        "extract_path_train = \"/content/intel_dataset2/seg_train/seg_train\"\n",
        "train_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
        "    extract_path_train,\n",
        "    validation_split=0.2,\n",
        "    subset=\"training\",\n",
        "    seed=SEED,\n",
        "    image_size=IMG_SIZE,\n",
        "    batch_size=BATCH_SIZE\n",
        ")\n",
        "\n",
        "val_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
        "    extract_path_train,\n",
        "    validation_split=0.2,\n",
        "    subset=\"validation\",\n",
        "    seed=SEED,\n",
        "    image_size=IMG_SIZE,\n",
        "    batch_size=BATCH_SIZE\n",
        ")\n",
        "\n",
        "class_names = train_ds.class_names\n",
        "num_classes = len(class_names)\n",
        "\n",
        "print(\"Classes:\", class_names)\n",
        "\n",
        "# ==========================================================\n",
        "# 5. DATASET OPTIMISATION\n",
        "# ==========================================================\n",
        "AUTOTUNE = tf.data.AUTOTUNE\n",
        "train_ds = train_ds.prefetch(buffer_size=AUTOTUNE)\n",
        "val_ds = val_ds.prefetch(buffer_size=AUTOTUNE)\n",
        "\n",
        "# ==========================================================\n",
        "# 6. VISUALISE SAMPLE IMAGES\n",
        "# ==========================================================\n",
        "plt.figure(figsize=(8,8))\n",
        "\n",
        "for images, labels in train_ds.take(1):\n",
        "    for i in range(9):\n",
        "        plt.subplot(3,3,i+1)\n",
        "        plt.imshow(images[i].numpy().astype(\"uint8\"))\n",
        "        plt.title(class_names[labels[i]])\n",
        "        plt.axis(\"off\")\n",
        "\n",
        "plt.show()"
      ],
      "metadata": {
        "id": "4FBB1NxJZSjb"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "rYvNuL5t3Hfn",
        "collapsed": true
      },
      "outputs": [],
      "source": [
        "\n",
        "\n",
        "# ==========================================================\n",
        "# 7. DATA AUGMENTATION\n",
        "# ==========================================================\n",
        "data_augmentation = models.Sequential([\n",
        "    layers.RandomFlip(\"horizontal\"),\n",
        "    layers.RandomRotation(0.1),\n",
        "    layers.RandomZoom(0.1)\n",
        "])\n",
        "\n",
        "# ==========================================================\n",
        "# 8. BUILD CNN MODEL (IMPROVED)\n",
        "# ==========================================================\n",
        "model = models.Sequential([\n",
        "\n",
        "    data_augmentation,\n",
        "    layers.Rescaling(1./255),\n",
        "\n",
        "    layers.Conv2D(32,3,activation='relu'),\n",
        "    layers.MaxPooling2D(),\n",
        "\n",
        "    layers.Conv2D(64,3,activation='relu'),\n",
        "    layers.MaxPooling2D(),\n",
        "\n",
        "    layers.Conv2D(128,3,activation='relu'),\n",
        "    layers.MaxPooling2D(),\n",
        "\n",
        "    layers.Conv2D(256,3,activation='relu'),\n",
        "    layers.MaxPooling2D(),\n",
        "\n",
        "    layers.Flatten(),\n",
        "\n",
        "    layers.Dense(256, activation='relu'),\n",
        "    layers.Dropout(0.5),\n",
        "\n",
        "    layers.Dense(num_classes, activation='softmax')\n",
        "])\n",
        "\n",
        "model.compile(\n",
        "    optimizer='adam',\n",
        "    loss='sparse_categorical_crossentropy',\n",
        "    metrics=['accuracy']\n",
        ")\n",
        "\n",
        "model.summary()\n",
        "\n",
        "# ==========================================================\n",
        "# 9. EARLY STOPPING\n",
        "# ==========================================================\n",
        "early_stop = tf.keras.callbacks.EarlyStopping(\n",
        "    monitor='val_loss',\n",
        "    patience=3,\n",
        "    restore_best_weights=True\n",
        ")\n",
        "\n",
        "# ==========================================================\n",
        "# 10. TRAIN MODEL\n",
        "# ==========================================================\n",
        "history = model.fit(\n",
        "    train_ds,\n",
        "    validation_data=val_ds,\n",
        "    epochs=20,\n",
        "    callbacks=[early_stop]\n",
        ")\n",
        "\n",
        "# ==========================================================\n",
        "# 11. PLOT TRAINING RESULTS\n",
        "# ==========================================================\n",
        "plt.figure(figsize=(8,5))\n",
        "\n",
        "plt.plot(history.history['accuracy'], label='Training Accuracy')\n",
        "plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n",
        "\n",
        "plt.xlabel(\"Epoch\")\n",
        "plt.ylabel(\"Accuracy\")\n",
        "plt.title(\"Training vs Validation Accuracy\")\n",
        "plt.legend()\n",
        "plt.show()\n",
        "\n",
        "# ==========================================================\n",
        "# 12. MODEL EVALUATION\n",
        "# ==========================================================\n",
        "loss, acc = model.evaluate(val_ds)\n",
        "\n",
        "print(\"Validation Accuracy:\", acc)\n",
        "\n",
        "# ==========================================================\n",
        "# 13. CONFUSION MATRIX\n",
        "# ==========================================================\n",
        "y_true = []\n",
        "y_pred = []\n",
        "\n",
        "for images, labels in val_ds:\n",
        "    preds = model.predict(images)\n",
        "    y_true.extend(labels.numpy())\n",
        "    y_pred.extend(np.argmax(preds, axis=1))\n",
        "\n",
        "cm = confusion_matrix(y_true, y_pred)\n",
        "\n",
        "plt.figure(figsize=(8,6))\n",
        "sns.heatmap(cm, annot=True, fmt=\"d\",\n",
        "            xticklabels=class_names,\n",
        "            yticklabels=class_names,\n",
        "            cmap=\"Blues\")\n",
        "\n",
        "plt.xlabel(\"Predicted\")\n",
        "plt.ylabel(\"Actual\")\n",
        "plt.title(\"Confusion Matrix\")\n",
        "plt.show()\n",
        "\n",
        "# ==========================================================\n",
        "# 14. CLASSIFICATION REPORT\n",
        "# ==========================================================\n",
        "print(classification_report(y_true, y_pred, target_names=class_names))"
      ]
    }
  ]
}