如何在keras语义分割中获取单个class的iou?
How to get iou of single class in keras semantic segmentation?
我正在使用 fchollet 的图像分割指南来执行语义分割。我试图通过将 8 位 img 掩码值标记为 1 和 2 来修改指南以适合我的数据集,就像在 Oxford Pets 数据集中一样。 (在class OxfordPets(keras.utils.Sequence):
中会减去0和1)
问题是如何获得单个 class(例如 1)的 IoU 指标?
我尝试了 Stack Overflow 建议的不同指标,但大多数建议使用我尝试过的 MeanIoU,但结果是 nan loss。这是使用自动对比后的蒙版示例。
PIL.ImageOps.autocontrast(load_img(val_target_img_paths[i]))
该模型似乎训练得很好,但准确性随着时间的推移而下降。
此外,有人可以帮助 解释如何根据 y_true
和 y_pred
计算指标得分吗? 我不太明白什么时候标签值用于 IoU 指标计算。
我当时也有类似的问题。我使用了 jaccard_distance_loss
和 dice_metric
。它们基于 IoU。我的任务是二元分割,所以我猜你可能需要修改代码以防你想将它用于多标签分类问题。
from keras import backend as K
def jaccard_distance_loss(y_true, y_pred, smooth=100):
"""
Jaccard = (|X & Y|)/ (|X|+ |Y| - |X & Y|)
= sum(|A*B|)/(sum(|A|)+sum(|B|)-sum(|A*B|))
The jaccard distance loss is usefull for unbalanced datasets. This has been
shifted so it converges on 0 and is smoothed to avoid exploding or disapearing
gradient.
Ref: https://en.wikipedia.org/wiki/Jaccard_index
@url: https://gist.github.com/wassname/f1452b748efcbeb4cb9b1d059dce6f96
@author: wassname
"""
intersection = K.sum(K.sum(K.abs(y_true * y_pred), axis=-1))
sum_ = K.sum(K.sum(K.abs(y_true) + K.abs(y_pred), axis=-1))
jac = (intersection + smooth) / (sum_ - intersection + smooth)
return (1 - jac) * smooth
def dice_metric(y_pred, y_true):
intersection = K.sum(K.sum(K.abs(y_true * y_pred), axis=-1))
union = K.sum(K.sum(K.abs(y_true) + K.abs(y_pred), axis=-1))
# if y_pred.sum() == 0 and y_pred.sum() == 0:
# return 1.0
return 2*intersection / union
# Example
size = 10
y_true = np.zeros(shape=(size,size))
y_true[3:6,3:6] = 1
y_pred = np.zeros(shape=(size,size))
y_pred[3:5,3:5] = 1
loss = jaccard_distance_loss(y_true,y_pred)
metric = dice_metric(y_pred,y_true)
print(f"loss: {loss}")
print(f"dice_metric: {metric}")
loss: 4.587155963302747
dice_metric: 0.6153846153846154
我正在使用 fchollet 的图像分割指南来执行语义分割。我试图通过将 8 位 img 掩码值标记为 1 和 2 来修改指南以适合我的数据集,就像在 Oxford Pets 数据集中一样。 (在class OxfordPets(keras.utils.Sequence):
中会减去0和1)
问题是如何获得单个 class(例如 1)的 IoU 指标?
我尝试了 Stack Overflow 建议的不同指标,但大多数建议使用我尝试过的 MeanIoU,但结果是 nan loss。这是使用自动对比后的蒙版示例。
PIL.ImageOps.autocontrast(load_img(val_target_img_paths[i]))
该模型似乎训练得很好,但准确性随着时间的推移而下降。
此外,有人可以帮助 解释如何根据 y_true
和 y_pred
计算指标得分吗? 我不太明白什么时候标签值用于 IoU 指标计算。
我当时也有类似的问题。我使用了 jaccard_distance_loss
和 dice_metric
。它们基于 IoU。我的任务是二元分割,所以我猜你可能需要修改代码以防你想将它用于多标签分类问题。
from keras import backend as K
def jaccard_distance_loss(y_true, y_pred, smooth=100):
"""
Jaccard = (|X & Y|)/ (|X|+ |Y| - |X & Y|)
= sum(|A*B|)/(sum(|A|)+sum(|B|)-sum(|A*B|))
The jaccard distance loss is usefull for unbalanced datasets. This has been
shifted so it converges on 0 and is smoothed to avoid exploding or disapearing
gradient.
Ref: https://en.wikipedia.org/wiki/Jaccard_index
@url: https://gist.github.com/wassname/f1452b748efcbeb4cb9b1d059dce6f96
@author: wassname
"""
intersection = K.sum(K.sum(K.abs(y_true * y_pred), axis=-1))
sum_ = K.sum(K.sum(K.abs(y_true) + K.abs(y_pred), axis=-1))
jac = (intersection + smooth) / (sum_ - intersection + smooth)
return (1 - jac) * smooth
def dice_metric(y_pred, y_true):
intersection = K.sum(K.sum(K.abs(y_true * y_pred), axis=-1))
union = K.sum(K.sum(K.abs(y_true) + K.abs(y_pred), axis=-1))
# if y_pred.sum() == 0 and y_pred.sum() == 0:
# return 1.0
return 2*intersection / union
# Example
size = 10
y_true = np.zeros(shape=(size,size))
y_true[3:6,3:6] = 1
y_pred = np.zeros(shape=(size,size))
y_pred[3:5,3:5] = 1
loss = jaccard_distance_loss(y_true,y_pred)
metric = dice_metric(y_pred,y_true)
print(f"loss: {loss}")
print(f"dice_metric: {metric}")
loss: 4.587155963302747
dice_metric: 0.6153846153846154