{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport tensorflow\nimport pandas as pd\nimport albumentations\nimport cv2\n\nimport keras\nimport tensorflow as tf\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.optimizers import *\nfrom tensorflow.keras.callbacks import ModelCheckpoint","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2023-11-12T09:30:22.355735Z","iopub.execute_input":"2023-11-12T09:30:22.356618Z","iopub.status.idle":"2023-11-12T09:30:32.065875Z","shell.execute_reply.started":"2023-11-12T09:30:22.356582Z","shell.execute_reply":"2023-11-12T09:30:32.065007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(tf.__version__)\nprint(keras.__version__)\n!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:32.067525Z","iopub.execute_input":"2023-11-12T09:30:32.068049Z","iopub.status.idle":"2023-11-12T09:30:33.050905Z","shell.execute_reply.started":"2023-11-12T09:30:32.068022Z","shell.execute_reply":"2023-11-12T09:30:33.049703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Metrics","metadata":{}},{"cell_type":"code","source":"#intersection over union\ndef iou(y_true, y_pred, smooth = 0.5):\n    intersection = K.sum(y_true * y_pred)\n    sum_ = K.sum(y_true + y_pred)\n    jac = (intersection + smooth) / (sum_ - intersection + smooth)\n    return jac\n\n\n# Computing Sensitivity      \ndef sensitivity(y_true, y_pred):\n    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n    return true_positives / (possible_positives + K.epsilon())\n\n# Computing Specificity\ndef specificity(y_true, y_pred):\n    true_negatives = K.sum(K.round(K.clip((1-y_true) * (1-y_pred), 0, 1)))\n    possible_negatives = K.sum(K.round(K.clip(1-y_true, 0, 1)))\n    return true_negatives / (possible_negatives + K.epsilon())\n\ndef f1_score(y_true, y_pred):\n    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n    precision = true_positives / (predicted_positives + K.epsilon())\n    recall = true_positives / (possible_positives + K.epsilon())\n    f1_val = 2*(precision*recall)/(precision+recall+K.epsilon())\n    return f1_val\n\n# Define Dice coefficient metric\ndef dice_coefficient(y_true, y_pred, epsilon=1e-6):\n    y_true_flat = tf.reshape(y_true, [-1])\n    y_pred_flat = tf.reshape(y_pred, [-1])\n    intersection = tf.reduce_sum(y_true_flat * y_pred_flat)\n    dice_score = (2.0 * intersection + epsilon) / (tf.reduce_sum(y_true_flat) + tf.reduce_sum(y_pred_flat) + epsilon)\n    return dice_score\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:33.052496Z","iopub.execute_input":"2023-11-12T09:30:33.052816Z","iopub.status.idle":"2023-11-12T09:30:33.065571Z","shell.execute_reply.started":"2023-11-12T09:30:33.052788Z","shell.execute_reply":"2023-11-12T09:30:33.064704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def tversky(y_true, y_pred, smooth=1, alpha=0.7):\n    y_true_pos = K.flatten(y_true)\n    y_pred_pos = K.flatten(y_pred)\n    true_pos = K.sum(y_true_pos * y_pred_pos)\n    false_neg = K.sum(y_true_pos * (1 - y_pred_pos))\n    false_pos = K.sum((1 - y_true_pos) * y_pred_pos)\n    return (true_pos + smooth) / (true_pos + alpha * false_neg + (1 - alpha) * false_pos + smooth)\n\ndef tversky_loss(y_true, y_pred):\n    return 1 - tversky(y_true, y_pred)\n\ndef focal_tversky_loss(y_true, y_pred, gamma=0.75):\n    tv = tversky(y_true, y_pred)\n    return K.pow((1 - tv), gamma)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:33.068316Z","iopub.execute_input":"2023-11-12T09:30:33.068687Z","iopub.status.idle":"2023-11-12T09:30:33.077664Z","shell.execute_reply.started":"2023-11-12T09:30:33.068653Z","shell.execute_reply":"2023-11-12T09:30:33.076772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CallBacks","metadata":{}},{"cell_type":"code","source":"epochs = 10\n\nearlystop = keras.callbacks.EarlyStopping(monitor='val_loss',\n                          min_delta=0,\n                          patience=epochs,\n                          verbose=1,\n                          restore_best_weights=True\n                          )\n\nreduce_lr = keras.callbacks.ReduceLROnPlateau(monitor='val_loss',\n                              factor=0.2,\n                              patience=5,\n                              verbose=1,\n                              min_delta=0.0001)\ncsv_logger = keras.callbacks.CSVLogger('Model.log')\n\n\ncallbacks = [earlystop, csv_logger, reduce_lr]","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:33.078676Z","iopub.execute_input":"2023-11-12T09:30:33.078950Z","iopub.status.idle":"2023-11-12T09:30:33.093215Z","shell.execute_reply.started":"2023-11-12T09:30:33.078926Z","shell.execute_reply":"2023-11-12T09:30:33.092273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prefix = '/kaggle/input/covid-segmentation/'\n\nimages_radiopedia = np.load(os.path.join(prefix, 'images_radiopedia.npy')).astype(np.float32)\nmasks_radiopedia = np.load(os.path.join(prefix, 'masks_radiopedia.npy')).astype(np.int8)\nimages_medseg = np.load(os.path.join(prefix, 'images_medseg.npy')).astype(np.float32)\nmasks_medseg = np.load(os.path.join(prefix, 'masks_medseg.npy')).astype(np.int8)\n\ntest_images_medseg = np.load(os.path.join(prefix, 'test_images_medseg.npy')).astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:33.094514Z","iopub.execute_input":"2023-11-12T09:30:33.095115Z","iopub.status.idle":"2023-11-12T09:30:50.272792Z","shell.execute_reply.started":"2023-11-12T09:30:33.095082Z","shell.execute_reply":"2023-11-12T09:30:50.271821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize(image_batch, mask_batch=None, pred_batch=None, num_samples = 8):\n    num_classes = mask_batch.shape[-1] if mask_batch is not None else 0\n    fix, ax = plt.subplots(num_classes + 1, num_samples, figsize=(num_samples * 2, (num_classes + 1) * 2))\n\n    for i in range(num_samples):\n        ax_image = ax[0, i] if num_classes > 0 else ax[i]\n        ax_image.imshow(image_batch[i,:,:,0], cmap='Greys')\n        ax_image.set_xticks([]) \n        ax_image.set_yticks([])\n        \n        if mask_batch is not None:\n            for j in range(num_classes):\n                if pred_batch is None:\n                    mask_to_show = mask_batch[i,:,:,j]\n                else:\n                    mask_to_show = np.zeros(shape=(*mask_batch.shape[1:-1], 3)) \n                    mask_to_show[..., 0] = pred_batch[i,:,:,j] > 0.5\n                    mask_to_show[..., 1] = mask_batch[i,:,:,j]\n                ax[j + 1, i].imshow(mask_to_show, vmin=0, vmax=1)\n                ax[j + 1, i].set_xticks([]) \n                ax[j + 1, i].set_yticks([]) \n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:50.274207Z","iopub.execute_input":"2023-11-12T09:30:50.274567Z","iopub.status.idle":"2023-11-12T09:30:50.286442Z","shell.execute_reply.started":"2023-11-12T09:30:50.274536Z","shell.execute_reply":"2023-11-12T09:30:50.285406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(images_radiopedia[30:], masks_radiopedia[30:])","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:50.287575Z","iopub.execute_input":"2023-11-12T09:30:50.287840Z","iopub.status.idle":"2023-11-12T09:30:53.089722Z","shell.execute_reply.started":"2023-11-12T09:30:50.287816Z","shell.execute_reply":"2023-11-12T09:30:53.088800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(images_medseg, masks_medseg)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:53.090923Z","iopub.execute_input":"2023-11-12T09:30:53.091218Z","iopub.status.idle":"2023-11-12T09:30:55.863685Z","shell.execute_reply.started":"2023-11-12T09:30:53.091191Z","shell.execute_reply":"2023-11-12T09:30:55.862755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(test_images_medseg)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:55.868103Z","iopub.execute_input":"2023-11-12T09:30:55.868643Z","iopub.status.idle":"2023-11-12T09:30:56.565559Z","shell.execute_reply.started":"2023-11-12T09:30:55.868608Z","shell.execute_reply":"2023-11-12T09:30:56.564658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_hists(images1, images2=None):\n    plt.hist(images1.ravel(), bins=100, density=True, color='b', alpha=1 if images2 is None else 0.5)\n    if images2 is not None:\n        plt.hist(images2.ravel(), bins=100, density=True, alpha=0.5, color='orange')\n    plt.show();","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:56.566768Z","iopub.execute_input":"2023-11-12T09:30:56.567056Z","iopub.status.idle":"2023-11-12T09:30:56.572872Z","shell.execute_reply.started":"2023-11-12T09:30:56.567031Z","shell.execute_reply":"2023-11-12T09:30:56.571800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_hists(images_radiopedia, images_medseg)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:30:56.574167Z","iopub.execute_input":"2023-11-12T09:30:56.574486Z","iopub.status.idle":"2023-11-12T09:31:00.642483Z","shell.execute_reply.started":"2023-11-12T09:30:56.574454Z","shell.execute_reply":"2023-11-12T09:31:00.641624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_hists(test_images_medseg, images_medseg)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:00.643784Z","iopub.execute_input":"2023-11-12T09:31:00.644074Z","iopub.status.idle":"2023-11-12T09:31:01.553798Z","shell.execute_reply.started":"2023-11-12T09:31:00.644047Z","shell.execute_reply":"2023-11-12T09:31:01.552898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess_images(images_arr, mean_std=None):\n    images_arr[images_arr > 500] = 500\n    images_arr[images_arr < -1500] = -1500\n    min_perc, max_perc = np.percentile(images_arr, 5), np.percentile(images_arr, 95)\n    images_arr_valid = images_arr[(images_arr > min_perc) & (images_arr < max_perc)]\n    mean, std = (images_arr_valid.mean(), images_arr_valid.std()) if mean_std is None else mean_std\n    images_arr = (images_arr - mean) / std\n    print(f'mean {mean}, std {std}')\n    return images_arr, (mean, std)\n\nimages_radiopedia, mean_std = preprocess_images(images_radiopedia)\nimages_medseg, _ = preprocess_images(images_medseg, mean_std)\ntest_images_medseg, _ = preprocess_images(test_images_medseg, mean_std)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:01.555198Z","iopub.execute_input":"2023-11-12T09:31:01.555601Z","iopub.status.idle":"2023-11-12T09:31:08.352147Z","shell.execute_reply.started":"2023-11-12T09:31:01.555566Z","shell.execute_reply":"2023-11-12T09:31:08.351196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_hists(images_radiopedia, images_medseg)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:08.353471Z","iopub.execute_input":"2023-11-12T09:31:08.353789Z","iopub.status.idle":"2023-11-12T09:31:12.340214Z","shell.execute_reply.started":"2023-11-12T09:31:08.353763Z","shell.execute_reply":"2023-11-12T09:31:12.339247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_hists(test_images_medseg, images_medseg)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:12.341262Z","iopub.execute_input":"2023-11-12T09:31:12.341532Z","iopub.status.idle":"2023-11-12T09:31:13.254816Z","shell.execute_reply.started":"2023-11-12T09:31:12.341508Z","shell.execute_reply":"2023-11-12T09:31:13.253818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_indexes, train_indexes = list(range(24)), list(range(24, 100))\n\ntrain_images = np.concatenate((images_medseg[train_indexes], images_radiopedia))\ntrain_masks = np.concatenate((masks_medseg[train_indexes], masks_radiopedia))\nval_images = images_medseg[val_indexes]\nval_masks = masks_medseg[val_indexes]\n\nbatch_size = len(val_masks)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:13.256224Z","iopub.execute_input":"2023-11-12T09:31:13.256859Z","iopub.status.idle":"2023-11-12T09:31:13.964429Z","shell.execute_reply.started":"2023-11-12T09:31:13.256824Z","shell.execute_reply":"2023-11-12T09:31:13.963361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SOURCE_SIZE = 512\nTARGET_SIZE = 224\n\ntrain_augs = albumentations.Compose([\n    albumentations.Rotate(limit=360, p=0.9, border_mode = cv2.BORDER_REPLICATE),\n    albumentations.RandomSizedCrop((int(SOURCE_SIZE * 0.75), SOURCE_SIZE), \n                                   TARGET_SIZE, \n                                   TARGET_SIZE, \n                                   interpolation = cv2.INTER_NEAREST),\n    albumentations.HorizontalFlip(p=0.5),\n\n])\n\nval_augs = albumentations.Compose([\n    albumentations.Resize(TARGET_SIZE, TARGET_SIZE, interpolation = cv2.INTER_NEAREST)\n])","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:13.965729Z","iopub.execute_input":"2023-11-12T09:31:13.966118Z","iopub.status.idle":"2023-11-12T09:31:13.973702Z","shell.execute_reply.started":"2023-11-12T09:31:13.966082Z","shell.execute_reply":"2023-11-12T09:31:13.972656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Dataset:   \n    def __init__(\n            self, \n            images, \n            masks,\n            augmentations=None\n    ):\n        self.images = images\n        self.masks = masks\n        self.augmentations = augmentations\n    \n    def __getitem__(self, i):\n        image = self.images[i]\n        mask = self.masks[i]\n        \n        if self.augmentations:\n            sample = self.augmentations(image=image, mask=mask)\n            image, mask = sample['image'], sample['mask']\n        return image, mask\n        \n    def __len__(self):\n        return len(self.images)\n    \n    \nclass Dataloder(tensorflow.keras.utils.Sequence):\n    \n    def __init__(self, dataset, batch_size=1, shuffle=False):\n        self.dataset = dataset\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.indexes = np.arange(len(dataset))\n\n        self.on_epoch_end()\n\n    def __getitem__(self, i):\n        \n        # collect batch data\n        start = i * self.batch_size\n        stop = (i + 1) * self.batch_size\n        images = []\n        masks = []\n        for j in range(start, stop):\n            image, mask = self.dataset[self.indexes[j]]\n            images.append(image)\n            masks.append(mask)\n        \n        images = np.stack(images, axis=0)\n        masks = np.stack(masks, axis=0).astype(np.float32)\n        \n        return (images, masks)\n    \n    def __len__(self):\n        \"\"\"Denotes the number of batches per epoch\"\"\"\n        return len(self.indexes) // self.batch_size\n    \n    def on_epoch_end(self):\n        \"\"\"Callback function to shuffle indexes each epoch\"\"\"\n        if self.shuffle:\n            self.indexes = np.random.permutation(self.indexes)\n            \ntrain_dataset = Dataset(train_images, train_masks, train_augs)\nval_dataset = Dataset(val_images, val_masks, val_augs)\n\ntrain_dataloader = Dataloder(train_dataset, batch_size = batch_size, shuffle = True)\nval_dataloader = Dataloder(val_dataset, batch_size = batch_size, shuffle = False)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:13.974936Z","iopub.execute_input":"2023-11-12T09:31:13.975215Z","iopub.status.idle":"2023-11-12T09:31:13.990620Z","shell.execute_reply.started":"2023-11-12T09:31:13.975190Z","shell.execute_reply":"2023-11-12T09:31:13.989394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_dataset)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:13.991796Z","iopub.execute_input":"2023-11-12T09:31:13.992069Z","iopub.status.idle":"2023-11-12T09:31:14.007385Z","shell.execute_reply.started":"2023-11-12T09:31:13.992045Z","shell.execute_reply":"2023-11-12T09:31:14.006408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"assert train_dataloader[0][0].shape == (batch_size, TARGET_SIZE, TARGET_SIZE, 1)\nassert train_dataloader[0][1].shape == (batch_size, TARGET_SIZE, TARGET_SIZE, 4)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:14.008510Z","iopub.execute_input":"2023-11-12T09:31:14.008865Z","iopub.status.idle":"2023-11-12T09:31:14.179796Z","shell.execute_reply.started":"2023-11-12T09:31:14.008831Z","shell.execute_reply":"2023-11-12T09:31:14.179025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(*next(iter(train_dataloader)))","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:14.180997Z","iopub.execute_input":"2023-11-12T09:31:14.181374Z","iopub.status.idle":"2023-11-12T09:31:16.652222Z","shell.execute_reply.started":"2023-11-12T09:31:14.181323Z","shell.execute_reply":"2023-11-12T09:31:16.651326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(*next(iter(val_dataloader)))","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:16.653560Z","iopub.execute_input":"2023-11-12T09:31:16.653896Z","iopub.status.idle":"2023-11-12T09:31:18.775170Z","shell.execute_reply.started":"2023-11-12T09:31:16.653866Z","shell.execute_reply":"2023-11-12T09:31:18.774305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"#from keras.layers.advanced_activations import ELU\nfrom keras.layers import ELU, PReLU, LeakyReLU","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:18.776548Z","iopub.execute_input":"2023-11-12T09:31:18.777110Z","iopub.status.idle":"2023-11-12T09:31:18.781305Z","shell.execute_reply.started":"2023-11-12T09:31:18.777078Z","shell.execute_reply":"2023-11-12T09:31:18.780483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import Input, Model\nfrom tensorflow.keras.layers import Conv2D, Concatenate, UpSampling2D, Input, BatchNormalization, Activation\nfrom keras.layers import ELU, PReLU, LeakyReLU","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:18.782416Z","iopub.execute_input":"2023-11-12T09:31:18.782716Z","iopub.status.idle":"2023-11-12T09:31:18.794513Z","shell.execute_reply.started":"2023-11-12T09:31:18.782686Z","shell.execute_reply":"2023-11-12T09:31:18.793581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"strategy = tf.distribute.MirroredStrategy()\nprint('Number of devices: {}'.format(strategy.num_replicas_in_sync))","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:18.795589Z","iopub.execute_input":"2023-11-12T09:31:18.795849Z","iopub.status.idle":"2023-11-12T09:31:21.859897Z","shell.execute_reply.started":"2023-11-12T09:31:18.795826Z","shell.execute_reply":"2023-11-12T09:31:21.858892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ELUnet","metadata":{}},{"cell_type":"code","source":"def double_conv_layer(inputs, filters):\n    x = tf.keras.layers.Conv2D(filters, 3, padding='same', activation='ELU')(inputs)\n    x = tf.keras.layers.Conv2D(filters, 3, padding='same', activation='ELU')(x)\n    return x\n\ndef down_block(inputs, filters):\n    c = double_conv_layer(inputs, filters)\n    p = MaxPooling2D(pool_size=(2, 2))(c)\n    return c, p\n\ndef up_block(inputs, concat_layer, filters):\n    x = Conv2DTranspose(filters, (2, 2), strides=(2, 2), padding='same')(inputs)\n    x = concatenate([x, concat_layer], axis=3)\n    x = double_conv_layer(x, filters)\n    return x","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:21.860983Z","iopub.execute_input":"2023-11-12T09:31:21.861282Z","iopub.status.idle":"2023-11-12T09:31:21.868313Z","shell.execute_reply.started":"2023-11-12T09:31:21.861248Z","shell.execute_reply":"2023-11-12T09:31:21.867459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def elu_net(input_shape, num_classes, base_filters):\n    inputs = Input(input_shape)\n\n    # Encoder\n    c1, p1 = down_block(inputs, base_filters)\n    c2, p2 = down_block(p1, base_filters * 2)\n    c3, p3 = down_block(p2, base_filters * 4)\n    c4, p4 = down_block(p3, base_filters * 8)\n\n    # Bridge\n    bridge = double_conv_layer(p4, base_filters * 16)\n\n    # Decoder\n    up_1 = up_block(bridge, c4, base_filters * 8)\n    up_2 = up_block(up_1, c3, base_filters * 4)\n    up_3 = up_block(up_2, c2, base_filters * 2)\n    up_4 = up_block(up_3, c1, base_filters)\n\n    outputs = Conv2D(num_classes, 1, activation='sigmoid')(up_4)\n\n    model = Model(inputs=inputs, outputs=outputs)\n\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:21.875756Z","iopub.execute_input":"2023-11-12T09:31:21.876010Z","iopub.status.idle":"2023-11-12T09:31:21.882932Z","shell.execute_reply.started":"2023-11-12T09:31:21.875988Z","shell.execute_reply":"2023-11-12T09:31:21.882062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (TARGET_SIZE, TARGET_SIZE, 1)  # Adjust the number of channels according to the data\nwith strategy.scope():\n    model = elu_net(input_shape=input_shape, num_classes=4, base_filters=8)\n    model.compile(loss = \"categorical_crossentropy\",\n                optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07), \n              \n                metrics = (['accuracy', \n                            tf.keras.metrics.Precision(name='precision'),\n                            tf.keras.metrics.Recall(name='recall'),\n                            tf.keras.metrics.AUC(name='AUC'),\n                            f1_score, specificity, sensitivity, iou, dice_coefficient, tversky]))\n\nprint(model.input_shape)\nprint(model.output_shape)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:21.883987Z","iopub.execute_input":"2023-11-12T09:31:21.884290Z","iopub.status.idle":"2023-11-12T09:31:22.402527Z","shell.execute_reply.started":"2023-11-12T09:31:21.884261Z","shell.execute_reply":"2023-11-12T09:31:22.401656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model,\n           show_shapes = True,\n           show_dtype= True,\n           show_layer_names = True,\n           show_layer_activations= True,\n           show_trainable= True,\n           rankdir = 'TB',\n           expand_nested = False,\n           dpi = 70)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:22.403742Z","iopub.execute_input":"2023-11-12T09:31:22.404021Z","iopub.status.idle":"2023-11-12T09:31:23.131927Z","shell.execute_reply.started":"2023-11-12T09:31:22.403995Z","shell.execute_reply":"2023-11-12T09:31:23.131025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"code","source":"%%time\nhistory = model.fit(\n    train_dataloader,\n    steps_per_epoch=len(train_dataloader) * 6,\n    epochs = 10,\n    validation_data = val_dataloader,\n    validation_steps = len(val_dataloader),\n    callbacks=callbacks,\n    workers = 4)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:31:23.133208Z","iopub.execute_input":"2023-11-12T09:31:23.133557Z","iopub.status.idle":"2023-11-12T09:35:28.339665Z","shell.execute_reply.started":"2023-11-12T09:31:23.133527Z","shell.execute_reply":"2023-11-12T09:35:28.338625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"Model-ELU.h5\")\nprint('Model save to Disk')","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:28.341151Z","iopub.execute_input":"2023-11-12T09:35:28.341549Z","iopub.status.idle":"2023-11-12T09:35:28.507746Z","shell.execute_reply.started":"2023-11-12T09:35:28.341512Z","shell.execute_reply":"2023-11-12T09:35:28.506799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Results","metadata":{}},{"cell_type":"code","source":"import pandas as pd\ndf = pd.DataFrame(history.history) \ndf.to_excel(\"outputElu.xlsx\")\n#df.to_csv(\"output1.csv\")\ndf.head(10)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:28.508801Z","iopub.execute_input":"2023-11-12T09:35:28.509079Z","iopub.status.idle":"2023-11-12T09:35:28.878257Z","shell.execute_reply.started":"2023-11-12T09:35:28.509054Z","shell.execute_reply":"2023-11-12T09:35:28.877344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Interpreting the Metrics\nfig, ax = plt.subplots(5, 2, figsize=(15, 30))\nax = ax.ravel()\n\nfor i, met in enumerate(['accuracy', 'loss', 'precision', 'recall', 'AUC', 'f1_score','sensitivity', 'specificity','iou', 'dice_coefficient']):\n    ax[i].plot(history.history[met])\n    ax[i].plot(history.history['val_' + met])\n    ax[i].set_title('Model {}'.format(met))\n    ax[i].set_xlabel('epochs')\n    ax[i].set_ylabel(met)\n    ax[i].legend(['train', 'val'])\nplt.savefig(\"Model-Results-Elu.png\")","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:28.880209Z","iopub.execute_input":"2023-11-12T09:35:28.880892Z","iopub.status.idle":"2023-11-12T09:35:32.256287Z","shell.execute_reply.started":"2023-11-12T09:35:28.880854Z","shell.execute_reply":"2023-11-12T09:35:32.255404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test model and inference Time","metadata":{}},{"cell_type":"code","source":"%%time\n# Evaluate the model on the test data using `evaluate`\n#print(\"Evaluate on test data\")\nresults = model.evaluate(val_dataloader, batch_size=16, callbacks= callbacks)\nprint(\"test loss test acc:\", results)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:32.257674Z","iopub.execute_input":"2023-11-12T09:35:32.258044Z","iopub.status.idle":"2023-11-12T09:35:32.652625Z","shell.execute_reply.started":"2023-11-12T09:35:32.258008Z","shell.execute_reply":"2023-11-12T09:35:32.651572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nmodel = tf.keras.models.load_model('Model-ELU.h5',\n                                           compile=False,\n                                           custom_objects={\n                                                'Accuracy': 'accuracy', \n                                                'Precision': tf.keras.metrics.Precision(), \n                                                'Recall': tf.keras.metrics.Recall()})\n\nmodel.compile(Adam(learning_rate=0.001, amsgrad=True),\n              loss = \"categorical_crossentropy\")","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:32.653960Z","iopub.execute_input":"2023-11-12T09:35:32.654349Z","iopub.status.idle":"2023-11-12T09:35:33.083721Z","shell.execute_reply.started":"2023-11-12T09:35:32.654311Z","shell.execute_reply":"2023-11-12T09:35:33.082775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calculate_severity(mask):\n    # Count the number of pixels in the mask\n    total_pixels = mask.shape[0] * mask.shape[1]\n    \n    # Compute the percentage of infected pixels\n    infected_pixels = np.count_nonzero(mask)\n    severity_percentage = (infected_pixels / total_pixels) * 100\n    \n    return severity_percentage","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:33.084934Z","iopub.execute_input":"2023-11-12T09:35:33.085214Z","iopub.status.idle":"2023-11-12T09:35:33.090133Z","shell.execute_reply.started":"2023-11-12T09:35:33.085189Z","shell.execute_reply":"2023-11-12T09:35:33.089239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ninput = val_dataloader[0]\nimage_batch, mask_batch = input\n\npreds = model.predict_on_batch(image_batch)\n#visualize(image_batch, mask_batch, pred_batch=preds)\n\nfor i in range(len(preds)):\n    # Get the i-th predicted mask and corresponding image from the batch\n    pred_mask = preds[i]\n    image = image_batch[i]\n    \n    # Convert the predicted mask to a binary image \n    pred_mask_binary = np.argmax(pred_mask, axis=-1).astype(np.uint8)\n    \n    # Calculate the severity percentage for the predicted mask\n    severity_percentage = calculate_severity(pred_mask_binary)\n    \n    # Display the severity percentage and the corresponding image\n    plt.imshow(image)\n    plt.title(f\"Severity of infection: {severity_percentage}%\")\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:33.091300Z","iopub.execute_input":"2023-11-12T09:35:33.091604Z","iopub.status.idle":"2023-11-12T09:35:40.656816Z","shell.execute_reply.started":"2023-11-12T09:35:33.091579Z","shell.execute_reply":"2023-11-12T09:35:40.655891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nmodel = tf.keras.models.load_model('Model-ELU.h5',\n                                   compile=False)\n\nmodel.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001, amsgrad=True),\n              loss=\"categorical_crossentropy\",\n              metrics = (['accuracy', tf.keras.metrics.Precision(name='precision'),\n                        tf.keras.metrics.Recall(name='recall'),\n                        tf.keras.metrics.AUC(name='AUC'),\n                        specificity, sensitivity, iou, dice_coefficient,tversky]))\n\ninput = val_dataloader[0]\nimage_batch, mask_batch = input\n\npreds = model.predict_on_batch(image_batch)\n\ntest_masks_prediction = preds > 0.3\n# Calculate accuracy\naccuracy = np.mean(test_masks_prediction == mask_batch)\n\n# Print the accuracy score\nprint('Accuracy:', accuracy)\nvisualize(image_batch, test_masks_prediction, num_samples=len(test_images_medseg))","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:40.658013Z","iopub.execute_input":"2023-11-12T09:35:40.658315Z","iopub.status.idle":"2023-11-12T09:35:44.254613Z","shell.execute_reply.started":"2023-11-12T09:35:40.658289Z","shell.execute_reply":"2023-11-12T09:35:44.253680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Quantization","metadata":{}},{"cell_type":"code","source":"converter = tf.lite.TFLiteConverter.from_keras_model(model)\nconverter.optimizations = [tf.lite.Optimize.DEFAULT]\ntflite_quant_model = converter.convert()\n\nopen(\"converted_quant_model.tflite\", \"wb\").write(tflite_quant_model)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:44.255994Z","iopub.execute_input":"2023-11-12T09:35:44.256562Z","iopub.status.idle":"2023-11-12T09:35:51.091203Z","shell.execute_reply.started":"2023-11-12T09:35:44.256528Z","shell.execute_reply":"2023-11-12T09:35:51.090260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Float model in Mb:\", os.path.getsize('converted_quant_model.tflite') / float(2**20))\nprint(\"Quantized model in Mb:\", os.path.getsize('converted_quant_model.tflite') / float(2**20))\nprint(\"Compression ratio:\", os.path.getsize('converted_quant_model.tflite')/os.path.getsize('converted_quant_model.tflite'))","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:51.092535Z","iopub.execute_input":"2023-11-12T09:35:51.092898Z","iopub.status.idle":"2023-11-12T09:35:51.099263Z","shell.execute_reply.started":"2023-11-12T09:35:51.092863Z","shell.execute_reply":"2023-11-12T09:35:51.098351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ELUnet with MobilenetV2 Encoder","metadata":{}},{"cell_type":"code","source":"def elu_net_with_mobilenetv2elu_net(input_shape=input_shape, num_classes=4, base_filters=8):\n    # Create a MobileNetV2 model with RGB input\n    base_model = MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')\n\n    # Remove the last layer to adapt to the single-channel output\n    base_model = Model(inputs=base_model.input, outputs=base_model.get_layer('block_13_expand_relu').output)\n\n    # Decoder\n    decoder = layers.Conv2DTranspose(base_filters * 1, (2, 2), strides=(2, 2), padding='same')(base_model.output)\n    decoder = layers.concatenate([base_model.get_layer('block_6_expand_relu').output, decoder], axis=-1)\n    decoder = layers.Conv2D(base_filters * 1, (3, 3), activation='elu', padding='same')(decoder)\n    \n    decoder = layers.Conv2DTranspose(base_filters * 2, (2, 2), strides=(2, 2), padding='same')(decoder)\n    decoder = layers.concatenate([base_model.get_layer('block_3_expand_relu').output, decoder], axis=-1)\n    decoder = layers.Conv2D(base_filters * 2, (3, 3), activation='elu', padding='same')(decoder)\n\n    decoder = layers.Conv2DTranspose(base_filters * 4, (2, 2), strides=(2, 2), padding='same')(decoder)\n    decoder = layers.concatenate([base_model.get_layer('block_1_expand_relu').output, decoder], axis=-1)\n    decoder = layers.Conv2D(base_filters * 4, (3, 3), activation='elu', padding='same')(decoder)\n\n    # Output layer\n    output = layers.Conv2D(num_classes, (1, 1), activation='softmax')(decoder)\n\n    # Create and compile the model\n    model = Model(inputs=base_model.input, outputs=output)\n    \n    return model\n","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:51.100665Z","iopub.execute_input":"2023-11-12T09:35:51.101338Z","iopub.status.idle":"2023-11-12T09:35:51.112554Z","shell.execute_reply.started":"2023-11-12T09:35:51.101304Z","shell.execute_reply":"2023-11-12T09:35:51.111704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (TARGET_SIZE, TARGET_SIZE, 1)  # Adjust the number of channels according to the data\nwith strategy.scope():\n    model = elu_net(input_shape=input_shape, num_classes=4, base_filters=8)\n    model.compile(loss = \"categorical_crossentropy\",\n                optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07), \n              \n                metrics = (['accuracy', \n                            tf.keras.metrics.Precision(name='precision'),\n                            tf.keras.metrics.Recall(name='recall'),\n                            tf.keras.metrics.AUC(name='AUC'),\n                            f1_score, specificity, sensitivity, iou, dice_coefficient, tversky]))\n\nprint(model.input_shape)\nprint(model.output_shape)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:51.113578Z","iopub.execute_input":"2023-11-12T09:35:51.114266Z","iopub.status.idle":"2023-11-12T09:35:51.556844Z","shell.execute_reply.started":"2023-11-12T09:35:51.114241Z","shell.execute_reply":"2023-11-12T09:35:51.555906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model,\n           show_shapes = True,\n           show_dtype= True,\n           show_layer_names = True,\n           show_layer_activations= True,\n           show_trainable= True,\n           rankdir = 'TB',\n           expand_nested = False,\n           dpi = 70)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:51.558073Z","iopub.execute_input":"2023-11-12T09:35:51.558414Z","iopub.status.idle":"2023-11-12T09:35:51.877170Z","shell.execute_reply.started":"2023-11-12T09:35:51.558381Z","shell.execute_reply":"2023-11-12T09:35:51.876308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nhistory = model.fit(\n    train_dataloader,\n    steps_per_epoch=len(train_dataloader) * 6,\n    epochs = 10,\n    validation_data = val_dataloader,\n    validation_steps = len(val_dataloader),\n    callbacks=callbacks,\n    workers = 4)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:35:51.878435Z","iopub.execute_input":"2023-11-12T09:35:51.878762Z","iopub.status.idle":"2023-11-12T09:39:55.776678Z","shell.execute_reply.started":"2023-11-12T09:35:51.878727Z","shell.execute_reply":"2023-11-12T09:39:55.775726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"Model-ELU-MBV2.h5\")\nprint('Model save to Disk')","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:39:55.777802Z","iopub.execute_input":"2023-11-12T09:39:55.778096Z","iopub.status.idle":"2023-11-12T09:39:55.957795Z","shell.execute_reply.started":"2023-11-12T09:39:55.778070Z","shell.execute_reply":"2023-11-12T09:39:55.956827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Results","metadata":{}},{"cell_type":"code","source":"import pandas as pd\ndf = pd.DataFrame(history.history) \ndf.to_excel(\"outputElu-MBV2.xlsx\")\n#df.to_csv(\"output1.csv\")\ndf.head(10)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:39:55.958994Z","iopub.execute_input":"2023-11-12T09:39:55.959290Z","iopub.status.idle":"2023-11-12T09:39:56.008619Z","shell.execute_reply.started":"2023-11-12T09:39:55.959258Z","shell.execute_reply":"2023-11-12T09:39:56.007680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Interpreting the Metrics\nfig, ax = plt.subplots(5, 2, figsize=(15, 30))\nax = ax.ravel()\n\nfor i, met in enumerate(['accuracy', 'loss', 'precision', 'recall', 'AUC', 'f1_score','sensitivity', 'specificity','iou', 'dice_coefficient']):\n    ax[i].plot(history.history[met])\n    ax[i].plot(history.history['val_' + met])\n    ax[i].set_title('Model {}'.format(met))\n    ax[i].set_xlabel('epochs')\n    ax[i].set_ylabel(met)\n    ax[i].legend(['train', 'val'])\nplt.savefig(\"Model-Results-Elu-MBV2.png\")","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:39:56.009634Z","iopub.execute_input":"2023-11-12T09:39:56.009886Z","iopub.status.idle":"2023-11-12T09:39:59.052199Z","shell.execute_reply.started":"2023-11-12T09:39:56.009863Z","shell.execute_reply":"2023-11-12T09:39:59.051291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test model and inference Time","metadata":{}},{"cell_type":"code","source":"%%time\n# Evaluate the model on the test data using `evaluate`\n#print(\"Evaluate on test data\")\nresults = model.evaluate(val_dataloader, batch_size=16, callbacks= callbacks)\nprint(\"test loss test acc:\", results)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:39:59.053475Z","iopub.execute_input":"2023-11-12T09:39:59.053847Z","iopub.status.idle":"2023-11-12T09:39:59.435265Z","shell.execute_reply.started":"2023-11-12T09:39:59.053810Z","shell.execute_reply":"2023-11-12T09:39:59.434426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nmodel = tf.keras.models.load_model('Model-ELU-MBV2.h5',\n                                           compile=False,\n                                           custom_objects={\n                                                'Accuracy': 'accuracy', \n                                                'Precision': tf.keras.metrics.Precision(), \n                                                'Recall': tf.keras.metrics.Recall()})\n\nmodel.compile(Adam(learning_rate=0.001, amsgrad=True),\n              loss = \"categorical_crossentropy\")","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:39:59.436347Z","iopub.execute_input":"2023-11-12T09:39:59.436644Z","iopub.status.idle":"2023-11-12T09:39:59.796186Z","shell.execute_reply.started":"2023-11-12T09:39:59.436618Z","shell.execute_reply":"2023-11-12T09:39:59.795292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ninput = val_dataloader[0]\nimage_batch, mask_batch = input\n\npreds = model.predict_on_batch(image_batch)\n#visualize(image_batch, mask_batch, pred_batch=preds)\n\nfor i in range(len(preds)):\n    # Get the i-th predicted mask and corresponding image from the batch\n    pred_mask = preds[i]\n    image = image_batch[i]\n    \n    # Convert the predicted mask to a binary image \n    pred_mask_binary = np.argmax(pred_mask, axis=-1).astype(np.uint8)\n    \n    # Calculate the severity percentage for the predicted mask\n    severity_percentage = calculate_severity(pred_mask_binary)\n    \n    # Display the severity percentage and the corresponding image\n    plt.imshow(image)\n    plt.title(f\"Severity of infection: {severity_percentage}%\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:39:59.797237Z","iopub.execute_input":"2023-11-12T09:39:59.797528Z","iopub.status.idle":"2023-11-12T09:40:07.185875Z","shell.execute_reply.started":"2023-11-12T09:39:59.797502Z","shell.execute_reply":"2023-11-12T09:40:07.184980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Quantization","metadata":{}},{"cell_type":"code","source":"converter = tf.lite.TFLiteConverter.from_keras_model(model)\nconverter.optimizations = [tf.lite.Optimize.DEFAULT]\ntflite_quant_model = converter.convert()\n\nopen(\"converted_quant_model.tflite\", \"wb\").write(tflite_quant_model)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:40:07.187300Z","iopub.execute_input":"2023-11-12T09:40:07.187723Z","iopub.status.idle":"2023-11-12T09:40:13.297109Z","shell.execute_reply.started":"2023-11-12T09:40:07.187686Z","shell.execute_reply":"2023-11-12T09:40:13.296148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Float model in Mb:\", os.path.getsize('converted_quant_model.tflite') / float(2**20))\nprint(\"Quantized model in Mb:\", os.path.getsize('converted_quant_model.tflite') / float(2**20))\nprint(\"Compression ratio:\", os.path.getsize('converted_quant_model.tflite')/os.path.getsize('converted_quant_model.tflite'))","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:40:13.298366Z","iopub.execute_input":"2023-11-12T09:40:13.298659Z","iopub.status.idle":"2023-11-12T09:40:13.304406Z","shell.execute_reply.started":"2023-11-12T09:40:13.298632Z","shell.execute_reply":"2023-11-12T09:40:13.303519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ELUnet with MobilenetV3 Encoder","metadata":{}},{"cell_type":"code","source":"def elunet_MobileNetV3(input_shape):\n    encoder = tf.keras.applications.MobileNetV3Small(input_shape=(input_shape[0], input_shape[1], 3), include_top=False, weights='imagenet')\n    encoder.trainable = False\n\n    encoder_outputs = [\n        encoder.get_layer('expanded_conv_6/project/BatchNorm').output,  # 32x32\n        encoder.get_layer('expanded_conv_4/project/BatchNorm').output,  # 64x64\n        encoder.get_layer('expanded_conv_3/squeeze_excite/Conv_1').output,  # 128x128\n        encoder.get_layer('expanded_conv_1/project/BatchNorm').output   # 256x256\n    ]\n    \n \n    # Downsampling path (contracting path)\n    inputs = tf.keras.Input(shape=input_shape)\n    x = tf.keras.layers.Conv2D(3, (1, 1), activation='elu')(inputs)\n    skips = []\n    for down in encoder_outputs:\n        x = tf.keras.layers.Conv2D(filters=128, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.Conv2D(filters=128, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        skips.append(x)\n        x = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(x)\n \n    # Bottleneck\n    x = tf.keras.layers.Conv2D(filters=64, kernel_size=3, activation='elu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.Conv2D(filters=64, kernel_size=3, activation='elu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n \n    # Upsampling path (expanding path)\n    for up, skip in zip(reversed(encoder_outputs), reversed(skips)):\n        x = tf.keras.layers.UpSampling2D(size=(2, 2))(x)\n        x = tf.keras.layers.Concatenate()([x, skip])\n        x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n \n    # Output\n    outputs = tf.keras.layers.Conv2D(filters=4, kernel_size=1, activation='softmax')(x)\n \n    # Create the model\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:42:26.240430Z","iopub.execute_input":"2023-11-12T09:42:26.240779Z","iopub.status.idle":"2023-11-12T09:42:26.255312Z","shell.execute_reply.started":"2023-11-12T09:42:26.240746Z","shell.execute_reply":"2023-11-12T09:42:26.254081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (TARGET_SIZE, TARGET_SIZE, 1)  # Adjust the number of channels according to the data\nwith strategy.scope():\n    model = elunet_MobileNetV3(input_shape=input_shape)\n    model.compile(loss = \"categorical_crossentropy\",\n                optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07), \n              \n                metrics = (['accuracy', \n                            tf.keras.metrics.Precision(name='precision'),\n                            tf.keras.metrics.Recall(name='recall'),\n                            tf.keras.metrics.AUC(name='AUC'),\n                            f1_score, specificity, sensitivity, iou, dice_coefficient, tversky]))\n\nprint(model.input_shape)\nprint(model.output_shape)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:42:34.320351Z","iopub.execute_input":"2023-11-12T09:42:34.320779Z","iopub.status.idle":"2023-11-12T09:42:36.988943Z","shell.execute_reply.started":"2023-11-12T09:42:34.320743Z","shell.execute_reply":"2023-11-12T09:42:36.987997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model,\n           show_shapes = True,\n           show_dtype= True,\n           show_layer_names = True,\n           show_layer_activations= True,\n           show_trainable= True,\n           rankdir = 'TB',\n           expand_nested = False,\n           dpi = 70)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:42:36.991970Z","iopub.execute_input":"2023-11-12T09:42:36.992255Z","iopub.status.idle":"2023-11-12T09:42:37.474826Z","shell.execute_reply.started":"2023-11-12T09:42:36.992230Z","shell.execute_reply":"2023-11-12T09:42:37.473848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nhistory = model.fit(\n    train_dataloader,\n    steps_per_epoch=len(train_dataloader) * 6,\n    epochs = 10,\n    validation_data = val_dataloader,\n    validation_steps = len(val_dataloader),\n    callbacks=callbacks,\n    workers = 4)","metadata":{"execution":{"iopub.status.busy":"2023-11-12T09:42:47.515322Z","iopub.execute_input":"2023-11-12T09:42:47.516183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"Model-ELU-MBV3.h5\")\nprint('Model save to Disk')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Results","metadata":{}},{"cell_type":"code","source":"import pandas as pd\ndf = pd.DataFrame(history.history) \ndf.to_excel(\"outputElu-MBV3.xlsx\")\n#df.to_csv(\"output1.csv\")\ndf.head(10)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Interpreting the Metrics\nfig, ax = plt.subplots(5, 2, figsize=(15, 30))\nax = ax.ravel()\n\nfor i, met in enumerate(['accuracy', 'loss', 'precision', 'recall', 'AUC', 'f1_score','sensitivity', 'specificity','iou', 'dice_coefficient']):\n    ax[i].plot(history.history[met])\n    ax[i].plot(history.history['val_' + met])\n    ax[i].set_title('Model {}'.format(met))\n    ax[i].set_xlabel('epochs')\n    ax[i].set_ylabel(met)\n    ax[i].legend(['train', 'val'])\nplt.savefig(\"Model-Results-Elu-MBV3.png\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test model and inference Time","metadata":{}},{"cell_type":"code","source":"%%time\n# Evaluate the model on the test data using `evaluate`\n#print(\"Evaluate on test data\")\nresults = model.evaluate(val_dataloader, batch_size=16, callbacks= callbacks)\nprint(\"test loss test acc:\", results)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ninput = val_dataloader[0]\nimage_batch, mask_batch = input\n\npreds = model.predict_on_batch(image_batch)\n#visualize(image_batch, mask_batch, pred_batch=preds)\n\nfor i in range(len(preds)):\n    # Get the i-th predicted mask and corresponding image from the batch\n    pred_mask = preds[i]\n    image = image_batch[i]\n    \n    # Convert the predicted mask to a binary image \n    pred_mask_binary = np.argmax(pred_mask, axis=-1).astype(np.uint8)\n    \n    # Calculate the severity percentage for the predicted mask\n    severity_percentage = calculate_severity(pred_mask_binary)\n    \n    # Display the severity percentage and the corresponding image\n    plt.imshow(image)\n    plt.title(f\"Severity of infection: {severity_percentage}%\")\n    plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Quantization","metadata":{}},{"cell_type":"code","source":"converter = tf.lite.TFLiteConverter.from_keras_model(model)\nconverter.optimizations = [tf.lite.Optimize.DEFAULT]\ntflite_quant_model = converter.convert()\n\nopen(\"converted_quant_model.tflite\", \"wb\").write(tflite_quant_model)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Float model in Mb:\", os.path.getsize('converted_quant_model.tflite') / float(2**20))\nprint(\"Quantized model in Mb:\", os.path.getsize('converted_quant_model.tflite') / float(2**20))\nprint(\"Compression ratio:\", os.path.getsize('converted_quant_model.tflite')/os.path.getsize('converted_quant_model.tflite'))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ELUnet with EfficientNetB0 Encoder","metadata":{}},{"cell_type":"code","source":"def elunet_efficientnet(input_shape):\n    encoder = tf.keras.applications.EfficientNetB0(input_shape=(input_shape[0], input_shape[1], 3), include_top=False, weights='imagenet')\n    encoder.trainable = False\n\n    encoder_outputs = [\n        encoder.get_layer('block2a_expand_activation').output,  # 128x128\n        encoder.get_layer('block3a_expand_activation').output,  # 64x64\n        encoder.get_layer('block4a_expand_activation').output,  # 32x32\n        encoder.get_layer('block6a_expand_activation').output,  # 16x16\n        encoder.get_layer('top_activation').output  # 8x8\n    ]\n \n    # Downsampling path (contracting path)\n    inputs = tf.keras.Input(shape=input_shape)\n    x = tf.keras.layers.Conv2D(3, (1, 1), activation='elu')(inputs)\n    skips = []\n    for down in encoder_outputs:\n        x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        skips.append(x)\n        x = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(x)\n \n    # Bottleneck\n    x = tf.keras.layers.Conv2D(filters=64, kernel_size=3, activation='elu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.Conv2D(filters=64, kernel_size=3, activation='elu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n \n    # Upsampling path (expanding path)\n    for up, skip in zip(reversed(encoder_outputs), reversed(skips)):\n        x = tf.keras.layers.UpSampling2D(size=(2, 2))(x)\n        x = tf.keras.layers.Concatenate()([x, skip])\n        x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='elu', padding='same')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n \n    # Output\n    outputs = tf.keras.layers.Conv2D(filters=4, kernel_size=1, activation='softmax')(x)\n \n    # Create the model\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n    return model","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (TARGET_SIZE, TARGET_SIZE, 1)  # Adjust the number of channels according to the data\nwith strategy.scope():\n    model = elunet_MobileNetV3(input_shape=input_shape)\n    model.compile(loss = \"categorical_crossentropy\",\n                optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07), \n              \n                metrics = (['accuracy', \n                            tf.keras.metrics.Precision(name='precision'),\n                            tf.keras.metrics.Recall(name='recall'),\n                            tf.keras.metrics.AUC(name='AUC'),\n                            f1_score, specificity, sensitivity, iou, dice_coefficient, tversky]))\n\nprint(model.input_shape)\nprint(model.output_shape)\nmodel.summary()","metadata":{},"execution_count":null,"outputs":[]}]}