{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":52279,"databundleVersionId":5822112,"sourceType":"competition"},{"sourceId":8380012,"sourceType":"datasetVersion","datasetId":4983219},{"sourceId":8467186,"sourceType":"datasetVersion","datasetId":5048244}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Imports","metadata":{}},{"cell_type":"code","source":"!pip install -U segmentation-models","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:24.579652Z","iopub.execute_input":"2024-05-20T23:34:24.579997Z","iopub.status.idle":"2024-05-20T23:34:38.714130Z","shell.execute_reply.started":"2024-05-20T23:34:24.579969Z","shell.execute_reply":"2024-05-20T23:34:38.712837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport pickle\nimport json, math\nimport numpy as np\nimport random, time\nimport pandas as pd\nfrom PIL import Image\nimport seaborn as sns\nimport shutil, sys, os, gc\nfrom datetime import datetime\nfrom tqdm.notebook import tqdm\nimport matplotlib.pyplot as plt\nfrom scipy.optimize import minimize\n\n\nimport tensorflow as tf\nfrom tensorflow.keras.utils import Sequence\nfrom sklearn.model_selection import train_test_split\n\n\nos.environ['SM_FRAMEWORK'] = 'tf.keras'\nimport segmentation_models as sm","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:38.716456Z","iopub.execute_input":"2024-05-20T23:34:38.716836Z","iopub.status.idle":"2024-05-20T23:34:51.158480Z","shell.execute_reply.started":"2024-05-20T23:34:38.716801Z","shell.execute_reply":"2024-05-20T23:34:51.157429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configs","metadata":{}},{"cell_type":"code","source":"class CFG:\n    SEED = 42\n    THRESHOLD = 0.5\n    MASK_CHANNEL = 1\n    ENCODERS_PATH = \"/kaggle/input/unet-encoders-weight/HuPMAP_UNET/\"\n    ENCODER_WEIGHT = lambda encoder : f\"{CFG.ENCODERS_PATH}/{encoder}/Unet_{encoder}_weights.keras\"\n    IMG_DIR = \"/kaggle/input/hubmap-human-vasculature-dataset-512512/HuPMap/images/\"\n    MASK_DIR = \"/kaggle/input/hubmap-human-vasculature-dataset-512512/HuPMap/masks/\"\n    TILES_FPATH = \"/kaggle/input/hubmap-human-vasculature-dataset-512512/HuPMap/kidney_tiles.csv\"\n    ENCODERS = ['vgg16', 'vgg19', 'resnet34', 'resnet50', 'resnet101', 'resnet152', 'seresnet18', 'seresnet34',\n                'seresnet50', 'seresnet101', 'seresnet152', 'resnext50', 'resnext101', 'seresnext50', 'seresnext101',\n                'inceptionv3', 'inceptionresnetv2','mobilenet','mobilenetv2', 'efficientnetb0', 'efficientnetb1',\n                'efficientnetb2', 'efficientnetb3', 'efficientnetb4', 'efficientnetb5', 'efficientnetb6', 'efficientnetb7']\n\nprint(f\"{len(CFG.ENCODERS)} ENCODER\")","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:51.159768Z","iopub.execute_input":"2024-05-20T23:34:51.160268Z","iopub.status.idle":"2024-05-20T23:34:51.168722Z","shell.execute_reply.started":"2024-05-20T23:34:51.160241Z","shell.execute_reply":"2024-05-20T23:34:51.167858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Utilities","metadata":{}},{"cell_type":"code","source":"# To read images, and their masks\ndef read_mask(index, channel=CFG.MASK_CHANNEL):\n    # loading mask\n    mask = np.load(f\"{CFG.MASK_DIR}{index}.npy\")\n    \n    # Select the specified channels\n    if channel == 1:\n        mask = mask[:, :, 0] # to consider only blood vessels\n    elif channel == 2:\n        selected_channels = mask[:, :, [0, 2]]\n        mask = np.sum(selected_channels, axis=2)\n    else:\n        pass\n    \n    # expanding dimension\n    if len(mask.shape) != 3:\n        mask = np.expand_dims(mask, axis=-1)\n        mask = np.where(mask > 0, 1, 0).astype(np.uint8)\n\n    return mask\n\ndef read_image_mask(df):\n    # Loading data\n    indexes = df['id'].to_numpy()\n    x = np.array([np.load(CFG.IMG_DIR + index + \".npy\") for index in tqdm(indexes, desc=\"Loading images\")])\n    y = np.array([read_mask(index) for index in tqdm(indexes, desc=\"Loading masks\")])\n    gc.collect()\n    \n    return x, y","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:51.170969Z","iopub.execute_input":"2024-05-20T23:34:51.171328Z","iopub.status.idle":"2024-05-20T23:34:51.200461Z","shell.execute_reply.started":"2024-05-20T23:34:51.171289Z","shell.execute_reply":"2024-05-20T23:34:51.199676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# to read encoders metrics csv\ndef read_encoders_metrics(path, encoders, sortby='dice'):\n    df_objects = []\n    \n    for encoder in tqdm(encoders, total=len(encoders)):\n        # loading dataframe\n        df = pd.read_csv(f\"{path}/{encoder}/metrics_dataframe.csv\")\n        metrics = df.iloc[:, 1:-1].mean()\n        \n        # building df object\n        df_object = {}\n        df_object['encoder'] = encoder\n        df_object['dice'] = metrics['dice'] * 100\n        df_object['iou'] = metrics['iou'] * 100\n        df_object['precision'] = metrics['precision'] * 100\n        df_object['recall'] = metrics['recall'] * 100\n        df_object['confidence'] = metrics['confidence']\n        df_object['score'] = metrics['precision'] / metrics['confidence']        \n        df_object['threshold'] = df.iloc[0]['threshold']\n        \n        # appending results\n        df_objects.append(df_object)\n        gc.collect()\n        \n    encoders_dataframe = pd.DataFrame(df_objects)\n    encoders_dataframe.sort_values(by=sortby, ascending=False, inplace=True)\n    \n    # return the sorted frame\n    return encoders_dataframe","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:51.201424Z","iopub.execute_input":"2024-05-20T23:34:51.201689Z","iopub.status.idle":"2024-05-20T23:34:51.210541Z","shell.execute_reply.started":"2024-05-20T23:34:51.201667Z","shell.execute_reply":"2024-05-20T23:34:51.209638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model prediction function\ndef predict_masks(x, encoder, weights):    \n    # Ensure the input image has the right shape for prediction\n    if len(x.shape) == 3:\n        x = np.expand_dims(x, axis=0)  # Add batch dimension if needed\n    \n    #defining unet model\n    unet = sm.Unet(encoder, encoder_weights='imagenet', decoder_use_batchnorm=True, classes=1, activation='sigmoid')\n    unet.load_weights(weights)\n    preprocess_input = sm.get_preprocessing(encoder)\n    \n    # making prediction\n    x_norm = preprocess_input(x)\n    y_hat = unet.predict(x_norm)\n    \n    return y_hat    ","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:51.211793Z","iopub.execute_input":"2024-05-20T23:34:51.212201Z","iopub.status.idle":"2024-05-20T23:34:51.223535Z","shell.execute_reply.started":"2024-05-20T23:34:51.212176Z","shell.execute_reply":"2024-05-20T23:34:51.222659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calculate_metrics(y_true, y_pred, threshold):\n    y_pred_binary = (y_pred > threshold).astype(np.uint8)\n\n    # True Positives, False Positives, False Negatives, True Negatives\n    TP = np.sum((y_true == 1) & (y_pred_binary == 1))\n    FP = np.sum((y_true == 0) & (y_pred_binary == 1))\n    TN = np.sum((y_true == 0) & (y_pred_binary == 0))\n    FN = np.sum((y_true == 1) & (y_pred_binary == 0))\n\n    # Dice coefficient\n    dice_denominator = 2 * TP + FP + FN\n    dice = (2 * TP) / dice_denominator if dice_denominator != 0 else 1\n\n    # Intersection over Union (IoU)\n    iou_denominator = TP + FP + FN\n    iou = TP / iou_denominator if iou_denominator != 0 else 1\n\n    # Precision\n    precision = TP / (TP + FP) if (TP + FP) != 0 else 1\n\n    # Recall\n    recall = TP / (TP + FN) if (TP + FN) != 0 else 1\n\n    # Confidence\n    confidence = np.mean(y_pred)\n\n    return dice, iou, precision, recall, confidence\n\ndef metrics_dataframe(Y, Y_hat, threshold, show_progress=True):\n    n_val = len(Y)\n    df_object = {}\n    df_object['dice'] = []\n    df_object['iou'] = []\n    df_object['precision'] = []\n    df_object['recall'] = []\n    df_object['confidence'] = []\n    df_object['threshold'] = threshold\n\n    for i in tqdm(range(n_val), total=n_val, disable=not show_progress):\n        metrics = calculate_metrics(Y[i], Y_hat[i], threshold)\n        df_object['dice'].append(metrics[0])\n        df_object['iou'].append(metrics[1])\n        df_object['precision'].append(metrics[2])\n        df_object['recall'].append(metrics[3])\n        df_object['confidence'].append(metrics[4])\n        \n    return pd.DataFrame(df_object)\n\ndef plot_result(X, Y_true, Y_pred, cutoff, model='model'):\n    \n    N = X.shape[0]\n    \n    fig, ax = plt.subplots(N,4, figsize = (10, 3*N))\n    \n    for k in range(N):\n        \n        cutoff_img1 = (Y_pred[k,:,:,0] > cutoff).astype(int)\n\n        true_img = np.zeros((512, 512, 3), dtype = np.uint8)\n        true_img[:,:,1] = Y_true[k,:,:,0]*200\n        \n        cutoff1 = np.zeros((512, 512, 3), dtype = np.uint8)\n        \n        cutoff1[:,:,0] = cutoff_img1*230\n        \n        cutoff1[:,:,1] = cutoff_img1*50\n        cutoff1[:,:,2] = cutoff_img1*50\n        \n        diff_photo1 = cutoff1.copy()\n        diff_photo1[:,:,1] += (Y_true[k,:,:,0]*200).astype(np.uint8)\n        \n        ax[k, 0].imshow(X[k])\n        ax[k, 1].imshow(true_img, cmap = \"gray\")\n        ax[k, 2].imshow(cutoff1, cmap = \"gray\")\n        ax[k, 3].imshow(diff_photo1)\n        \n        for j in range(4):\n            ax[k,j].set_xticks([])\n            ax[k,j].set_yticks([])\n    \n        if k == 0:\n            ax[k, 0].set_title(\"kidney tissue\")\n            ax[k, 1].set_title(\"true label\")\n            ax[k, 2].set_title(f\"{model} (cutoff at {cutoff})\")\n            ax[k, 3].set_title(\"Compare (Y:tp)\")","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:58:30.605270Z","iopub.execute_input":"2024-05-20T23:58:30.605639Z","iopub.status.idle":"2024-05-20T23:58:30.626565Z","shell.execute_reply.started":"2024-05-20T23:58:30.605600Z","shell.execute_reply":"2024-05-20T23:58:30.625639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Reading data","metadata":{}},{"cell_type":"code","source":"# read csv file\ntile_df = pd.read_csv(CFG.TILES_FPATH)\n\n# ignore blank masks, and select some features\ntile_df = tile_df[tile_df['annotated'] == 1]\ntile_df = tile_df[(tile_df['blood_vessel'] > 0) | (tile_df['unsure'] > 0)]\ntile_df = tile_df[['id', 'source_wsi', 'dataset', 'dataset_wsi', 'blood_vessel', 'glomerulus', 'unsure']]\n\nprint(tile_df.shape)\ntile_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:51.245011Z","iopub.execute_input":"2024-05-20T23:34:51.245405Z","iopub.status.idle":"2024-05-20T23:34:51.312574Z","shell.execute_reply.started":"2024-05-20T23:34:51.245374Z","shell.execute_reply":"2024-05-20T23:34:51.311764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# spliting data and perserving the same ratio of each class\n_, X_valframe = train_test_split(tile_df, test_size=0.2, random_state=CFG.SEED, stratify=tile_df['dataset_wsi'])\n\n# Loading validation data\nX_val, Y_val = read_image_mask(X_valframe)\nprint(X_valframe.shape, X_val.shape, Y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:51.313635Z","iopub.execute_input":"2024-05-20T23:34:51.313897Z","iopub.status.idle":"2024-05-20T23:34:59.920146Z","shell.execute_reply.started":"2024-05-20T23:34:51.313876Z","shell.execute_reply":"2024-05-20T23:34:59.919251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# reading encoders metrics\nencoders_df = read_encoders_metrics(CFG.ENCODERS_PATH, CFG.ENCODERS)\nencoders_df.head(30)","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:34:59.922417Z","iopub.execute_input":"2024-05-20T23:34:59.922736Z","iopub.status.idle":"2024-05-20T23:35:05.256745Z","shell.execute_reply.started":"2024-05-20T23:34:59.922711Z","shell.execute_reply":"2024-05-20T23:35:05.255848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Ensemble Prediction","metadata":{}},{"cell_type":"code","source":"# Pick best architectures based on dice score\nbest_encoders = encoders_df[:6]['encoder'].to_numpy()\nY_hat_ensemble = [predict_masks(X_val, encoder, CFG.ENCODER_WEIGHT(encoder)) for encoder in tqdm(best_encoders, total=best_encoders.shape[0])]","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:35:05.257846Z","iopub.execute_input":"2024-05-20T23:35:05.258113Z","iopub.status.idle":"2024-05-20T23:46:35.752599Z","shell.execute_reply.started":"2024-05-20T23:35:05.258089Z","shell.execute_reply":"2024-05-20T23:46:35.751607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# list every architecture accuracy\nbest_thresholds = []\nfor _, encoder in enumerate(best_encoders):\n    threshold = encoders_df[encoders_df['encoder'] == encoder].iloc[0]['threshold']\n    metrics = metrics_dataframe(Y_val, Y_hat_ensemble[_], threshold=threshold).mean()\n    best_thresholds.append(threshold)\n    \n    print(f\"{encoder} - {np.round(metrics['dice']*100, 3)}% DICE - {np.round(metrics['iou']*100, 3)}% IOU - {threshold*100}% threshold\")","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:48:06.201184Z","iopub.execute_input":"2024-05-20T23:48:06.202025Z","iopub.status.idle":"2024-05-20T23:48:08.696188Z","shell.execute_reply.started":"2024-05-20T23:48:06.201995Z","shell.execute_reply":"2024-05-20T23:48:08.695246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generate samples for ploting\nn_val = len(X_val)\nnp.random.seed(CFG.SEED + 14)\nval_sample = np.random.choice(n_val, 3)\n\n# ploting prediction of each model\nfor _, threshold in enumerate(tqdm(best_thresholds, total=len(best_thresholds))):\n    plot_result(X_val[val_sample], Y_val[val_sample], Y_hat_ensemble[_][val_sample], cutoff=threshold, model=best_encoders[_])","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:48:48.259636Z","iopub.execute_input":"2024-05-20T23:48:48.260446Z","iopub.status.idle":"2024-05-20T23:48:55.795231Z","shell.execute_reply.started":"2024-05-20T23:48:48.260419Z","shell.execute_reply":"2024-05-20T23:48:55.794371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Average Ensembling","metadata":{}},{"cell_type":"code","source":"# Stack the predictions to create a new dimension\nY_hat_stack = np.stack(Y_hat_ensemble, axis=-1)\n\n# Compute the ensembled prediction\nensembled_pred = np.mean(Y_hat_stack, axis=-1)\n\n# Colculate metrics\nmetrics = metrics_dataframe(Y_val, ensembled_pred, threshold=CFG.THRESHOLD).mean()\nprint(f\"{metrics['dice'] * 100}% Dice - {metrics['iou'] * 100}% IOU - {metrics['precision'] * 100}% Precision - {metrics['recall'] * 100}% Recall - {metrics['confidence'] * 100}% Confidence\")","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:58:55.185425Z","iopub.execute_input":"2024-05-20T23:58:55.186133Z","iopub.status.idle":"2024-05-20T23:58:59.515698Z","shell.execute_reply.started":"2024-05-20T23:58:55.186097Z","shell.execute_reply":"2024-05-20T23:58:59.514784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_result(X_val[val_sample], Y_val[val_sample], ensembled_pred[val_sample], cutoff=CFG.THRESHOLD, model=\"Average Ensembling\")","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:59:01.215661Z","iopub.execute_input":"2024-05-20T23:59:01.216306Z","iopub.status.idle":"2024-05-20T23:59:02.359240Z","shell.execute_reply.started":"2024-05-20T23:59:01.216277Z","shell.execute_reply":"2024-05-20T23:59:02.358280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del Y_hat_stack\ndel ensembled_pred\ndel metrics\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:59:02.361089Z","iopub.execute_input":"2024-05-20T23:59:02.361436Z","iopub.status.idle":"2024-05-20T23:59:02.659763Z","shell.execute_reply.started":"2024-05-20T23:59:02.361407Z","shell.execute_reply":"2024-05-20T23:59:02.658665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Weighted Average Ensembling","metadata":{}},{"cell_type":"code","source":"# Objective function to minimize the negative Dice score\ndef objective(weights, y_preds, y_true):\n    weights = np.array(weights)\n    weights = weights / np.sum(weights)  # Normalize weights\n    weights = weights.reshape(1, 1, 1, 1, -1)\n    ensembled_pred_wavg = np.sum(y_preds * weights, axis=-1)\n    dice = metrics_dataframe(y_true, ensembled_pred_wavg, threshold=0.5, show_progress=False).mean()['dice']\n    return -dice  # We minimize the negative Dice score to maximize Dice\n\n# Initial weights\ninitial_weights = [1/6] * 6\n\n# Stack the predictions to create a new dimension\nY_hat_stack = np.stack(Y_hat_ensemble, axis=-1)\n\n# Optimization\nresult = minimize(objective, initial_weights, args=(Y_hat_stack, Y_val), method='SLSQP', bounds=[(0,1)]*6)\n\n# Normalized optimal weights\noptimal_weights = result.x / np.sum(result.x)\nprint(\"Optimal Weights:\", optimal_weights)\n\n# Apply optimal weights to compute the final ensemble prediction\nweights = optimal_weights.reshape(1, 1, 1, 1, -1)\nensembled_pred = np.sum(Y_hat_stack * weights, axis=-1)\n\n# Calculate final metrics with optimal weights\nmetrics = metrics_dataframe(Y_val, ensembled_pred, threshold=CFG.THRESHOLD).mean()\nprint(f\"{metrics['dice'] * 100}% Dice - {metrics['iou'] * 100}% IOU - {metrics['precision'] * 100}% Precision - {metrics['recall'] * 100}% Recall - {metrics['confidence'] * 100}% Confidence\")","metadata":{"execution":{"iopub.status.busy":"2024-05-20T23:59:07.886053Z","iopub.execute_input":"2024-05-20T23:59:07.886851Z","iopub.status.idle":"2024-05-21T00:02:38.430185Z","shell.execute_reply.started":"2024-05-20T23:59:07.886818Z","shell.execute_reply":"2024-05-21T00:02:38.429023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_result(X_val[val_sample], Y_val[val_sample], ensembled_pred[val_sample], cutoff=CFG.THRESHOLD, model=\"WAEnsembling\")","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:00.084856Z","iopub.execute_input":"2024-05-21T00:03:00.085994Z","iopub.status.idle":"2024-05-21T00:03:01.226454Z","shell.execute_reply.started":"2024-05-21T00:03:00.085961Z","shell.execute_reply":"2024-05-21T00:03:01.225564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del metrics\ndel ensembled_pred\ndel weights\ndel optimal_weights\ndel result\ndel Y_hat_stack\ndel initial_weights\ndel objective\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:19.287362Z","iopub.execute_input":"2024-05-21T00:03:19.288110Z","iopub.status.idle":"2024-05-21T00:03:19.292196Z","shell.execute_reply.started":"2024-05-21T00:03:19.288077Z","shell.execute_reply":"2024-05-21T00:03:19.291146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Majority Voting Ensembling","metadata":{}},{"cell_type":"code","source":"# Convert probabilities to binary masks\nbinary_masks = [(pred > threshold).astype(np.uint8) for pred in Y_hat_ensemble]\n\n# Stack the binary masks to create a new dimension\nbinary_masks_stack = np.stack(binary_masks, axis=-1)  # Shape will be (327, 512, 512, 1, 6)\n\n# Compute majority vote\nensembled_pred = np.sum(binary_masks_stack, axis=-1) > (len(Y_hat_ensemble) / 2)\n\n# Calculate final metrics\nmetrics = metrics_dataframe(Y_val, ensembled_pred, threshold=CFG.THRESHOLD).mean()\nprint(f\"{metrics['dice'] * 100}% Dice - {metrics['iou'] * 100}% IOU - {metrics['precision'] * 100}% Precision - {metrics['recall'] * 100}% Recall - {metrics['confidence'] * 100}% Confidence\")","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:28.084452Z","iopub.execute_input":"2024-05-21T00:03:28.085095Z","iopub.status.idle":"2024-05-21T00:03:32.002252Z","shell.execute_reply.started":"2024-05-21T00:03:28.085064Z","shell.execute_reply":"2024-05-21T00:03:32.001299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_result(X_val[val_sample], Y_val[val_sample], ensembled_pred[val_sample],cutoff=CFG.THRESHOLD, model=\"MVEnsembling\")","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:32.003992Z","iopub.execute_input":"2024-05-21T00:03:32.004274Z","iopub.status.idle":"2024-05-21T00:03:33.168915Z","shell.execute_reply.started":"2024-05-21T00:03:32.004249Z","shell.execute_reply":"2024-05-21T00:03:33.168007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del metrics\ndel ensembled_pred\ndel binary_masks_stack\ndel binary_masks\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:33.170038Z","iopub.execute_input":"2024-05-21T00:03:33.170333Z","iopub.status.idle":"2024-05-21T00:03:33.467533Z","shell.execute_reply.started":"2024-05-21T00:03:33.170306Z","shell.execute_reply":"2024-05-21T00:03:33.466565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Maximum Probability Ensembling","metadata":{}},{"cell_type":"code","source":"# Stack the predictions to create a new dimension\nY_hat_stack = np.stack(Y_hat_ensemble, axis=-1)  # Shape will be (327, 512, 512, 1, 6)\n\n# Compute maximum probability\nensembled_pred = np.max(Y_hat_stack, axis=-1)\n\n# Calculate final metrics\nmetrics = metrics_dataframe(Y_val, ensembled_pred, threshold=CFG.THRESHOLD).mean()\nprint(f\"{metrics['dice'] * 100}% Dice - {metrics['iou'] * 100}% IOU - {metrics['precision'] * 100}% Precision - {metrics['recall'] * 100}% Recall - {metrics['confidence'] * 100}% Confidence\")","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:39.506849Z","iopub.execute_input":"2024-05-21T00:03:39.507664Z","iopub.status.idle":"2024-05-21T00:03:45.864753Z","shell.execute_reply.started":"2024-05-21T00:03:39.507634Z","shell.execute_reply":"2024-05-21T00:03:45.863831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_result(X_val[val_sample], Y_val[val_sample], ensembled_pred[val_sample],cutoff=CFG.THRESHOLD, model=\"MVEnsembling\")","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:45.866696Z","iopub.execute_input":"2024-05-21T00:03:45.867289Z","iopub.status.idle":"2024-05-21T00:03:47.026658Z","shell.execute_reply.started":"2024-05-21T00:03:45.867254Z","shell.execute_reply":"2024-05-21T00:03:47.024795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del metrics\ndel ensembled_pred\ndel Y_hat_stack\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-05-21T00:03:47.028879Z","iopub.execute_input":"2024-05-21T00:03:47.029164Z","iopub.status.idle":"2024-05-21T00:03:47.298325Z","shell.execute_reply.started":"2024-05-21T00:03:47.029134Z","shell.execute_reply":"2024-05-21T00:03:47.297333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}