CoolFace
Apppublic

JeeKay/brain-tumor-segmentation

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
multitask_train.py280 linesDownload Raw Back to root
1#!/usr/bin/env python2# coding: utf-83 4# In[1]:5 6 7import os8import numpy as np9import tensorflow as tf10from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping11from dataprep_multitask import get_train_val_datasets12from utils.losses import dice_loss, dice_coefficient, focal_tversky_loss  # custom metrics13from models.unet_multitask import build_unet_multioutput14from glob import glob15from visualize import visualize_batch16import h5py17 18os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'  # 3=errors only19os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'20os.environ['TF_GPU_ALLOCATOR'] = 'cuda_malloc_async'21 22# Set seeds for reproducibility23tf.random.set_seed(42)24np.random.seed(42)25 26# Paths27DATA_DIR = "BraTS20/BraTS2020_training_data/content/data"28MODEL_SAVE_PATH = "models/unet_brats.keras"29 30# Hyperparameters31BATCH_SIZE = 832EPOCHS = 3033 34# Load datasets35train_dataset, val_dataset = get_train_val_datasets(DATA_DIR, batch_size=BATCH_SIZE)36 37 38# ------------------- Model Setup -------------------39model = build_unet_multioutput(input_shape=(240, 240, 4))40model.compile(41    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),42    loss={43        'wt_head': focal_tversky_loss,44        'tc_head': focal_tversky_loss,45        'et_head': focal_tversky_loss,46    },47    loss_weights={48        'wt_head': 1.0,49        'tc_head': 1.0,50        'et_head': 2.0,51    },52    metrics={53        'wt_head': dice_coefficient,54        'tc_head': dice_coefficient,55        'et_head': dice_coefficient,56    }57)58 59# ------------------- Callbacks -------------------60callbacks = [61    ModelCheckpoint("models/unet_multihead_brats.keras", save_best_only=True, monitor='val_et_head_dice_coefficient', mode='max'),62    ReduceLROnPlateau(monitor='val_et_head_dice_coefficient', factor=0.5, patience=4, min_lr=1e-6, verbose=1),63    EarlyStopping(monitor='val_et_head_dice_coefficient', mode='max', patience=8, restore_best_weights=True)64]65 66# ------------------- Training -------------------67history = model.fit(68    train_dataset,69    validation_data=val_dataset,70    steps_per_epoch=len(train_dataset) // BATCH_SIZE,71    validation_steps=len(val_dataset) // BATCH_SIZE,72    epochs=EPOCHS,73    callbacks=callbacks74)75 76 77# In[4]:78 79 80import matplotlib.pyplot as plt81 82print("\nGenerating predictions and visualizing...\n")83 84# Get one batch from validation set85for x_batch, y_batch in val_dataset.take(1):86    preds = model.predict(x_batch)87    pred_masks = {88        'wt_head': (preds[0] > 0.5).astype(np.float32),89        'tc_head': (preds[1] > 0.5).astype(np.float32),90        'et_head': (preds[2] > 0.5).astype(np.float32),91    }92 93    def overlay_prediction(img, pred_masks):94        flair = img[:, :, 3]95        flair_norm = (flair - flair.min()) / (flair.max() - flair.min() + 1e-8)96        overlay = np.stack([flair_norm]*3, axis=-1)97        overlay[pred_masks['wt_head'][..., 0] == 1] = [1, 0, 0]  # Red98        overlay[pred_masks['tc_head'][..., 0] == 1] = [0, 1, 0]  # Green99        overlay[pred_masks['et_head'][..., 0] == 1] = [0, 0, 1]  # Blue100        return overlay101 102    for i in range(min(3, x_batch.shape[0])):103        image = x_batch[i].numpy()104        flair = image[:, :, 3]105        pred_overlay = overlay_prediction(image, {106            'wt_head': pred_masks['wt_head'][i],107            'tc_head': pred_masks['tc_head'][i],108            'et_head': pred_masks['et_head'][i],109        })110 111        plt.figure(figsize=(12, 4))112        plt.subplot(1, 2, 1)113        plt.imshow(flair, cmap='gray')114        plt.title("FLAIR")115        plt.axis('off')116 117        plt.subplot(1, 2, 2)118        plt.imshow(pred_overlay)119        plt.title("Predicted Mask Overlay")120        plt.axis('off')121        plt.show()122 123    break124 125 126# In[5]:127 128 129import matplotlib.pyplot as plt130 131def overlay_mask(flair, wt, tc, et):132    """133    Build RGB overlay on FLAIR using WT (red), TC (green), ET (blue) masks.134    """135    flair_norm = (flair - flair.min()) / (flair.max() - flair.min() + 1e-8)136    overlay = np.stack([flair_norm]*3, axis=-1)137    overlay[wt[..., 0] == 1] = [1, 0, 0]  # Red138    overlay[tc[..., 0] == 1] = [0, 1, 0]  # Green139    overlay[et[..., 0] == 1] = [0, 0, 1]  # Blue140    return overlay141 142 143# Predict one batch144for x_batch, y_batch in val_dataset.take(1):145    preds = model.predict(x_batch)146 147    for i in range(3):  # Show first 3 samples148        img = x_batch[i].numpy()149        flair = img[:, :, 3]150 151        # Predicted masks (thresholded)152        wt_pred = (preds[0][i] > 0.5).astype(np.float32)153        tc_pred = (preds[1][i] > 0.5).astype(np.float32)154        et_pred = (preds[2][i] > 0.5).astype(np.float32)155 156        # Ground truth masks157        wt_true = y_batch['wt_head'][i].numpy()158        tc_true = y_batch['tc_head'][i].numpy()159        et_true = y_batch['et_head'][i].numpy()160 161        # Overlays162        gt_overlay = overlay_mask(flair, wt_true, tc_true, et_true)163        pred_overlay = overlay_mask(flair, wt_pred, tc_pred, et_pred)164 165        # Plot side-by-side166        plt.figure(figsize=(10, 5))167        plt.subplot(1, 2, 1)168        plt.imshow(gt_overlay)169        plt.title("Ground Truth Overlay")170        plt.axis('off')171 172        plt.subplot(1, 2, 2)173        plt.imshow(pred_overlay)174        plt.title("Predicted Overlay")175        plt.axis('off')176 177        plt.tight_layout()178        plt.show()179 180    break181 182 183# In[6]:184 185 186import matplotlib.pyplot as plt187import numpy as np188 189def overlay_mask(flair, wt, tc, et):190    """191    Build RGB overlay on FLAIR using WT (red), TC (green), ET (blue).192    """193    flair_norm = (flair - flair.min()) / (flair.max() - flair.min() + 1e-8)194    overlay = np.stack([flair_norm]*3, axis=-1)195    overlay[wt[..., 0] == 1] = [1, 0, 0]  # Red: WT196    overlay[tc[..., 0] == 1] = [0, 1, 0]  # Green: TC197    overlay[et[..., 0] == 1] = [0, 0, 1]  # Blue: ET198    return overlay199 200def overlay_errors(flair, gt, pred):201    """202    Compare prediction vs ground truth:203    - TP (correct) regions keep their color204    - FP (predicted but not GT): Magenta205    - FN (GT but not predicted): Yellow206    """207    flair_norm = (flair - flair.min()) / (flair.max() - flair.min() + 1e-8)208    overlay = np.stack([flair_norm]*3, axis=-1)209 210    for mask_name, color, idx in zip(['wt_head', 'tc_head', 'et_head'],211                                     [[1, 0, 0], [0, 1, 0], [0, 0, 1]],212                                     range(3)):213        gt_mask = gt[mask_name][..., 0]214        pred_mask = pred[mask_name][..., 0]215 216        tp = np.logical_and(gt_mask == 1, pred_mask == 1)217        fn = np.logical_and(gt_mask == 1, pred_mask == 0)  # Missed218        fp = np.logical_and(gt_mask == 0, pred_mask == 1)  # Extra219 220        overlay[tp] = color            # Correct221        overlay[fn] = [1, 1, 0]        # Yellow for FN222        overlay[fp] = [1, 0, 1]        # Magenta for FP223 224    return overlay225 226# Run on one batch227for x_batch, y_batch in val_dataset.take(1):228    preds = model.predict(x_batch)229 230    for i in range(3):231        img = x_batch[i].numpy()232        flair = img[:, :, 3]233 234        # Threshold predictions235        pred_masks = {236            'wt_head': (preds[0][i] > 0.5).astype(np.float32),237            'tc_head': (preds[1][i] > 0.5).astype(np.float32),238            'et_head': (preds[2][i] > 0.5).astype(np.float32)239        }240 241        gt_masks = {242            'wt_head': y_batch['wt_head'][i].numpy(),243            'tc_head': y_batch['tc_head'][i].numpy(),244            'et_head': y_batch['et_head'][i].numpy()245        }246 247        # Overlays248        gt_overlay = overlay_mask(flair, gt_masks['wt_head'], gt_masks['tc_head'], gt_masks['et_head'])249        pred_overlay = overlay_mask(flair, pred_masks['wt_head'], pred_masks['tc_head'], pred_masks['et_head'])250        error_overlay = overlay_errors(flair, gt_masks, pred_masks)251 252        # Plot all 3253        plt.figure(figsize=(18, 5))254        plt.subplot(1, 3, 1)255        plt.imshow(gt_overlay)256        plt.title("Ground Truth Overlay")257        plt.axis('off')258 259        plt.subplot(1, 3, 2)260        plt.imshow(pred_overlay)261        plt.title("Predicted Overlay")262        plt.axis('off')263 264        plt.subplot(1, 3, 3)265        plt.imshow(error_overlay)266        plt.title("Error Overlay\nFN=Yellow | FP=Magenta")267        plt.axis('off')268 269        plt.tight_layout()270        plt.show()271 272    break273 274 275# In[ ]:276 277 278 279 280