{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"},{"sourceId":8409759,"sourceType":"datasetVersion","datasetId":5005013}],"dockerImageVersionId":30919,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"**Importing Necessary Libraries**","metadata":{}},{"cell_type":"code","source":"pip install --upgrade pip","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T20:00:44.352642Z","iopub.execute_input":"2025-03-29T20:00:44.352893Z","iopub.status.idle":"2025-03-29T20:04:08.145613Z","shell.execute_reply.started":"2025-03-29T20:00:44.352872Z","shell.execute_reply":"2025-03-29T20:04:08.144631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install scikit-image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T20:06:34.21079Z","iopub.execute_input":"2025-03-29T20:06:34.211021Z","iopub.status.idle":"2025-03-29T20:06:38.553465Z","shell.execute_reply.started":"2025-03-29T20:06:34.211Z","shell.execute_reply":"2025-03-29T20:06:38.552408Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom skimage import exposure\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt \nimport tensorflow as tf\nfrom tensorflow import keras\nfrom PIL import Image as im\nfrom glob import glob\nimport seaborn as sns\nimport random\nimport imgaug.augmenters as iaa\nimport os\nimport albumentations as A\nimport gc\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelEncoder\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.models import Sequential, load_model\nfrom tensorflow.keras.models import Model\n\nfrom tensorflow.keras.applications import InceptionV3\nfrom tensorflow.keras.applications import DenseNet121\nfrom tensorflow.keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.applications import EfficientNetB0\n\nfrom tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropout,MaxPooling2D,BatchNormalization\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras import losses\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\nfrom sklearn import preprocessing\nfrom skimage import exposure,filters,color\n\n# from Preprocessing import *\nfrom sklearn.metrics import classification_report, accuracy_score,confusion_matrix, precision_score, recall_score, f1_score,roc_curve, roc_auc_score\nimport warnings \nwarnings.filterwarnings('ignore')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:16:36.862587Z","iopub.execute_input":"2025-03-29T21:16:36.862875Z","iopub.status.idle":"2025-03-29T21:16:36.86951Z","shell.execute_reply.started":"2025-03-29T21:16:36.862853Z","shell.execute_reply":"2025-03-29T21:16:36.868716Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<img src='https://media.springernature.com/lw685/springer-static/image/art%3A10.1186%2Fs12938-020-00766-3/MediaObjects/12938_2020_766_Fig1_HTML.png?as=webp'>","metadata":{}},{"cell_type":"markdown","source":"* [Microaneurysms Segmentation](#ms)\n* [Haemorrhages Segmentation](#hae)\n* [Hard Exudates Segmentation](#hes)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T08:19:05.125109Z","iopub.execute_input":"2024-05-15T08:19:05.125538Z","iopub.status.idle":"2024-05-15T08:19:05.166126Z","shell.execute_reply.started":"2024-05-15T08:19:05.125496Z","shell.execute_reply":"2024-05-15T08:19:05.164359Z"}}},{"cell_type":"markdown","source":"**Functions (Reading image, Training data, Preprocessing)**","metadata":{}},{"cell_type":"code","source":"def read_image(path,input_image_size=(512,512)):\n    image = cv2.imread(path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = cv2.resize(image,input_image_size)\n    return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:12:29.73696Z","iopub.execute_input":"2025-03-29T21:12:29.73734Z","iopub.status.idle":"2025-03-29T21:12:29.741847Z","shell.execute_reply.started":"2025-03-29T21:12:29.737311Z","shell.execute_reply":"2025-03-29T21:12:29.74078Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def read_segmentation_training_data(images_train_dir,masks_train_dir,images_train_listdir,masks_train_listdir,image_size = 512):\n\n    MASKS=np.zeros((1,image_size, image_size, 1), dtype=bool)\n    IMAGES=np.zeros((1,image_size, image_size, 3),dtype=np.uint8)\n\n    for j,file in enumerate(images_train_listdir):   ##the smaller, the faster\n        image = read_image(f\"{images_train_dir}/{file}\")\n        image_ex = np.expand_dims(image, axis=0)\n        IMAGES = np.vstack([IMAGES, image_ex])\n\n    images_train=np.array(IMAGES)[1:]\n\n    for j,file in enumerate(masks_train_listdir):   ##the smaller, the faster\n        mask = read_image(f\"{masks_train_dir}/{file}\") \n        mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)\n        mask = mask.reshape(512,512,1)\n        mask_ex = np.expand_dims(mask, axis=0)    \n        MASKS = np.vstack([MASKS, mask_ex])\n\n    masks_train=np.array(MASKS)[1:]\n    \n    print(images_train.shape,masks_train.shape)\n\n    return images_train,masks_train","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:12:30.961961Z","iopub.execute_input":"2025-03-29T21:12:30.962444Z","iopub.status.idle":"2025-03-29T21:12:30.971049Z","shell.execute_reply.started":"2025-03-29T21:12:30.962405Z","shell.execute_reply":"2025-03-29T21:12:30.970184Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def preprocess_images(images):\n    # Creating the pre-processing process\n    preprocessed_images = []\n    for image in images:\n        # Convert image to uint8\n        image_uint8 = image.astype(np.uint8)\n        # Split channels\n        b, green_channel, r = cv2.split(image_uint8)\n        # Apply CLAHE\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))\n        contrast_limit_image = clahe.apply(green_channel)\n        # Gamma correction\n        gamma_corrected_image = cv2.convertScaleAbs(contrast_limit_image, alpha=1.2)\n        # Gaussian filtering\n        filtered_image = filters.gaussian(contrast_limit_image, sigma=0.5)\n\n        preprocessed_images.append(filtered_image)\n    return np.array(preprocessed_images)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:12:30.983791Z","iopub.execute_input":"2025-03-29T21:12:30.98416Z","iopub.status.idle":"2025-03-29T21:12:30.994904Z","shell.execute_reply.started":"2025-03-29T21:12:30.984126Z","shell.execute_reply":"2025-03-29T21:12:30.99396Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load sample images (replace with actual image paths)\nimage_paths = '/kaggle/input/idrid-2018/IDRiD/Segmentation/Images/a. Training Set/'\nimages = [cv2.imread(img_path) for img_path in image_paths]\npreprocessed_images = preprocess_images(images)\n\n# Display the images\nfig, axes = plt.subplots(1, 3, figsize=(12, 4))\nfor i, ax in enumerate(axes):\n    ax.imshow(preprocessed_images[i], cmap='gray')\n    ax.axis('off')\n    ax.set_title(f'Preprocessed Image {i+1}')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T20:44:38.242084Z","iopub.execute_input":"2025-03-29T20:44:38.242396Z","iopub.status.idle":"2025-03-29T20:44:38.600287Z","shell.execute_reply.started":"2025-03-29T20:44:38.242371Z","shell.execute_reply":"2025-03-29T20:44:38.599096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\n\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T20:44:43.024841Z","iopub.execute_input":"2025-03-29T20:44:43.025158Z","iopub.status.idle":"2025-03-29T20:44:43.243355Z","shell.execute_reply.started":"2025-03-29T20:44:43.025125Z","shell.execute_reply":"2025-03-29T20:44:43.242511Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import skimage\nprint(skimage.__version__)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T02:44:00.481138Z","iopub.execute_input":"2025-03-29T02:44:00.481457Z","iopub.status.idle":"2025-03-29T02:44:00.498213Z","shell.execute_reply.started":"2025-03-29T02:44:00.481431Z","shell.execute_reply":"2025-03-29T02:44:00.497435Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"python -m pip install --upgrade pip","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T02:43:27.076805Z","iopub.execute_input":"2025-03-29T02:43:27.077125Z","iopub.status.idle":"2025-03-29T02:43:27.081344Z","shell.execute_reply.started":"2025-03-29T02:43:27.077099Z","shell.execute_reply":"2025-03-29T02:43:27.080426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install --upgrade scikit-image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T02:44:20.093288Z","iopub.execute_input":"2025-03-29T02:44:20.093592Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\nfrom skimage import filters\n\ndef preprocess_images(images):\n    preprocessed_images = []\n    \n    for image in images:\n        # Convert image to uint8\n        image_uint8 = image.astype(np.uint8)\n\n        # Extract Green Channel (Most Informative for Microaneurysms)\n        _, green_channel, _ = cv2.split(image_uint8)\n\n        # Apply CLAHE (Adaptive Histogram Equalization)\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))\n        contrast_enhanced = clahe.apply(green_channel)\n\n        # Apply Gaussian Blur to Reduce Noise\n        blurred_image = cv2.GaussianBlur(contrast_enhanced, (5, 5), sigmaX=2.0)\n\n        preprocessed_images.append(blurred_image)\n\n    return np.array(preprocessed_images)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:22:14.152803Z","iopub.execute_input":"2025-03-29T21:22:14.153236Z","iopub.status.idle":"2025-03-29T21:22:14.158795Z","shell.execute_reply.started":"2025-03-29T21:22:14.153201Z","shell.execute_reply":"2025-03-29T21:22:14.157799Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\n\ndef preprocess_images(images):\n    preprocessed_images = []\n    \n    for image in images:\n        # Convert image to uint8\n        image_uint8 = image.astype(np.uint8)\n\n        # Extract Green Channel (Best for MA detection)\n        _, green_channel, _ = cv2.split(image_uint8)\n\n        # Apply CLAHE (Adaptive Histogram Equalization)\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))\n        contrast_enhanced = clahe.apply(green_channel)\n\n        # Suppress Blood Vessels: Difference Image (Original - Gaussian Blur)\n        blurred = cv2.GaussianBlur(contrast_enhanced, (15, 15), 0)\n        vessel_suppressed = cv2.subtract(contrast_enhanced, blurred)\n\n        # Optional: Morphological Top-Hat Transformation to Highlight MAs\n        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))\n        tophat_image = cv2.morphologyEx(vessel_suppressed, cv2.MORPH_TOPHAT, kernel)\n\n        # Thresholding to Highlight MAs (Fine-tune Threshold Value)\n        _, ma_highlighted = cv2.threshold(tophat_image, 15, 255, cv2.THRESH_BINARY)\n\n        preprocessed_images.append(ma_highlighted)\n\n    return np.array(preprocessed_images)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:24:03.056429Z","iopub.execute_input":"2025-03-29T21:24:03.056867Z","iopub.status.idle":"2025-03-29T21:24:03.065243Z","shell.execute_reply.started":"2025-03-29T21:24:03.05683Z","shell.execute_reply":"2025-03-29T21:24:03.063864Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"'''import os\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom skimage import filters\n\ndef preprocess_images(images):\n    preprocessed_images = []\n    for image in images:\n        image_uint8 = image.astype(np.uint8)\n        b, green_channel, r = cv2.split(image_uint8)\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))\n        contrast_limit_image = clahe.apply(green_channel)\n        gamma_corrected_image = cv2.convertScaleAbs(contrast_limit_image, alpha=2.0)\n        filtered_image = filters.gaussian(contrast_limit_image, sigma=0.9)\n        preprocessed_images.append(filtered_image)\n    return np.array(preprocessed_images)\n'''\n\ndef load_images_from_folder(folder_path):\n    images = []\n    image_filenames = []\n    for filename in os.listdir(folder_path):\n        img_path = os.path.join(folder_path, filename)\n        img = cv2.imread(img_path)\n        if img is not None:\n            images.append(img)\n            image_filenames.append(filename)\n    return images, image_filenames\n\ndef save_images(images, filenames, output_folder):\n    if not os.path.exists(output_folder):\n        os.makedirs(output_folder)\n    for img, filename in zip(images, filenames):\n        img_path = os.path.join(output_folder, filename)\n        cv2.imwrite(img_path, (img * 255).astype(np.uint8))\n\ndef display_images(images, num_images=10):\n    plt.figure(figsize=(15, 5))\n    for i in range(min(num_images, len(images))):\n        plt.subplot(2, 5, i + 1)\n        plt.imshow(images[i], cmap='brg')\n        plt.axis('off')\n    plt.show()\n\n# Define paths\ninput_folder = \"/kaggle/input/idrid-2018/IDRiD/Segmentation/Images/a. Training Set/\"  # Replace with actual input folder path\noutput_folder = \"/kaggle/working/output_images/\"\n\n# Load images\nimages, filenames = load_images_from_folder(input_folder)\n\n# Preprocess images\npreprocessed_images = preprocess_images(images)\n\n# Save preprocessed images\nsave_images(preprocessed_images, filenames, output_folder)\n\n# Display first 10 images\ndisplay_images(preprocessed_images, 10)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:24:04.912297Z","iopub.execute_input":"2025-03-29T21:24:04.912599Z","iopub.status.idle":"2025-03-29T21:24:17.369686Z","shell.execute_reply.started":"2025-03-29T21:24:04.912576Z","shell.execute_reply":"2025-03-29T21:24:17.368822Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Defining UNET Model Archtecture**","metadata":{}},{"cell_type":"code","source":"# Define a convolutional block\ndef conv_block(input, num_filters):\n    # Convolution layer with 'num_filters' filters and 3x3 kernel size\n    conv = tf.keras.layers.Conv2D(num_filters, 3, padding=\"same\")(input)\n    # Batch normalization to normalize and stabilize the activations\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    # ReLU activation function to introduce non-linearity\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    # Second convolution layer with 'num_filters' filters and 3x3 kernel size\n    conv = tf.keras.layers.Conv2D(num_filters, 3, padding=\"same\")(conv)\n    # Batch normalization\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    # ReLU activation\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    return conv\n\n# Define an encoder block\ndef encoder_block(input, num_filters):\n    # Create convolutional block\n    skip = conv_block(input, num_filters)\n    # Max pooling layer to downsample the spatial dimensions\n    pool = tf.keras.layers.MaxPool2D((2,2))(skip)\n    return skip, pool\n\n# Define a decoder block\ndef decoder_block(input, skip, num_filters):\n    # Upsampling layer followed by a convolutional layer\n    up_conv = tf.keras.layers.Conv2DTranspose(num_filters, (2,2), strides=2, padding=\"same\")(input)\n    # Concatenate the upsampled feature map with the corresponding skip connection from the encoder\n    conv = tf.keras.layers.Concatenate()([up_conv, skip])\n    # Convolutional block to extract features\n    conv = conv_block(conv, num_filters)\n    return conv\n\n# Define the U-Net architecture\ndef Unet(input_shape):\n    # Input layer\n    inputs = tf.keras.layers.Input(input_shape)\n\n    # Encoding path\n    skip1, pool1 = encoder_block(inputs, 64)\n    skip2, pool2 = encoder_block(pool1, 128)\n    skip3, pool3 = encoder_block(pool2, 256)\n    skip4, pool4 = encoder_block(pool3, 512)\n\n    # Bridge convolutional block\n    bridge = conv_block(pool4, 1024)\n\n    # Decoding path\n    decode1 = decoder_block(bridge, skip4, 512)\n    decode2 = decoder_block(decode1, skip3, 256)\n    decode3 = decoder_block(decode2, skip2, 128)\n    decode4 = decoder_block(decode3, skip1, 64)\n\n    # Output layer\n    outputs = tf.keras.layers.Conv2D(1, 1, padding=\"same\", activation=\"sigmoid\")(decode4)\n    # Define the model with input and output layers\n    model = tf.keras.models.Model(inputs, outputs, name=\"U-Net\")\n    return model\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**UNET MODIFIED (01)**","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\ndef conv_block(input, num_filters):\n    \"\"\"\n    Simplified convolutional block with fewer operations\n    \"\"\"\n    conv = tf.keras.layers.Conv2D(num_filters, 3, padding=\"same\")(input)\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    return conv\n\ndef encoder_block(input, num_filters):\n    \"\"\"\n    Simplified encoder block with max pooling\n    \"\"\"\n    conv = conv_block(input, num_filters)\n    pool = tf.keras.layers.MaxPool2D((2,2))(conv)\n    return conv, pool\n\ndef decoder_block(input, skip, num_filters):\n    \"\"\"\n    Simplified decoder block with upsampling\n    \"\"\"\n    up_conv = tf.keras.layers.Conv2DTranspose(num_filters, (2,2), strides=2, padding=\"same\")(input)\n    conv = tf.keras.layers.Concatenate()([up_conv, skip])\n    conv = conv_block(conv, num_filters)\n    return conv\n\ndef Unet(input_shape):\n    \"\"\"\n    Simplified U-Net architecture with reduced layers\n    \"\"\"\n    inputs = tf.keras.layers.Input(input_shape)\n    \n    # Encoder path (reduced to 3 levels)\n    skip1, pool1 = encoder_block(inputs, 64)\n    skip2, pool2 = encoder_block(pool1, 128)\n    skip3, pool3 = encoder_block(pool2, 256)\n    \n    # Bridge \n    bridge = conv_block(pool3, 512)\n    \n    # Decoder path\n    decode1 = decoder_block(bridge, skip3, 256)\n    decode2 = decoder_block(decode1, skip2, 128)\n    decode3 = decoder_block(decode2, skip1, 64)\n    \n    # Output layer with sigmoid activation\n    outputs = tf.keras.layers.Conv2D(1, 1, padding=\"same\", activation=\"sigmoid\")(decode3)\n    \n    model = tf.keras.models.Model(inputs=inputs, outputs=outputs, name=\"Simplified-UNet\")\n    return model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:07:54.3124Z","iopub.execute_input":"2025-03-29T21:07:54.312647Z","iopub.status.idle":"2025-03-29T21:07:54.32012Z","shell.execute_reply.started":"2025-03-29T21:07:54.312626Z","shell.execute_reply":"2025-03-29T21:07:54.319461Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**REVISED UNET MODIFIED (01)**","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\ndef conv_block(input, num_filters, dropout_rate=0.3):\n    \"\"\"\n    Convolutional block with Batch Normalization, ReLU, and Dropout\n    \"\"\"\n    conv = tf.keras.layers.Conv2D(num_filters, 3, padding=\"same\")(input)\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    conv = tf.keras.layers.Dropout(dropout_rate)(conv)  # Added dropout\n    return conv\n\ndef encoder_block(input, num_filters, dropout_rate=0.1):\n    \"\"\"\n    Encoder block with convolution and max pooling\n    \"\"\"\n    conv = conv_block(input, num_filters, dropout_rate)\n    pool = tf.keras.layers.MaxPool2D((2,2))(conv)\n    return conv, pool\n\ndef decoder_block(input, skip, num_filters, dropout_rate=0.1):\n    \"\"\"\n    Decoder block with upsampling\n    \"\"\"\n    up_conv = tf.keras.layers.Conv2DTranspose(num_filters, (2,2), strides=2, padding=\"same\")(input)\n    conv = tf.keras.layers.Concatenate()([up_conv, skip])\n    conv = conv_block(conv, num_filters, dropout_rate)\n    return conv\n\ndef Unet(input_shape):\n    \"\"\"\n    Hybrid U-Net optimized for small datasets with future scalability\n    \"\"\"\n    inputs = tf.keras.layers.Input(input_shape)\n    \n    # Encoder path\n    skip1, pool1 = encoder_block(inputs, 32)  # Reduced initial filters\n    skip2, pool2 = encoder_block(pool1, 64)\n    skip3, pool3 = encoder_block(pool2, 128)\n    \n    # Bridge \n    bridge = conv_block(pool3, 256)\n    \n    # Decoder path\n    decode1 = decoder_block(bridge, skip3, 128)\n    decode2 = decoder_block(decode1, skip2, 64)\n    decode3 = decoder_block(decode2, skip1, 32)\n    \n    # Output layer with L2 regularization\n    outputs = tf.keras.layers.Conv2D(1, 1, padding=\"same\", activation=\"sigmoid\", \n                                     kernel_regularizer=tf.keras.regularizers.l2(0.01))(decode3)\n\n    model = tf.keras.models.Model(inputs=inputs, outputs=outputs, name=\"Hybrid-UNet\")\n    \n    return model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:18:35.695943Z","iopub.execute_input":"2025-03-29T21:18:35.696272Z","iopub.status.idle":"2025-03-29T21:18:35.704614Z","shell.execute_reply.started":"2025-03-29T21:18:35.696248Z","shell.execute_reply":"2025-03-29T21:18:35.703607Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**UNET Modified 02**","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\ndef conv_block(input, num_filters, dropout_rate=0.2):\n    \"\"\"\n    Convolutional block with L2 regularization and dropout\n    \"\"\"\n    conv = tf.keras.layers.Conv2D(\n        num_filters, \n        3, \n        padding=\"same\", \n        kernel_regularizer=tf.keras.regularizers.l2(0.01)\n    )(input)\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    conv = tf.keras.layers.Dropout(dropout_rate)(conv)\n    \n    conv = tf.keras.layers.Conv2D(\n        num_filters, \n        3, \n        padding=\"same\", \n        kernel_regularizer=tf.keras.regularizers.l2(0.01)\n    )(conv)\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    \n    return conv\n\ndef encoder_block(input, num_filters, dropout_rate=0.2):\n    \"\"\"\n    Encoder block with pooling\n    \"\"\"\n    conv = conv_block(input, num_filters, dropout_rate)\n    pool = tf.keras.layers.MaxPool2D((2,2))(conv)\n    return conv, pool\n\ndef decoder_block(input, skip, num_filters, dropout_rate=0.2):\n    \"\"\"\n    Decoder block with upsampling\n    \"\"\"\n    up_conv = tf.keras.layers.Conv2DTranspose(\n        num_filters, \n        (2,2), \n        strides=2, \n        padding=\"same\",\n        kernel_regularizer=tf.keras.regularizers.l2(0.01)\n    )(input)\n    conv = tf.keras.layers.Concatenate()([up_conv, skip])\n    conv = conv_block(conv, num_filters, dropout_rate)\n    return conv\n\ndef Unet(input_shape, num_classes=1, dropout_rate=0.2):\n    \"\"\"\n    U-Net architecture with sigmoid activation\n    \"\"\"\n    inputs = tf.keras.layers.Input(input_shape)\n    \n    # Encoder path\n    skip1, pool1 = encoder_block(inputs, 32, dropout_rate)\n    skip2, pool2 = encoder_block(pool1, 64, dropout_rate)\n    \n    # Bridge \n    bridge = conv_block(pool2, 128, dropout_rate)\n    \n    # Decoder path\n    decode1 = decoder_block(bridge, skip2, 64, dropout_rate)\n    decode2 = decoder_block(decode1, skip1, 32, dropout_rate)\n    \n    # Output layer with sigmoid activation\n    outputs = tf.keras.layers.Conv2D(\n        num_classes, \n        1, \n        padding=\"same\", \n        activation=\"sigmoid\",\n        kernel_regularizer=tf.keras.regularizers.l2(0.01)\n    )(decode2)\n    \n    # Create model\n    model = tf.keras.models.Model(inputs=inputs, outputs=outputs, name=\"Sigmoid-UNet\")\n    \n    # Compile model\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n        loss='binary_crossentropy',\n        metrics=['accuracy']\n    )\n    \n    return model\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:14:29.785206Z","iopub.execute_input":"2025-03-29T21:14:29.785519Z","iopub.status.idle":"2025-03-29T21:14:30.033119Z","shell.execute_reply.started":"2025-03-29T21:14:29.785494Z","shell.execute_reply":"2025-03-29T21:14:30.032295Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<img src=\"https://media.geeksforgeeks.org/wp-content/uploads/20220614121231/Group14.jpg\">","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/aptos2019-blindness-detection/train.csv').head(20)\n\nx_train = []\ny_train = []\n\nimage_size = (512,512)\n\nfor index, row in train_df.iterrows():\n    image_path = f\"/kaggle/input/aptos2019-blindness-detection/train_images/{row['id_code']}.png\"\n    image = cv2.imread(image_path,cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = cv2.resize(image, image_size)\n    x_train.append(image)\n    y_train.append(row['diagnosis'])\n    \nx_train = np.array(x_train)\ny_train = np.array(y_train,dtype=np.int32)","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **---------------------------START-----------------------------------**","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"**PREPROCESSING GRAYSCALE**","metadata":{}},{"cell_type":"markdown","source":"**Image paths**","metadata":{}},{"cell_type":"code","source":"#Training data dir\nimages_train_dir ='/kaggle/input/idrid-2018/IDRiD/Segmentation/Images/a. Training Set'\nmasks_train_dir = '/kaggle/input/idrid-2018/IDRiD/Segmentation/Mask/a. Training Set/1. Microaneurysms'\n\n#Testing data dir\n\nimages_test_dir ='/kaggle/input/idrid-2018/IDRiD/Segmentation/Images/b. Testing Set'\nmasks_test_dir = '/kaggle/input/idrid-2018/IDRiD/Segmentation/Mask/b. Testing Set/1. Microaneurysms'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:14:32.289598Z","iopub.execute_input":"2025-03-29T21:14:32.289921Z","iopub.status.idle":"2025-03-29T21:14:32.293557Z","shell.execute_reply.started":"2025-03-29T21:14:32.289894Z","shell.execute_reply":"2025-03-29T21:14:32.292722Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Reading image paths**","metadata":{}},{"cell_type":"code","source":"images_train_listdir = sorted(os.listdir(images_train_dir))\nmasks_train_listdir = sorted(os.listdir(masks_train_dir))\n\nprint(images_train_listdir)\nprint(masks_train_listdir)\n\nimages_test_listdir = sorted(os.listdir(images_test_dir))\nmasks_test_listdir = sorted(os.listdir(masks_test_dir))\nprint(images_test_listdir)\nprint(masks_test_listdir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:14:35.870949Z","iopub.execute_input":"2025-03-29T21:14:35.871302Z","iopub.status.idle":"2025-03-29T21:14:35.878429Z","shell.execute_reply.started":"2025-03-29T21:14:35.871272Z","shell.execute_reply":"2025-03-29T21:14:35.877715Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Reading the images and masks for segmentation**","metadata":{}},{"cell_type":"code","source":"images_train,masks_train = read_segmentation_training_data(images_train_dir,masks_train_dir,images_train_listdir,masks_train_listdir)\nimages_test,masks_test = read_segmentation_training_data(images_test_dir,masks_test_dir,images_test_listdir,masks_test_listdir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:14:38.498481Z","iopub.execute_input":"2025-03-29T21:14:38.498784Z","iopub.status.idle":"2025-03-29T21:14:49.93888Z","shell.execute_reply.started":"2025-03-29T21:14:38.498761Z","shell.execute_reply":"2025-03-29T21:14:49.937894Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(images_train)\nprint(masks_train)\nprint(images_test)\nprint(masks_test)","metadata":{"trusted":true,"_kg_hide-input":false,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Preprocessing Images**","metadata":{}},{"cell_type":"code","source":"images_train_processed = preprocess_images(images_train)\nimages_test_processed = preprocess_images(images_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:14:49.940058Z","iopub.execute_input":"2025-03-29T21:14:49.940409Z","iopub.status.idle":"2025-03-29T21:14:50.055305Z","shell.execute_reply.started":"2025-03-29T21:14:49.940378Z","shell.execute_reply":"2025-03-29T21:14:50.054132Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Image Augmentation**","metadata":{}},{"cell_type":"code","source":"# Define augmentation pipeline with specific transformations\naugmentations = {\n    \"hflip\": A.HorizontalFlip(p=1),   # Horizontal Flip\n    \"vflip\": A.VerticalFlip(p=1),     # Vertical Flip\n    \"rotate90\": A.RandomRotate90(p=1),  # 90-degree Rotation\n    \"transpose\": A.Transpose(p=1),      # Transpose\n    \"shift_scale_rotate\": A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.05, rotate_limit=10, p=1)  # Shift, Scale, Rotate\n}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:17:24.565739Z","iopub.execute_input":"2025-03-29T21:17:24.566031Z","iopub.status.idle":"2025-03-29T21:17:24.571339Z","shell.execute_reply.started":"2025-03-29T21:17:24.56601Z","shell.execute_reply":"2025-03-29T21:17:24.570346Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\n\n\n# Function to apply augmentation and save images\ndef augment_and_save(images, masks, image_names, mask_names, output_folder, prefix=\"train\"):\n    \n    # Create output directories if they don't exist\n    output_image_folder = os.path.join(output_folder, \"images\")\n    output_mask_folder = os.path.join(output_folder, \"masks\")\n    os.makedirs(output_image_folder, exist_ok=True)\n    os.makedirs(output_mask_folder, exist_ok=True)\n\n    for idx, (img, mask, img_name, mask_name) in enumerate(zip(images, masks, image_names, mask_names)):\n        # Check if image and mask are valid\n        if img is None or mask is None:\n            print(f\"⚠ Image or mask at index {idx} is invalid.\")\n            continue\n\n        # Resize to maintain consistency\n        img = cv2.resize(img, (512, 512))\n        mask = cv2.resize(mask, (512, 512), interpolation=cv2.INTER_NEAREST)\n\n        # Extract filename without extension\n        img_base = os.path.splitext(img_name)[0]  # Remove file extension\n        mask_base = os.path.splitext(mask_name)[0]  # Remove file extension\n\n        # Apply augmentations\n        for aug_name, aug in augmentations.items():\n            augmented = aug(image=img, mask=mask)\n            aug_img = augmented['image']\n            aug_mask = augmented['mask']\n\n            # Define new filenames: Keep the original base name and add the augmentation type\n            aug_img_filename = f\"{img_base}_{aug_name}.jpg\"\n            aug_mask_filename = f\"{mask_base}_{aug_name}.tif\"\n\n            # Save augmented images and masks\n            cv2.imwrite(os.path.join(output_image_folder, aug_img_filename), aug_img)\n            cv2.imwrite(os.path.join(output_mask_folder, aug_mask_filename), aug_mask)\n        \n        print(f\"Augmented images saved for {img_base}\")\n        print(f\"Augmented images saved for {mask_base}\")\n\n    print(f\"✅ Augmented images and masks saved in {output_image_folder} and {output_mask_folder}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:17:25.831491Z","iopub.execute_input":"2025-03-29T21:17:25.831806Z","iopub.status.idle":"2025-03-29T21:17:25.83902Z","shell.execute_reply.started":"2025-03-29T21:17:25.831782Z","shell.execute_reply":"2025-03-29T21:17:25.838105Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"output_folder = \"/kaggle/working/microaneurysms-segmentation/\"  # Folder to store augmented images\n\n# Apply augmentation and save images/masks for training data\naugment_and_save(images_train_processed, masks_train, images_train_listdir, masks_train_listdir, output_folder, prefix=\"train\")\n\n# Apply augmentation and save images/masks for test data\naugment_and_save(images_test_processed, masks_test, images_test_dir, masks_test_dir, output_folder, prefix=\"test\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:17:29.269068Z","iopub.execute_input":"2025-03-29T21:17:29.269416Z","iopub.status.idle":"2025-03-29T21:17:30.689758Z","shell.execute_reply.started":"2025-03-29T21:17:29.269392Z","shell.execute_reply":"2025-03-29T21:17:30.689028Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Don't run this cell**","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\n\nfor i,image in enumerate(images_train_processed[:3]):\n    plt.subplot(1, 3, i+1)\n    plt.title(f\"{images_train_listdir[i]}\")\n    plt.imshow(image,cmap='gray')\n    #plt.imshow(image)\n    plt.axis('off')","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Select one image and its augmented versions\nimage_index = 2  # Change this to select a different image\noriginal_image = images_train_processed[image_index]\noriginal_mask = masks_train[image_index]\n\n# Define augmented images list\naugmented_images = []\naugmented_masks = []\n\n# Apply augmentations and store the results\nfor aug_name, aug in augmentations.items():\n    augmented = aug(image=original_image, mask=original_mask)\n    augmented_images.append(augmented['image'])\n    augmented_masks.append(augmented['mask'])\n\n# Plot the original image and its augmented versions\nplt.figure(figsize=(10, 5))\n\n# Plot original image\nplt.subplot(2, 3, 1)\nplt.title(\"Original Image\")\nplt.imshow(original_image, cmap='brg')\nplt.axis('off')\n\n# Plot augmented images\nfor i, (aug_img, aug_name) in enumerate(zip(augmented_images, augmentations.keys())):\n    plt.subplot(2, 3, i + 2)  # i + 2 because the first subplot is for the original image\n    plt.title(f\"Augmented: {aug_name}\")\n    plt.imshow(aug_img, cmap='brg')\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:17:35.222685Z","iopub.execute_input":"2025-03-29T21:17:35.22298Z","iopub.status.idle":"2025-03-29T21:17:35.841642Z","shell.execute_reply.started":"2025-03-29T21:17:35.222956Z","shell.execute_reply":"2025-03-29T21:17:35.840777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\n\ngc.collect()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:17:41.90454Z","iopub.execute_input":"2025-03-29T21:17:41.904841Z","iopub.status.idle":"2025-03-29T21:17:42.162536Z","shell.execute_reply.started":"2025-03-29T21:17:41.904816Z","shell.execute_reply":"2025-03-29T21:17:42.161751Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Defining UNET Model Parameters**","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 8\nEPOCHS = 20\nLEARNING_RATE = 0.001","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:17:44.107206Z","iopub.execute_input":"2025-03-29T21:17:44.107532Z","iopub.status.idle":"2025-03-29T21:17:44.111447Z","shell.execute_reply.started":"2025-03-29T21:17:44.107505Z","shell.execute_reply":"2025-03-29T21:17:44.110392Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create an instance of the U-Net model with the specified input shape\nunet_model2 = Unet((512,512,1))\n# Compile the model with Adam optimizer and binary crossentropy loss\noptimizer = Adam(LEARNING_RATE) \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:18:48.687136Z","iopub.execute_input":"2025-03-29T21:18:48.687553Z","iopub.status.idle":"2025-03-29T21:18:48.864355Z","shell.execute_reply.started":"2025-03-29T21:18:48.687523Z","shell.execute_reply":"2025-03-29T21:18:48.863484Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"unet_model2.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:18:50.708567Z","iopub.execute_input":"2025-03-29T21:18:50.708901Z","iopub.status.idle":"2025-03-29T21:18:50.756623Z","shell.execute_reply.started":"2025-03-29T21:18:50.708871Z","shell.execute_reply":"2025-03-29T21:18:50.755915Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\n\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:18:58.556259Z","iopub.execute_input":"2025-03-29T21:18:58.556582Z","iopub.status.idle":"2025-03-29T21:18:58.781Z","shell.execute_reply.started":"2025-03-29T21:18:58.556558Z","shell.execute_reply":"2025-03-29T21:18:58.780319Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Assuming balanced classes\n\nunet_model2.compile(optimizer=optimizer, \n                   loss=losses.BinaryCrossentropy(from_logits=False), \n                   metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:19:01.040611Z","iopub.execute_input":"2025-03-29T21:19:01.040958Z","iopub.status.idle":"2025-03-29T21:19:01.049478Z","shell.execute_reply.started":"2025-03-29T21:19:01.04093Z","shell.execute_reply":"2025-03-29T21:19:01.048655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:19:01.922025Z","iopub.execute_input":"2025-03-29T21:19:01.922481Z","iopub.status.idle":"2025-03-29T21:19:02.167352Z","shell.execute_reply.started":"2025-03-29T21:19:01.922437Z","shell.execute_reply":"2025-03-29T21:19:02.166456Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import warnings\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau, TensorBoard, CSVLogger, LearningRateScheduler\nimport datetime\n\nwarnings.filterwarnings('ignore')\n\n# Checkpoint to save the best model\ncheckpoint = ModelCheckpoint('MA_best_model_{epoch:02d}-{val_loss:.4f}.keras', monitor='val_loss',  mode='min', save_best_only=True, verbose=1)\n\n# Reduce learning rate if validation loss doesn't improve\nreduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience= 3, min_lr=1e-6, mode='min', verbose=1)\n\n# Early stopping to prevent overfitting\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5 ,mode='min',  restore_best_weights=True, verbose=1)\n\n# TensorBoard logging\nlog_dir = 'logs/fit/' + datetime.datetime.now().strftime('%Y%m%d-%H%M%S')\ntensorboard = TensorBoard(log_dir=log_dir, histogram_freq=1, write_graph=True, write_images=True)\n\n\n# CSV Logger to log training history\ncsv_logger = CSVLogger('MA_training_log.csv', append= True)\n\n# Learning rate schedule function\ndef lr_schedule(epoch):\n    initial_lr = 0.01\n    drop_factor = 0.5\n    drop_epochs = 10\n    min_lr = 1e-6\n\n    new_lr = initial_lr * (drop_factor ** (epoch / drop_epochs))\n    return max(new_lr, min_lr)\n\n# Learning rate scheduler callback\nlr_scheduler = LearningRateScheduler(lr_schedule)\n\n# List of callbacks\ncallbacks = [checkpoint, reduce_lr, early_stopping, tensorboard, csv_logger, lr_scheduler]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:19:02.464296Z","iopub.execute_input":"2025-03-29T21:19:02.464624Z","iopub.status.idle":"2025-03-29T21:19:02.471193Z","shell.execute_reply.started":"2025-03-29T21:19:02.464598Z","shell.execute_reply":"2025-03-29T21:19:02.470265Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tensorboard --logdir=logs/fit","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T20:48:20.232415Z","iopub.execute_input":"2025-03-29T20:48:20.232731Z","iopub.status.idle":"2025-03-29T20:48:20.455644Z","shell.execute_reply.started":"2025-03-29T20:48:20.232704Z","shell.execute_reply":"2025-03-29T20:48:20.454738Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nvidia-smi","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Training the Model**","metadata":{}},{"cell_type":"code","source":"unet_history = unet_model2.fit(\n    images_train_processed, masks_train, \n    validation_split=0.3, \n    batch_size=BATCH_SIZE, \n    epochs=EPOCHS,\n    callbacks=[checkpoint, early_stopping, reduce_lr, tensorboard, csv_logger, lr_scheduler])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:19:07.830172Z","iopub.execute_input":"2025-03-29T21:19:07.830543Z","iopub.status.idle":"2025-03-29T21:20:18.21844Z","shell.execute_reply.started":"2025-03-29T21:19:07.830517Z","shell.execute_reply":"2025-03-29T21:20:18.21749Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:20:36.947945Z","iopub.execute_input":"2025-03-29T21:20:36.948289Z","iopub.status.idle":"2025-03-29T21:20:37.2229Z","shell.execute_reply.started":"2025-03-29T21:20:36.948264Z","shell.execute_reply":"2025-03-29T21:20:37.222014Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Plotting Losses**","metadata":{}},{"cell_type":"code","source":"def plot_training_history(history):\n    plt.figure(figsize=(12, 4))\n\n    # Plot training and validation loss\n    plt.subplot(1, 2, 1)\n    plt.plot(history.history['loss'], label='Training Loss')\n    plt.plot(history.history['val_loss'], label='Validation Loss')\n    plt.title(\"Training & Validation Loss\")\n    plt.xlabel(\"Epoch\")\n    plt.ylabel(\"Loss\")\n    plt.legend()\n    \n\n    # Plot training and validation accuracy\n    plt.subplot(1, 2, 2)\n    plt.plot(history.history['accuracy'], label='Training Accuracy')\n    plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n    plt.title(\"Training & Validation Accuracy\")\n    plt.xlabel(\"Epoch\")\n    plt.ylabel(\"Accuracy\")\n    plt.legend()\n\n    plt.tight_layout()\n    plt.show()\n\n# Plot training history\nplot_training_history(unet_history)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:20:38.950573Z","iopub.execute_input":"2025-03-29T21:20:38.9509Z","iopub.status.idle":"2025-03-29T21:20:39.372269Z","shell.execute_reply.started":"2025-03-29T21:20:38.950871Z","shell.execute_reply":"2025-03-29T21:20:39.371424Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_result(idx, og, unet, target, p):\n    \n    fig, axs = plt.subplots(1, 3, figsize=(12,12))\n    axs[0].set_title(\"Original \"+str(idx) )\n    axs[0].imshow(og,cmap='brg')\n    axs[0].axis('off')\n    \n    axs[1].set_title(\"U-Net: p>\"+str(p))\n    axs[1].imshow(unet,cmap='gray')\n    axs[1].axis('off')\n    \n    axs[2].set_title(\"Ground Truth\")\n    axs[2].imshow(target,cmap='gray')\n    axs[2].axis('off')\n\n    plt.show()\n    \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:20:44.716939Z","iopub.execute_input":"2025-03-29T21:20:44.717478Z","iopub.status.idle":"2025-03-29T21:20:44.724304Z","shell.execute_reply.started":"2025-03-29T21:20:44.717425Z","shell.execute_reply":"2025-03-29T21:20:44.723182Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Testing on known data**","metadata":{}},{"cell_type":"code","source":"unet_predict = unet_model2.predict(images_test_processed[:-1])\nprint(len(images_test_processed))\n\nr1 = 0.5\n\n\n\n\n\nunet_predict1 = (unet_predict > r1).astype(np.uint8)\n\n\n\nshow_test_idx = random.sample(range(len(unet_predict)), 3)\nfor idx in show_test_idx:\n    show_result(idx, images_test_processed[idx], unet_predict1[idx], masks_test[idx], r1)\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-29T21:21:21.526435Z","iopub.execute_input":"2025-03-29T21:21:21.526798Z","iopub.status.idle":"2025-03-29T21:21:22.58217Z","shell.execute_reply.started":"2025-03-29T21:21:21.526768Z","shell.execute_reply":"2025-03-29T21:21:22.581295Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"output_dir = \"/kaggle/working/predicted_masks/\"\n\nos.makedirs(output_dir, exist_ok=True)  # Create the directory if it doesn't exist\n","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for idx, pred_mask in enumerate(unet_predict1):\n    # Convert the predicted mask to an image (0s and 255s)\n    pred_mask_image = pred_mask * 255  # Scale to 0-255 for saving as an image\n\n    # Save the predicted mask as a PNG file\n    output_path = os.path.join(output_dir, f\"pred_mask_{idx}.png\")\n    cv2.imwrite(output_path, pred_mask_image)\n\n    print(f\"Saved predicted mask for image {idx} at {output_path}\")\n\nprint(f\"✅ All predicted masks saved in {output_dir}\")","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Testing Accuracy & Loss on known data**","metadata":{}},{"cell_type":"code","source":"loss,accuracy = unet_model2.evaluate(images_test_processed[:-1],masks_test[:-1])\n\nprint(\"Test Loss:\", loss)\nprint(\"Test Accuracy:\", accuracy)","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Saving the Predicted Test Images in output directory**","metadata":{}},{"cell_type":"code","source":"def show_result(idx, og, unet, p):\n    \n    fig, axs = plt.subplots(1, 2, figsize=(12,12))\n    axs[0].set_title(\"Original \"+str(idx) )\n    axs[0].imshow(og,cmap='gray')\n    axs[0].axis('off')\n    \n    axs[1].set_title(\"U-Net: Class \"+str(p))\n    axs[1].imshow(unet,cmap='gray')\n    axs[1].axis('off')\n\n    plt.show()\n    \nunet_predict = unet_model2.predict(preprocess_images(images_train_processed))\n\nr1 = 0.9\n\nunet_predict1 = (unet_predict > r1).astype(np.uint8)\n\nshow_test_idx = random.sample(range(len(unet_predict)), 3)\nfor idx in show_test_idx:\n    show_result(idx, preprocess_images(images_train_processed)[idx], unet_predict1[idx], masks_train[idx])\n    ","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Testing on unknown data**","metadata":{}},{"cell_type":"markdown","source":"**Model Evaluation**","metadata":{}},{"cell_type":"markdown","source":"**Hyperparameter Tuning**","metadata":{}},{"cell_type":"markdown","source":"**Testing**","metadata":{}},{"cell_type":"markdown","source":"**Model Re-evaluation**","metadata":{}},{"cell_type":"markdown","source":"**Saving the Model**","metadata":{}},{"cell_type":"code","source":"# Save the entire model (architecture + weights + optimizer state)\nunet_model2.save(\"MA_trained_model.h5\")","metadata":{"trusted":true,"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **--------------------------------------------END-------------------------------------------------**","metadata":{}}]}