# Install necessary libraries (if not already)
!pip install opencv-python-headless
!pip install tensorflow
!pip install kaggle

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, concatenate, BatchNormalization
from tensorflow.keras.models import Model
from sklearn.model_selection import train_test_split
from google.colab import files

# Set up Kaggle API credentials
os.environ['KAGGLE_USERNAME'] = 'saisai6567'
os.environ['KAGGLE_KEY'] = 'a26b5bb35240ac0aa00506ef1db25bb9'

# Download the dataset from Kaggle
!kaggle datasets download -d kpgeek/kitti-roadlane-detection-dataset-224-x-224
!unzip -oq kitti-roadlane-detection-dataset-224-x-224.zip -d kitti_road


### Step 2: Define U-Net Model


def unet_model(input_size=(224, 224, 3)):
    def conv_block(X, num_filters):
        out = Conv2D(num_filters, kernel_size=(3, 3), padding='same', activation='relu')(X)
        out = BatchNormalization()(out)
        out = Conv2D(num_filters, kernel_size=(3, 3), padding='same', activation='relu')(out)
        out = BatchNormalization()(out)
        return out

    def deconv_block(X, conc_skip, num_filters):
        out = UpSampling2D((2, 2))(X)
        out = concatenate([out, conc_skip], axis=-1)
        out = Conv2D(num_filters, kernel_size=(3, 3), padding='same', activation='relu')(out)
        out = BatchNormalization()(out)
        out = Conv2D(num_filters, kernel_size=(3, 3), padding='same', activation='relu')(out)
        out = BatchNormalization()(out)
        return out

    inputs = Input(input_size)
    c1 = conv_block(inputs, 64)
    p1 = MaxPooling2D((2, 2))(c1)
    c2 = conv_block(p1, 128)
    p2 = MaxPooling2D((2, 2))(c2)
    c3 = conv_block(p2, 256)
    p3 = MaxPooling2D((2, 2))(c3)
    c4 = conv_block(p3, 512)
    p4 = MaxPooling2D((2, 2))(c4)
    c5 = conv_block(p4, 1024)

    u6 = deconv_block(c5, c4, 512)
    u7 = deconv_block(u6, c3, 256)
    u8 = deconv_block(u7, c2, 128)
    u9 = deconv_block(u8, c1, 64)
    outputs = Conv2D(1, (1, 1), activation='sigmoid')(u9)

    model = Model(inputs=[inputs], outputs=[outputs])
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    return model

# Load the U-Net model
unet = unet_model()


### Step 3: Load Dataset


def load_data(image_dir, mask_dir, img_size=(224, 224)):
    images = []
    masks = []

    image_files = sorted(os.listdir(image_dir)) # Ensure consistent order
    mask_files = {os.path.splitext(os.path.basename(f))[0].replace('gt_', ''): f for f in os.listdir(mask_dir)}

    print(f"Total image files: {len(image_files)}, Total mask files: {len(mask_files)}")

    for img_file in image_files:
        img_path = os.path.join(image_dir, img_file)
        img_name, _ = os.path.splitext(img_file)
        if img_name in mask_files:
            mask_path = os.path.join(mask_dir, mask_files[img_name])
            img = cv2.imread(img_path)
            if img is not None:
                img = cv2.resize(img, img_size)
                images.append(img)
            mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
            if mask is not None:
                mask = cv2.resize(mask, img_size)
                masks.append(mask)
        else:
            print(f"Missing mask for image: {img_path}")

    if not images or not masks:
        print("No images or masks loaded. Check your dataset.")
        return None, None

    images = np.array(images)
    masks = np.array(masks)
    images = images.astype('float32') / 255.0
    masks = masks.astype('float32') / 255.0
    masks = np.expand_dims(masks, axis=-1)
    return images, masks

# Paths updated as per directory structure provided
train_image_dir = '/content/kitti_road/data_road_224/training/image_2'
train_mask_dir = '/content/kitti_road/data_road_224/training/gt_image_2'

# Load training data
train_images, train_masks = load_data(train_image_dir, train_mask_dir)

# Check dataset size after loading
if train_images is not None and train_masks is not None:
    print(f"Loaded {len(train_images)} images and {len(train_masks)} masks")
else:
    print("Failed to load images or masks.")

# Split the dataset into training and validation sets
if train_images is not None and train_masks is not None:
    train_images, val_images, train_masks, val_masks = train_test_split(train_images, train_masks, test_size=0.2, random_state=42)
    print(f"Training images: {train_images.shape}, Validation images: {val_images.shape}")
    print(f"Training masks: {train_masks.shape}, Validation masks: {val_masks.shape}")

# Train the U-Net model
unet.fit(train_images, train_masks, validation_data=(val_images, val_masks), epochs=10, batch_size=16)


### Step 4: Define Functions for Image Processing


