0

I have 700 chest MRI images with related ground truths. i am trying to segment the images with the help of U-Net network.Firsly i resize the image and then normalize them. then split the data to traing, validation and test part. then after feed the images and ground truths(masks) to the unet network. but my dice coefficent is so poor and about 0.20. here you can see my script in python. could you please help me how to improve my result?

import keras
from keras import layers
import numpy as np
import cv2
import glob
import matplotlib.pyplot as plt
from keras.models import *
from keras.layers import *
from keras import backend as keras

from keras.callbacks import ModelCheckpoint, LearningRateScheduler, EarlyStopping, ReduceLROnPlateau
from IPython.display import clear_output
from sklearn.model_selection import train_test_split



# define the paths to the images and their ground truths
image_paths = glob.glob('/home/somayeh/Desktop/archive (3)/Lung Segmentation/CXR_png/*.png')
mask_paths = glob.glob("/home/somayeh/Desktop/archive (3)/Lung Segmentation/masks/*.png")

# initialize empty arrays to hold the images and masks
images = []
masks = []
images_superpixel = []
binary_masks = []



# loop over the image and mask paths
for image_path, mask_path in zip(image_paths, mask_paths):
    # read the image and mask using OpenCV
    image = cv2.imread(image_path)
    mask = cv2.imread(mask_path)  # read the mask as grayscale


    # resize the image and mask to the desired dimensions
    image = cv2.resize(image, (256, 256))
    mask = cv2.resize(mask, (256, 256))



    # normalize the image and mask to have values between 0 and 1
    image = image / 255.0
    mask = mask / 255.0
    # add the image and mask to the corresponding arrays
    images.append(image)
    masks.append(mask)



images = np.array(images)
masks = np.array(masks)


# add a channel dimension to the masks
masks = np.expand_dims(masks, axis=-1)
# #
# #
def dice_coef(y_true, y_pred):
    y_true_f = keras.flatten(y_true)
    y_pred_f = keras.flatten(y_pred)
    intersection = keras.sum(y_true_f * y_pred_f)
    return (2. * intersection + 1 ) / (keras.sum(y_true_f) + keras.sum(y_pred_f))

def dice_coef_loss(y_true, y_pred):
    return -dice_coef(y_true, y_pred)

def build_unet(input_size=(256,256,3)):

    inputs  = Input(input_size)
    conv1 = Conv2D(32, (3,3), activation='relu', padding='same')(inputs)
    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1)
    pool1 = MaxPooling2D(pool_size=(2,2))(conv1)

    conv2 = Conv2D(64, (3,3), activation='relu', padding='same')(pool1)
    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv2)
    pool2 = MaxPooling2D(pool_size=(2,2))(conv2)

    conv3 = Conv2D(128, (3,3), activation='relu', padding='same')(pool2)
    conv3 = Conv2D(128, (3,3), activation='relu', padding='same')(conv3)
    pool3 = MaxPooling2D(pool_size=(2,2))(conv3)

    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool3)
    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv4)
    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)

    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool4)
    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv5)
    pool5 = MaxPooling2D(pool_size=(2, 2))(conv5)

    conv6 = Conv2D(1024, (3, 3), activation='relu', padding='same') (pool5)
    conv6 = Conv2D(1024, (3, 3), activation = 'relu', padding='same')(conv6)
    pool6 = MaxPooling2D(pool_size=(2, 2))(conv6)


    up7 = layers.concatenate([Conv2DTranspose(512, (2,2), strides=(2,2), padding='same')(conv6), conv5], axis=3)

    conv7 = Conv2D(512, (3, 3), activation='relu', padding='same')(up7)
    conv7 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv7)


    up8 = layers.concatenate([Conv2DTranspose(256, (2,2), strides=(2,2), padding='same')(conv7), conv4], axis=3)

    conv8 = Conv2D(256, (3, 3), activation='relu', padding='same')(up8)
    conv8 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv8)

    up9 = layers.concatenate([Conv2DTranspose(128, (2,2), strides=(2,2), padding='same')(conv8), conv3], axis=3)

    conv9 = Conv2D(128, (3, 3), activation='relu', padding='same')(up9)
    conv9 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv9)

    up10 = layers.concatenate([Conv2DTranspose(64, (2,2), strides=(2,2), padding='same')(conv9), conv2], axis=3)

    conv10 = Conv2D(64, (3, 3), activation='relu', padding='same')(up10)
    conv10 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv10)

    up11 = layers.concatenate([Conv2DTranspose(32, (2,2), strides=(2,2), padding='same')(conv10), conv1], axis=3)

    conv11 = Conv2D(32, (3, 3), activation='relu', padding='same')(up11)
    conv11 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv11)

    conv12 = Conv2D(3, (1,1), activation='sigmoid')(conv11)

    return Model(inputs=[inputs], outputs=[conv12])

#  callbacks, early stopping and reduced LR
weight_path="{}_weights.best.hdf5".format('cxr_reg')

checkpoint = ModelCheckpoint(weight_path, monitor='val_loss', verbose=1,
                             save_best_only=True, mode='min', save_weights_only = True)

reduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.5,
                                   patience=3,
                                   verbose=1, mode='min', epsilon=0.0001, cooldown=2, min_lr=1e-6)
early = EarlyStopping(monitor="val_loss",
                      mode="min",
                      patience=15) # probably needs to be more patient, but kaggle time is limited
callbacks_list = [checkpoint, early, reduceLROnPlat]

# 5. Train the model using the preprocessed data.

model = build_unet((256,256,3))
model.compile(optimizer='adam', loss=dice_coef_loss, metrics=dice_coef)
model.summary()


model.compile(optimizer='adam', loss=dice_coef_loss, metrics=dice_coef)

train_vol, validation_vol, train_seg, validation_seg = train_test_split(images,
                                                            masks,
                                                            test_size = 0.4,random_state = 2018)
print(train_vol.shape)
#
validation_vol, test_vol, validation_seg, test_seg = train_test_split(validation_vol,validation_seg,
                                                            test_size = 0.4,
                                                            random_state = 2018)
print(validation_vol)
print(test_vol)

#
loss_history = model.fit(train_vol,
                       train_seg,
                         batch_size = 30,
                  epochs = 50,
                  validation_data =(test_vol,test_seg),callbacks=callbacks_list )


clear_output()
#
pred_candidates = np.random.randint(1, validation_vol.shape[0], 10)
preds = model.predict(validation_vol)

plt.figure(figsize=(20, 10))

for i in range(0, 9, 3):
    plt.subplot(3, 3, i + 1)

    plt.imshow(np.squeeze(validation_vol[pred_candidates[i]]))
    plt.xlabel("Base Image")
#
    plt.subplot(3, 3, i + 2)
    plt.imshow(np.squeeze(validation_seg[pred_candidates[i]]))
    plt.xlabel("Mask")

    plt.subplot(3, 3, i + 3)
    plt.imshow(np.squeeze(preds[pred_candidates[i]]))
    plt.xlabel("Pridiction")

0 Answers0