As I was training UNET, the dice coef and iou sometimes become greater than 1 and iou > dice
, then after several batches they would become normal again.
As shown in the picture.
I have defined them as following:
def dice_coef(y_true, y_pred, smooth=1):
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
intersection = K.sum(y_true_f * y_pred_f)
return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)
def iou(y_true, y_pred, smooth=1):
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
intersection = K.sum(y_true_f * y_pred_f)
union = K.sum(y_true_f) + K.sum(y_pred_f) - intersection
return (intersection + smooth) / (union + smooth)
def dice_loss(y_true, y_pred):
return 1. - dice_coef(y_true, y_pred)
I have tried adding K.abs()
to y_pred but that results in a worse performance. I feel that since the output is sigmoid activated whether adding K.abs()
or not should give the same result? Also, as you can see my accuracy is weird, I have been relying on dice to judge my model performance, would be greater if someone can point out the issue.
I believe your y_true
images might not be in the range between 0 and 1.... are you sure they're not between 0 and 255? Or that they have a single channel (instead of 3 channels?)
This should not be the cause, but you're using a batch dice, you should use an image dice:
def dice_coef(y_true, y_pred, smooth=1):
y_true_f = K.batch_flatten(y_true)
y_pred_f = K.batch_flatten(y_pred)
intersection = K.sum(y_true_f * y_pred_f, axis=-1)
sums = K.sum(y_true_f, axis=-1) + K.sum(y_pred_f, axis=-1)
return (2. * intersection + smooth) / (sums + smooth)
Usually, I use K.epsilon()
for "smooth" (something very small).
The same goes for iou
:
def iou(y_true, y_pred, smooth=1):
y_true_f = K.batch_flatten(y_true)
y_pred_f = K.batch_flatten(y_pred)
intersection = K.sum(y_true_f * y_pred_f, axis=-1)
union = K.sum(y_true_f, axis=-1) + K.sum(y_pred_f, axis=-1) - intersection
return (intersection + smooth) / (union + smooth)
Example of a channel dice:
#considering shape (batch, classes, image_size, image_size)
def dice_coef(y_true, y_pred, smooth=1):
intersection = K.sum(y_true * y_pred, axis=[2,3])
sums = K.sum(y_true, axis=[2,3]) + K.sum(y_pred, axis=[2,3])
dice = (2. * intersection + smooth) / (sums + smooth)
return K.mean(dice, axis=-1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With