# Function to dehaze the image using the method described in the paper
def dehaze_image(image):
    def retinex_ssr(img, sigma):
        img = img.astype(np.float32) + 1.0
        retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma))
        return retinex

    def retinex_msr(img, sigma_list):
        msr = np.zeros_like(img, dtype=np.float32)
        for sigma in sigma_list:
            msr += retinex_ssr(img, sigma)
        msr = msr / len(sigma_list)
        return msr

    sigma_list = [15, 80, 250]
    img_msr = retinex_msr(image, sigma_list)
    img_msr = np.uint8(cv2.normalize(img_msr, None, 0, 255, cv2.NORM_MINMAX))

    gray = cv2.cvtColor(img_msr, cv2.COLOR_BGR2GRAY)
    hessian = cv2.cornerHarris(gray, 2, 3, 0.04)
    hessian = cv2.dilate(hessian, None)
    img_msr[hessian > 0.01 * hessian.max()] = [0, 0, 255]

    return img_msr

# Preprocess the image for segmentation
def preprocess_image_segmentation(image):
    image = cv2.resize(image, (224, 224))
    image = image.astype('float32') / 255.0
    image = np.expand_dims(image, axis=0)
    return image

# Perform road segmentation using U-Net
def segment_road(image, model):
    image = preprocess_image_segmentation(image)
    mask = model.predict(image)
    mask = (mask[0] > 0.5).astype('uint8') * 255
    return mask

# Combine the original image with the segmentation mask
def highlight_road(image, mask):
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    highlighted_image = cv2.drawContours(image.copy(), contours, -1, (0, 255, 0), 3)
    return highlighted_image


### Step 5: Upload and Process the Image


uploaded = files.upload()
image_path = list(uploaded.keys())[0]
image = cv2.imread(image_path)
original_height, original_width = image.shape[:2]
dehazed_image = dehaze_image(image)
road_mask = segment_road(dehazed_image, unet)
highlighted_image = highlight_road(dehazed_image, road_mask)

# Display the result
plt.figure(figsize=(15, 15))
plt.subplot(1, 3, 1)
plt.title("Original Image")
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.axis('off')

plt.subplot(1, 3, 2)
plt.title("Dehazed Image")
plt.imshow(cv2.cvtColor(dehazed_image, cv2.COLOR_BGR2RGB))
plt.axis('off')

plt.subplot(1, 3, 3)
plt.title("Road Highlighted")
plt.imshow(cv2.cvtColor(highlighted_image, cv2.COLOR_BGR2RGB))
plt.axis('off')

plt.show()


use this code upload predict plot structure but on this dataset
https://www.kaggle.com/datasets/rangalamahesh/preprocessed-1/data
and thislogic
"Road Lane Detection Using UNET
# import required libraries/dependencies
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import cv2
import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import models, layers, Sequential
/opt/conda/lib/python3.10/site-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.24.3
  warnings.warn(f"A NumPy version >={np_minversion} and <{np_maxversion}"
# train path
train_path = '/kaggle/input/tusimple-preprocessed-data/tusimple_preprocessed/training'
# create a generator and get the images from the directory
img_generator = keras.preprocessing.image.ImageDataGenerator()
seed = 10
images_set = img_generator.flow_from_directory(
    train_path,
    shuffle=False,
    batch_size=64,
    class_mode='binary',
    target_size=(256, 320)
)
Found 7252 images belonging to 2 classes.
'''
Assign the images in 'images_set' to two seperate arrays:
assign the road images to 'X' and the ground truth masks to 'Y'
'''
num_images = 7252 # gotten from the output of the cell above
num_batches = num_images // 64 + 1

# initialize an empty list to store the images
X = []
Y = []
# loop over the batches and extract the images
for i in range(num_batches):
    batch = next(images_set)
    batch_images = batch[0] # this contains the images
    batch_labels = batch[1] # this contains 0s and 1s
    for ind, lb in enumerate(batch_labels):
        '''
        a label of 0 means the image belongs to ground truth image,
        and a label of 1 means that the image belongs to the ground truth mask
        '''
        if lb == 0: 
            X.append(batch_images[ind])
        else:
            Y.append(np.mean(batch_images[ind], axis=2)) # Y shape is (m, 256, 320)
    if i % 10 == 0:
        print(f'Batch {i}')

# convert the lists to numpy arrays
X = np.array(X)
Y = np.array(Y)
Batch 0
Batch 10
Batch 20
Batch 30
Batch 40
Batch 50
Batch 60
Batch 70
Batch 80
Batch 90
Batch 100
Batch 110
# shuffle the dataset
from sklearn.utils import shuffle

X, Y = shuffle(X, Y, random_state=100)
# Normalize and reshape the mask set (Y)
Y = (Y >= 100).astype('int').reshape(-1, 256, 320, 1)
Y.min(), Y.max()
(0, 1)
# we get 2000 images for training and evaluation
X = np.array(X[:2000])
Y = np.array(Y[:2000])
# Split the datset into train and val sets
from sklearn.model_selection import train_test_split

X_train, X_val, Y_train, Y_val = train_test_split(X, Y, test_size=.1, random_state=100)
print("Shape of X_train:", X_train.shape)
print("Shape of X_val:", X_val.shape)
print("Shape of Y_train:", Y_train.shape)
print("Shape of Y_val:", Y_val.shape)
Shape of X_train: (1800, 256, 320, 3)
Shape of X_val: (200, 256, 320, 3)
Shape of Y_train: (1800, 256, 320, 1)
Shape of Y_val: (200, 256, 320, 1)
# free the RAM from undesired clutters
import gc
del X, Y, images_set
gc.collect()
53
# define the model's architecture

from keras.layers import Input, Conv2D, MaxPooling2D, Dropout, UpSampling2D, Concatenate
from keras.models import Model

def unet(input_size=(256,320,3)):
    inputs = Input(input_size)
    rescale = keras.layers.Rescaling(1./255)(inputs)
    # Encoder
    conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(rescale)
    conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)
    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
    
    conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)
    conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
    
    conv3 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool2)
    conv3 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)
    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)
    
    conv4 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool3)
    conv4 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)
    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)
    
    # Decoder
    conv5 = Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool4)
    conv5 = Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)
    drop5 = Dropout(0.5)(conv5)
    
    up6 = Conv2D(512, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2,2))(drop5))
    merge6 = Concatenate(axis=3)([conv4, up6])
    conv6 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge6)
    conv6 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)
    
    up7 = Conv2D(256, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2,2))(conv6))
    merge7 = Concatenate(axis=3)([conv3, up7])
    conv7 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge7)
    conv7 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv7)
    
    up8 = Conv2D(128, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2,2))(conv7))
    merge8 = Concatenate(axis=3)([conv2, up8])
    conv8 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge8)
    conv8 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv8)
    
    up9 = Conv2D(64, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2,2))(conv8))
    merge9 = Concatenate(axis=3)([conv1, up9])
    conv9 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge9)
    conv9 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv9)
    
    outputs = Conv2D(1, 1, activation='sigmoid')(conv9)
    
    model = Model(inputs=inputs, outputs=outputs)
    
    return model

