When gt and pd are exactly the same and filled with the same value val, compute_dice returns NaN for the classes that are not the value val. This is due to the resulting zero division at the line: dice = 2 * np.logical_and(pd, gt).sum() / (pd.sum() + gt.sum()). I believe it should return 1.0 since gt and pd are still exactly the same.
I wrote this up to demonstrate this and included a possible fix.
import numpy as np
import random
def compute_dice(truth, pred, classes, use_fix=True):
dice_scores = []
# Compute Dice for each class
for i in range(classes):
try:
pd = np.equal(pred, i)
gt = np.equal(truth, i)
if use_fix and (pd == gt).all():
dice_scores.append(1.0)
continue
dice = 2 * np.logical_and(pd, gt).sum() / (pd.sum() + gt.sum())
dice_scores.append(dice)
except ZeroDivisionError:
dice_scores.append(0.0)
# Return computed Dice scores
return dice_scores
if __name__ == "__main__":
image_shape = (4, 4)
num_classes = 2
val = random.randint(0, num_classes)
gt = np.full(image_shape, val)
pd = np.copy(gt)
print(f"gt/pd: \n{gt}")
dice_score = compute_dice(gt, pd, num_classes, use_fix=True)
print(f"Dice scores: {dice_score}")scores
When
gt
andpd
are exactly the same and filled with the same valueval
, compute_dice returns NaN for the classes that are not the valueval
. This is due to the resulting zero division at the line:dice = 2 * np.logical_and(pd, gt).sum() / (pd.sum() + gt.sum())
. I believe it should return 1.0 sincegt
andpd
are still exactly the same.I wrote this up to demonstrate this and included a possible fix.