SMOOTH = 1e-6
def dice_coef(y_true, y_pred):
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
inter = K.sum(y_true_f * y_pred_f)
return (2. * inter + SMOOTH) / (K.sum(y_true_f) + K.sum(y_pred_f) + SMOOTH)
def dice_loss(y_true, y_pred):
return 1.0 - dice_coef(y_true, y_pred)
def iou_coef(y_true, y_pred, smooth=1e-6):
y_true = tf.squeeze(y_true, axis=-1)
num_classes = K.int_shape(y_pred)[-1]
y_true_oh = tf.one_hot(tf.cast(y_true, tf.int32), depth=num_classes)
y_pred_arg = K.argmax(y_pred, axis=-1)
y_pred_oh = tf.one_hot(y_pred_arg, depth=num_classes)
intersection = K.sum(y_true_oh * y_pred_oh, axis=[0,1,2,3])
union = K.sum(y_true_oh + y_pred_oh, axis=[0,1,2,3]) - intersection
iou = (intersection + smooth) / (union + smooth)
return K.mean(iou)
def combined_dice_ce_loss(y_true, y_pred):
y_true = tf.squeeze(y_true, axis=-1)
num_classes = K.int_shape(y_pred)[-1]
y_true_oh = tf.one_hot(tf.cast(y_true, tf.int32), depth=num_classes)
dice_sum = 0.0
for c in range(1, num_classes):
dice_sum += dice_coef(y_true_oh[..., c], y_pred[..., c])
dice_mean = dice_sum / tf.cast(num_classes - 1, tf.float32)
ce = K.categorical_crossentropy(y_true_oh, y_pred)
ce_mean = K.mean(ce)
return 0.5 * (1.0 - dice_mean) + 0.5 * ce_mean
def dice_whole_tumor(y_true, y_pred):
y_true = tf.squeeze(y_true, axis=-1)
num_classes = K.int_shape(y_pred)[-1]
y_true_oh = tf.one_hot(tf.cast(y_true, tf.int32), depth=num_classes)
y_pred_arg = K.argmax(y_pred, axis=-1)
y_true_wt = K.cast(K.any(y_true_oh[..., 1:], axis=-1), 'float32')
y_pred_wt = K.cast(K.any(tf.stack([tf.equal(y_pred_arg, 1), tf.equal(y_pred_arg, 2), tf.equal(y_pred_arg, 3)], axis=-1), axis=-1), 'float32')
return dice_coef(y_true_wt, y_pred_wt)
def dice_tumor_core(y_true, y_pred):
y_true = tf.squeeze(y_true, axis=-1)
num_classes = K.int_shape(y_pred)[-1]
y_true_oh = tf.one_hot(tf.cast(y_true, tf.int32), depth=num_classes)
y_pred_arg = K.argmax(y_pred, axis=-1)
y_true_tc = K.cast(K.any(tf.stack([y_true_oh[..., 1], y_true_oh[..., 3]], axis=-1), axis=-1), 'float32')
y_pred_tc = K.cast(K.any(tf.stack([tf.equal(y_pred_arg, 1), tf.equal(y_pred_arg, 3)], axis=-1), axis=-1), 'float32')
return dice_coef(y_true_tc, y_pred_tc)
def dice_enhancing_tumor(y_true, y_pred):
y_true = tf.squeeze(y_true, axis=-1)
num_classes = K.int_shape(y_pred)[-1]
y_true_oh = tf.one_hot(tf.cast(y_true, tf.int32), depth=num_classes)
y_pred_arg = K.argmax(y_pred, axis=-1)
y_true_et = y_true_oh[..., 3]
y_pred_et = K.cast(tf.equal(y_pred_arg, 3), 'float32')
return dice_coef(y_true_et, y_pred_et)