model = unet()
# Compile the model
model.compile(optimizer='adam', loss=keras.losses.BinaryFocalCrossentropy(), metrics=['accuracy'])
model.summary()
Model: "model"
__________________________________________________________________________________________________
 Layer (type)                Output Shape                 Param #   Connected to                  
==================================================================================================
 input_1 (InputLayer)        [(None, 256, 320, 3)]        0         []                            
                                                                                                  
 rescaling (Rescaling)       (None, 256, 320, 3)          0         ['input_1[0][0]']             
                                                                                                  
 conv2d (Conv2D)             (None, 256, 320, 64)         1792      ['rescaling[0][0]']           
                                                                                                  
 conv2d_1 (Conv2D)           (None, 256, 320, 64)         36928     ['conv2d[0][0]']              
                                                                                                  
 max_pooling2d (MaxPooling2  (None, 128, 160, 64)         0         ['conv2d_1[0][0]']            
 D)                                                                                               
                                                                                                  
 conv2d_2 (Conv2D)           (None, 128, 160, 128)        73856     ['max_pooling2d[0][0]']       
                                                                                                  
 conv2d_3 (Conv2D)           (None, 128, 160, 128)        147584    ['conv2d_2[0][0]']            
                                                                                                  
 max_pooling2d_1 (MaxPoolin  (None, 64, 80, 128)          0         ['conv2d_3[0][0]']            
 g2D)                                                                                             
                                                                                                  
 conv2d_4 (Conv2D)           (None, 64, 80, 256)          295168    ['max_pooling2d_1[0][0]']     
                                                                                                  
 conv2d_5 (Conv2D)           (None, 64, 80, 256)          590080    ['conv2d_4[0][0]']            
                                                                                                  
 max_pooling2d_2 (MaxPoolin  (None, 32, 40, 256)          0         ['conv2d_5[0][0]']            
 g2D)                                                                                             
                                                                                                  
 conv2d_6 (Conv2D)           (None, 32, 40, 512)          1180160   ['max_pooling2d_2[0][0]']     
                                                                                                  
 conv2d_7 (Conv2D)           (None, 32, 40, 512)          2359808   ['conv2d_6[0][0]']            
                                                                                                  
 max_pooling2d_3 (MaxPoolin  (None, 16, 20, 512)          0         ['conv2d_7[0][0]']            
 g2D)                                                                                             
                                                                                                  
 conv2d_8 (Conv2D)           (None, 16, 20, 1024)         4719616   ['max_pooling2d_3[0][0]']     
                                                                                                  
 conv2d_9 (Conv2D)           (None, 16, 20, 1024)         9438208   ['conv2d_8[0][0]']            
                                                                                                  
 dropout (Dropout)           (None, 16, 20, 1024)         0         ['conv2d_9[0][0]']            
                                                                                                  
 up_sampling2d (UpSampling2  (None, 32, 40, 1024)         0         ['dropout[0][0]']             
 D)                                                                                               
                                                                                                  
 conv2d_10 (Conv2D)          (None, 32, 40, 512)          2097664   ['up_sampling2d[0][0]']       
                                                                                                  
 concatenate (Concatenate)   (None, 32, 40, 1024)         0         ['conv2d_7[0][0]',            
                                                                     'conv2d_10[0][0]']           
                                                                                                  
 conv2d_11 (Conv2D)          (None, 32, 40, 512)          4719104   ['concatenate[0][0]']         
                                                                                                  
 conv2d_12 (Conv2D)          (None, 32, 40, 512)          2359808   ['conv2d_11[0][0]']           
                                                                                                  
 up_sampling2d_1 (UpSamplin  (None, 64, 80, 512)          0         ['conv2d_12[0][0]']           
 g2D)                                                                                             
                                                                                                  
 conv2d_13 (Conv2D)          (None, 64, 80, 256)          524544    ['up_sampling2d_1[0][0]']     
                                                                                                  
 concatenate_1 (Concatenate  (None, 64, 80, 512)          0         ['conv2d_5[0][0]',            
 )                                                                   'conv2d_13[0][0]']           
                                                                                                  
 conv2d_14 (Conv2D)          (None, 64, 80, 256)          1179904   ['concatenate_1[0][0]']       
                                                                                                  
 conv2d_15 (Conv2D)          (None, 64, 80, 256)          590080    ['conv2d_14[0][0]']           
                                                                                                  
 up_sampling2d_2 (UpSamplin  (None, 128, 160, 256)        0         ['conv2d_15[0][0]']           
 g2D)                                                                                             
                                                                                                  
 conv2d_16 (Conv2D)          (None, 128, 160, 128)        131200    ['up_sampling2d_2[0][0]']     
                                                                                                  
 concatenate_2 (Concatenate  (None, 128, 160, 256)        0         ['conv2d_3[0][0]',            
 )                                                                   'conv2d_16[0][0]']           
                                                                                                  
 conv2d_17 (Conv2D)          (None, 128, 160, 128)        295040    ['concatenate_2[0][0]']       
                                                                                                  
 conv2d_18 (Conv2D)          (None, 128, 160, 128)        147584    ['conv2d_17[0][0]']           
                                                                                                  
 up_sampling2d_3 (UpSamplin  (None, 256, 320, 128)        0         ['conv2d_18[0][0]']           
 g2D)                                                                                             
                                                                                                  
 conv2d_19 (Conv2D)          (None, 256, 320, 64)         32832     ['up_sampling2d_3[0][0]']     
                                                                                                  
 concatenate_3 (Concatenate  (None, 256, 320, 128)        0         ['conv2d_1[0][0]',            
 )                                                                   'conv2d_19[0][0]']           
                                                                                                  
 conv2d_20 (Conv2D)          (None, 256, 320, 64)         73792     ['concatenate_3[0][0]']       
                                                                                                  
 conv2d_21 (Conv2D)          (None, 256, 320, 64)         36928     ['conv2d_20[0][0]']           
                                                                                                  
 conv2d_22 (Conv2D)          (None, 256, 320, 1)          65        ['conv2d_21[0][0]']           
                                                                                                  
