骰子系数大于 1
Dice coef greater than 1
我在训练UNET的时候,dice coef和iou有时会变得大于1,iou > dice
,然后经过几批又会恢复正常。
如图picture.
我将它们定义如下:
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)
我曾尝试将 K.abs()
添加到 y_pred,但这会导致性能变差。我觉得由于输出是 sigmoid 激活的,是否添加 K.abs()
是否应该给出相同的结果?另外,正如您所看到的,我的准确性很奇怪,我一直依靠骰子来判断我的模型性能,如果有人能指出这个问题会更好。
我相信您的 y_true
图片可能不在 0 到 1 之间的范围内....您确定它们不在 0 到 255 之间吗?或者他们只有一个频道(而不是 3 个频道?)
这应该不是原因,但您使用的是批量骰子,您应该使用图像骰子:
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)
通常,我使用 K.epsilon()
来表示 "smooth"(非常小的东西)。
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)
通道骰子示例:
#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)
我在训练UNET的时候,dice coef和iou有时会变得大于1,iou > dice
,然后经过几批又会恢复正常。
如图picture.
我将它们定义如下:
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)
我曾尝试将 K.abs()
添加到 y_pred,但这会导致性能变差。我觉得由于输出是 sigmoid 激活的,是否添加 K.abs()
是否应该给出相同的结果?另外,正如您所看到的,我的准确性很奇怪,我一直依靠骰子来判断我的模型性能,如果有人能指出这个问题会更好。
我相信您的 y_true
图片可能不在 0 到 1 之间的范围内....您确定它们不在 0 到 255 之间吗?或者他们只有一个频道(而不是 3 个频道?)
这应该不是原因,但您使用的是批量骰子,您应该使用图像骰子:
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)
通常,我使用 K.epsilon()
来表示 "smooth"(非常小的东西)。
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)
通道骰子示例:
#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)