==================================================================================================
Total params: 31031745 (118.38 MB)
Trainable params: 31031745 (118.38 MB)
Non-trainable params: 0 (0.00 Byte)
__________________________________________________________________________________________________
MODEL TRAINING
from tensorflow.keras.callbacks import ModelCheckpoint, TensorBoard

# Define the path to the folder where you want to save TensorBoard logs
tensorboard_log_dir = '/kaggle/working/logs'

# Create a TensorBoard callback
tensorboard_callback = TensorBoard(log_dir=tensorboard_log_dir, histogram_freq=1)

# train the model
epochs = 32
batch_size = 8

# Add TensorBoard callback to the list of callbacks
callbacks = [
    ModelCheckpoint("save_at_{epoch}.h5"),
    tensorboard_callback,
]


# Train the model
history = model.fit(
    X_train,
    Y_train,
    epochs=epochs,
    callbacks=callbacks,
    validation_data=(X_val, Y_val),
    batch_size=batch_size
)
Epoch 1/32
2023-12-15 04:02:15.519051: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:954] layout failed: INVALID_ARGUMENT: Size of values 0 does not match size of permutation 4 @ fanin shape inmodel/dropout/dropout/SelectV2-2-TransposeNHWCToNCHW-LayoutOptimizer
225/225 [==============================] - ETA: 0s - loss: 0.2839 - accuracy: 0.9542
/opt/conda/lib/python3.10/site-packages/keras/src/engine/training.py:3000: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.
  saving_api.save_model(
225/225 [==============================] - 213s 787ms/step - loss: 0.2839 - accuracy: 0.9542 - val_loss: 0.0409 - val_accuracy: 0.9565
Epoch 2/32
225/225 [==============================] - 177s 786ms/step - loss: 0.0268 - accuracy: 0.9649 - val_loss: 0.0205 - val_accuracy: 0.9693
Epoch 3/32
225/225 [==============================] - 178s 789ms/step - loss: 0.0170 - accuracy: 0.9740 - val_loss: 0.0163 - val_accuracy: 0.9751
Epoch 4/32
225/225 [==============================] - 178s 789ms/step - loss: 0.0149 - accuracy: 0.9766 - val_loss: 0.0159 - val_accuracy: 0.9765
Epoch 5/32
225/225 [==============================] - 178s 789ms/step - loss: 0.0139 - accuracy: 0.9780 - val_loss: 0.0138 - val_accuracy: 0.9782
Epoch 6/32
225/225 [==============================] - 177s 789ms/step - loss: 0.0130 - accuracy: 0.9791 - val_loss: 0.0140 - val_accuracy: 0.9782
Epoch 7/32
225/225 [==============================] - 177s 788ms/step - loss: 0.0125 - accuracy: 0.9797 - val_loss: 0.0134 - val_accuracy: 0.9791
Epoch 8/32
225/225 [==============================] - 177s 789ms/step - loss: 0.0123 - accuracy: 0.9800 - val_loss: 0.0134 - val_accuracy: 0.9792
Epoch 9/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0118 - accuracy: 0.9806 - val_loss: 0.0136 - val_accuracy: 0.9791
Epoch 10/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0115 - accuracy: 0.9812 - val_loss: 0.0132 - val_accuracy: 0.9789
Epoch 11/32
225/225 [==============================] - 178s 790ms/step - loss: 0.0113 - accuracy: 0.9814 - val_loss: 0.0131 - val_accuracy: 0.9789
Epoch 12/32
225/225 [==============================] - 177s 788ms/step - loss: 0.0110 - accuracy: 0.9818 - val_loss: 0.0135 - val_accuracy: 0.9786
Epoch 13/32
225/225 [==============================] - 177s 788ms/step - loss: 0.0108 - accuracy: 0.9821 - val_loss: 0.0126 - val_accuracy: 0.9800
Epoch 14/32
225/225 [==============================] - 178s 790ms/step - loss: 0.0105 - accuracy: 0.9826 - val_loss: 0.0142 - val_accuracy: 0.9792
Epoch 15/32
225/225 [==============================] - 178s 789ms/step - loss: 0.0102 - accuracy: 0.9830 - val_loss: 0.0146 - val_accuracy: 0.9773
Epoch 16/32
225/225 [==============================] - 177s 788ms/step - loss: 0.0101 - accuracy: 0.9833 - val_loss: 0.0131 - val_accuracy: 0.9794
Epoch 17/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0098 - accuracy: 0.9836 - val_loss: 0.0140 - val_accuracy: 0.9796
Epoch 18/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0095 - accuracy: 0.9843 - val_loss: 0.0147 - val_accuracy: 0.9791
Epoch 19/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0091 - accuracy: 0.9849 - val_loss: 0.0153 - val_accuracy: 0.9792
Epoch 20/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0088 - accuracy: 0.9853 - val_loss: 0.0146 - val_accuracy: 0.9797
Epoch 21/32
225/225 [==============================] - 177s 786ms/step - loss: 0.0088 - accuracy: 0.9854 - val_loss: 0.0153 - val_accuracy: 0.9790
Epoch 22/32
225/225 [==============================] - 177s 785ms/step - loss: 0.0087 - accuracy: 0.9856 - val_loss: 0.0154 - val_accuracy: 0.9796
Epoch 23/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0082 - accuracy: 0.9865 - val_loss: 0.0156 - val_accuracy: 0.9790
Epoch 24/32
225/225 [==============================] - 177s 785ms/step - loss: 0.0079 - accuracy: 0.9869 - val_loss: 0.0163 - val_accuracy: 0.9794
Epoch 25/32
225/225 [==============================] - 177s 785ms/step - loss: 0.0073 - accuracy: 0.9878 - val_loss: 0.0156 - val_accuracy: 0.9792
Epoch 26/32
225/225 [==============================] - 177s 787ms/step - loss: 0.0071 - accuracy: 0.9882 - val_loss: 0.0172 - val_accuracy: 0.9793
Epoch 27/32
225/225 [==============================] - 177s 785ms/step - loss: 0.0068 - accuracy: 0.9886 - val_loss: 0.0180 - val_accuracy: 0.9794
Epoch 28/32
225/225 [==============================] - 177s 786ms/step - loss: 0.0071 - accuracy: 0.9884 - val_loss: 0.0179 - val_accuracy: 0.9781
Epoch 29/32
225/225 [==============================] - 177s 786ms/step - loss: 0.0065 - accuracy: 0.9892 - val_loss: 0.0177 - val_accuracy: 0.9790
Epoch 30/32
225/225 [==============================] - 177s 785ms/step - loss: 0.0061 - accuracy: 0.9899 - val_loss: 0.0182 - val_accuracy: 0.9792
Epoch 31/32
225/225 [==============================] - 177s 786ms/step - loss: 0.0060 - accuracy: 0.9901 - val_loss: 0.0198 - val_accuracy: 0.9788
Epoch 32/32
225/225 [==============================] - 177s 785ms/step - loss: 0.0058 - accuracy: 0.9905 - val_loss: 0.0198 - val_accuracy: 0.9790
preds = model.predict(X_val)
preds.max(), preds.min()
7/7 [==============================] - 23s 545ms/step
(0.99993193, 0.0)
# visualize some results from the val set.
plt.figure(figsize=(10, 45))
s, e = 90, 98
index = 1

preds = (preds >= .5).astype('int')
for i, j, k in zip(X_val[s:e], preds[s:e], Y_val[s:e]):
    # write these images into file as well
    cv2.imwrite(f'./out/img-{index}.jpg', i)
    cv2.imwrite(f'./out/pred-{index}.jpg', j*255.)
    cv2.imwrite(f'./out/ground-{index}.jpg', k*255.)
    
    plt.subplot(10, 2, index)
    plt.imshow(i/255.)
    plt.title('Ground truth image')
    
    plt.subplot(10, 2, index+1)
    plt.imshow(j, cmap='gray')
    plt.title('Pred mask')
    index += 2

# create metrices
accuracy = tf.keras.metrics.Accuracy()
precision = tf.keras.metrics.Precision()
recal = tf.keras.metrics.Recall()
iou = tf.keras.metrics.IoU(num_classes=2, target_class_ids=[1])


# accuracy
accuracy.update_state(Y_val, preds)
accuracy_value = accuracy.result().numpy()
# precision
precision.update_state(Y_val, preds)
precision_value = precision.result().numpy()
# recal
recal.update_state(Y_val, preds)
recal_value = recal.result().numpy()
# f1 score
f1_score = 2 / ((1 / precision_value) + (1 / recal_value))

# Intersection over union (IoU)
iou.update_state(Y_val, preds)
iou_value = iou.result().numpy()

print("Accuracy:", accuracy_value)
print("Precision:", precision_value)
print("Recall:", recal_value)
print('F1 Score: ', f1_score)
print('IoU: ', iou_value)
Accuracy: 0.97897863
Precision: 0.7686643
Recall: 0.73975855
F1 Score:  0.7539344668559255
IoU:  0.605052
# create metrices
accuracy = tf.keras.metrics.Accuracy()
precision = tf.keras.metrics.Precision()
recal = tf.keras.metrics.Recall()
iou = tf.keras.metrics.IoU(num_classes=2, target_class_ids=[1])
from sklearn.metrics import mean_squared_error
import math
# Calculate MSE
mse_value = mean_squared_error(Y_val.flatten(), preds.flatten())

# Calculate RMSE
rmse_value = math.sqrt(mse_value)
# accuracy
accuracy.update_state(Y_val, preds)
accuracy_value = accuracy.result().numpy()
# precision
precision.update_state(Y_val, preds)
precision_value = precision.result().numpy()
# recal
recal.update_state(Y_val, preds)
recal_value = recal.result().numpy()
# f1 score
f1_score = 2 / ((1 / precision_value) + (1 / recal_value))

# Intersection over union (IoU)
iou.update_state(Y_val, preds)
iou_value = iou.result().numpy()

print("Accuracy:", accuracy_value)
print("Precision:", precision_value)
print("Recall:", recal_value)
print('F1 Score: ', f1_score)
print('IoU: ', iou_value)
# Print the results
print("Mean Squared Error (MSE):", mse_value)
print("Root Mean Squared Error (RMSE):", rmse_value)
Accuracy: 0.97897863
Precision: 0.7686643
Recall: 0.73975855
F1 Score:  0.7539344668559255
IoU:  0.605052
Mean Squared Error (MSE): 0.0210213623046875
Root Mean Squared Error (RMSE): 0.1449874556804398
GRAPHICAL VISUALIZATION OF METRICS
# Plot training and validation metrics with markers for starting and ending points
plt.figure(figsize=(12, 6))

# Plot Training and Validation Loss
plt.subplot(2, 1, 1)  # Two subplots in a vertical arrangement

plt.plot(history.history['loss'], label='Training Loss', marker='o')
plt.plot(history.history['val_loss'], label='Validation Loss', marker='o')
plt.title('Training and Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.ylim(-0.1, 1.1)  # Set y-axis limits for loss with padding

# Display values for starting and ending points on the loss plot
start_loss_coord = (0, history.history['loss'][0])
end_loss_coord = (epochs-1, history.history['loss'][-1])
plt.text(*start_loss_coord, f'({start_loss_coord[0]}, {start_loss_coord[1]:.4f})', color='green', fontsize=10, ha='right', weight='bold')
plt.text(*end_loss_coord, f'({end_loss_coord[0]}, {end_loss_coord[1]:.4f})', color='red', fontsize=10, ha='right', weight='bold')

plt.subplot(2, 1, 2)  # Second subplot for accuracy

# Plot Training and Validation Accuracy
plt.plot(history.history['accuracy'], label='Training Accuracy', marker='o')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy', marker='o')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.ylim(-0.1, 1.1)  # Set y-axis limits for accuracy with padding

# Display values for starting and ending points on the accuracy plot
start_accuracy_coord = (0, history.history['accuracy'][0])
end_accuracy_coord = (epochs-1, history.history['accuracy'][-1])
plt.text(*start_accuracy_coord, f'({start_accuracy_coord[0]}, {start_accuracy_coord[1]:.4f})', color='green', fontsize=10, ha='right', weight='bold')
plt.text(*end_accuracy_coord, f'({end_accuracy_coord[0]}, {end_accuracy_coord[1]:.4f})', color='red', fontsize=10, ha='right', weight='bold')

plt.tight_layout()  # Adjust layout for better visualization

plt.show()

# Plot training and validation metrics with markers for starting and ending points
plt.figure(figsize=(12, 6))

# Plot Training and Validation Loss
plt.subplot(2, 1, 1)  # Two subplots in a vertical arrangement

plt.plot(history.history['loss'], label='Training Loss', marker='o')
plt.plot(history.history['val_loss'], label='Validation Loss', marker='o')
plt.title('Training and Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.ylim(-0.1, 1.1)  # Set y-axis limits for loss with padding

# Display values for starting and ending points on the loss plot
start_loss_coord = (0, history.history['loss'][0])
end_loss_coord = (epochs-1, history.history['loss'][-1])
plt.text(*start_loss_coord, f'({start_loss_coord[0]}, {start_loss_coord[1]:.4f})', color='green', fontsize=10, ha='right', weight='bold')
plt.text(*end_loss_coord, f'({end_loss_coord[0]}, {end_loss_coord[1]:.4f})', color='red', fontsize=10, ha='right', weight='bold')

plt.subplot(2, 1, 2)  # Second subplot for accuracy

# Plot Training and Validation Accuracy
plt.plot(history.history['accuracy'], label='Training Accuracy', marker='o')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy', marker='o')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.ylim(-0.1, 1.1)  # Set y-axis limits for accuracy with padding

# Display values for starting and ending points on the accuracy plot
start_accuracy_coord = (0, history.history['accuracy'][0])
end_accuracy_coord = (epochs-1, history.history['accuracy'][-1])
plt.text(*start_accuracy_coord, f'({start_accuracy_coord[0]}, {start_accuracy_coord[1]:.4f})', color='green', fontsize=10, ha='right', weight='bold')
plt.text(*end_accuracy_coord, f'({end_accuracy_coord[0]}, {end_accuracy_coord[1]:.4f})', color='red', fontsize=10, ha='right', weight='bold')

plt.tight_layout()  # Adjust layout for better visualization

# Save the plot to a file
plt.savefig('training_validation_plot.png')

# Show the plot
plt.show()

# Plot training and validation metrics with dot markers for starting and ending points
plt.figure(figsize=(12, 6))

# Plot Training and Validation Loss
plt.subplot(2, 1, 1)  # Two subplots in a vertical arrangement

# Plot without 'o' marker for all epochs
plt.plot(history.history['loss'], label='Training Loss', marker='None', linestyle='-', color='blue')
plt.plot(history.history['val_loss'], label='Validation Loss', marker='None', linestyle='-', color='orange')

# Dot marker for starting point
plt.scatter(*start_loss_coord, color='green', s=50, label='Start') 

# Dot marker for ending point
plt.scatter(*end_loss_coord, color='red', s=50, label='End')  

plt.title('Training and Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.ylim(-0.1, 1.1)  # Set y-axis limits for loss with padding

# Display values for starting and ending points on the loss plot
plt.text(*start_loss_coord, f'({start_loss_coord[0]}, {start_loss_coord[1]:.4f})', color='green', fontsize=10, ha='right', va='bottom', weight='bold')
plt.text(*end_loss_coord, f'({end_loss_coord[0]}, {end_loss_coord[1]:.4f})', color='red', fontsize=10, ha='right', va='bottom', weight='bold')

plt.subplot(2, 1, 2)  # Second subplot for accuracy

# Plot without 'o' marker for all epochs
plt.plot(history.history['accuracy'], label='Training Accuracy', marker='None', linestyle='-', color='blue')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy', marker='None', linestyle='-', color='orange')

# Dot marker for starting point
plt.scatter(*start_accuracy_coord, color='green', s=50, label='Start')  

# Dot marker for ending point
plt.scatter(*end_accuracy_coord, color='red', s=50, label='End')  

plt.title('Training and Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.ylim(-0.1, 1.1)  # Set y-axis limits for accuracy with padding

# Display values for starting and ending points on the accuracy plot
plt.text(*start_accuracy_coord, f'({start_accuracy_coord[0]}, {start_accuracy_coord[1]:.4f})', color='green', fontsize=10, ha='right', va='bottom', weight='bold')
plt.text(*end_accuracy_coord, f'({end_accuracy_coord[0]}, {end_accuracy_coord[1]:.4f})', color='red', fontsize=10, ha='right', va='bottom', weight='bold')

plt.tight_layout()  # Adjust layout for better visualization

# Save the plot to a file
plt.savefig('training_validation_plot.png')

# Show the plot
plt.show()

RECALL CURVE
from sklearn.metrics import recall_score

# Calculate recall
recall_val = recall_score(Y_val.flatten(), preds.flatten())

# Plot Recall Curve
plt.plot([0, 1], [0, recall_val], label=f'Recall: {recall_val:.4f}', marker='o')
plt.xlabel('False Positive Rate')
plt.ylabel('Recall')
plt.title('Recall Curve')
plt.legend()
plt.grid(True)
plt.savefig('recall_curve.png')
plt.show()

PRECISION CURVE
from sklearn.metrics import precision_score

# Calculate precision
precision_val = precision_score(Y_val.flatten(), preds.flatten())

# Plot Precision Curve
plt.plot([0, 1], [0, precision_val], label=f'Precision: {precision_val:.4f}', marker='o')
plt.xlabel('False Positive Rate')
plt.ylabel('Precision')
plt.title('Precision Curve')
plt.legend()
plt.grid(True)
plt.savefig('precision_curve.png')
plt.show()

PRECISION RECALL CURVE
from sklearn.metrics import precision_recall_curve

# Calculate precision-recall curve values
precision, recall, _ = precision_recall_curve(Y_val.flatten(), preds.flatten())

# Plot Recall-Precision Curve
plt.plot(recall, precision, label='Recall-Precision Curve', marker='o')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Recall-Precision Curve')
plt.legend()
plt.grid(True)
plt.savefig('recall_precision_curve.png')
plt.show()

F1 SCORE
from sklearn.metrics import f1_score

# Calculate F1 Score
f1_score_val = f1_score(Y_val.flatten(), preds.flatten())

# Plot F1 Score Curve
plt.plot([0, 1], [0, f1_score_val], label=f'F1 Score: {f1_score_val:.4f}', marker='o')
plt.xlabel('False Positive Rate')
plt.ylabel('F1 Score')
plt.title('F1 Score Curve')
plt.legend()
plt.grid(True)
plt.savefig('f1_score_curve.png')
plt.show()

ACCURACY CURVE
# Plot Accuracy Curve
plt.plot([0, 1], [0, accuracy_value], label=f'Accuracy: {accuracy_value:.4f}', marker='o')
plt.xlabel('False Positive Rate')
plt.ylabel('Accuracy')
plt.title('Accuracy Curve')
plt.legend()
plt.grid(True)
plt.savefig('accuracy_curve.png')
plt.show()

IoU CURVE
from sklearn.metrics import confusion_matrix

# Calculate confusion matrix
conf_matrix = confusion_matrix(Y_val.flatten(), preds.flatten())

# Calculate True Positive, False Positive, False Negative
tp = conf_matrix[1, 1]
fp = conf_matrix[0, 1]
fn = conf_matrix[1, 0]

# Calculate IoU (Jaccard Index)
iou_val = tp / (tp + fp + fn)

# Plot IoU Curve
plt.plot([0, 1], [0, iou_val], label=f'IoU: {iou_val:.4f}', marker='o')
plt.xlabel('False Positive Rate')
plt.ylabel('IoU')
plt.title('IoU Curve')
plt.legend()
plt.grid(True)
plt.savefig('iou_curve.png')
plt.show()

PRECISION-RECALL CURVE(WITH VALUES)`
# Plot Recall Curve with values
plt.figure(figsize=(8, 6))
plt.plot(recall, precision, label='Recall Curve', marker='o')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Recall-Precision Curve')
plt.legend()

# Annotate Recall and Precision values on the plot
for i, txt in enumerate(recall):
    plt.annotate(f'Recall: {recall[i]:.3f}\nPrecision: {precision[i]:.3f}', (recall[i], precision[i]), textcoords="offset points", xytext=(0,10), ha='center')

# Show the Recall Curve plot
plt.grid(True)
plt.tight_layout()
plt.show()

from sklearn.metrics import recall_score

# Calculate recall
recall_val = recall_score(Y_val.flatten(), preds.flatten())

# Plot Recall Curve
plt.plot([0, 1], [0, recall_val], label=f'Recall: {recall_val:.4f}', marker='o')
plt.xlabel('False Positive Rate')
plt.ylabel('Recall')
plt.title('Recall Curve')
plt.legend()

# Annotate starting and ending point values
plt.annotate(f'(0, 0)', (0, 0), textcoords="offset points", xytext=(0,10), ha='center')
plt.annotate(f'(1, {recall_val:.4f})', (1, recall_val), textcoords="offset points", xytext=(0,10), ha='center')

plt.grid(True)
plt.savefig('recall_curve.png')
plt.show()

ROC CURVE
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt

# Assuming preds and Y_val are numpy arrays

# Calculate False Positive Rate (FPR), True Positive Rate (TPR), and thresholds
fpr, tpr, thresholds = roc_curve(Y_val.flatten(), preds.flatten())

# Calculate Area Under the Curve (AUC)
roc_auc = auc(fpr, tpr)

# Print AUC value
print("Area Under the Curve (AUC): {:.2f}".format(roc_auc))

# Plot ROC curve
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = {:.2f})'.format(roc_auc))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc='lower right')
plt.show()"