【问题标题】:How to calculate the mean IU score in image segmentation?如何计算图像分割中的平均 IU 分数?
【发布时间】:2015-07-27 12:50:05
【问题描述】:

如何计算this 论文中的 mean IU(mean Intersection over Union)分数?

朗、乔纳森、埃文·谢尔哈默和特雷弗·达雷尔。 “用于语义分割的全卷积网络。”

【问题讨论】:

标签: computer-vision image-segmentation evaluation-strategy


【解决方案1】:

对于每个班级联合交集 (IU) 得分为:

真阳性/(真阳性+假阳性+假阴性)

平均 IU 只是所有类别的平均值。


关于论文中的符号:

  • n_cl : 类数
  • t_i : i 类中的像素总数
  • n_ij :预测属于 j 类的 i 类的像素数。所以对于类i

    • n_ii : 正确分类的像素数(真阳性)
    • n_ij : 错误分类的像素数(误报)
    • n_ji : 错误未分类的像素数(假阴性)

您可以在 Pascak DevKit here 中找到 matlab 代码来直接计算它

【讨论】:

  • @stochastic_zeitgeist 检查this
  • 我认为这仅适用于矩形边界框。对于不规则的形状,我认为this 应该可以。
  • 如果我像true positive / (true positive + false positive + false negative) 一样为数据集中的每张图像计算 IOU,下一步该怎么做?我应该计算所有图像 IOU 的平均值吗?如果在某些图像上某些类没有呈现和预测,所以I = 0U = 0,那么在平均 IOU 时,我需要为每个类分别做“计数器”吗?
  • 您必须计算测试集中所有图像的 tp/(tp + fp + fn)。这意味着您对每个类别的测试集中的所有图像求和 tp、fp、fn,然后计算 IoU。对每个单独的图像 IoU 取平均值会导致错误的全局 IoU。
  • “取每个图像 IoU 的平均值” 我不是说这个。您计算每个类中所有像素的 IoU,然后取所有类的平均 IoU。
【解决方案2】:
 from sklearn.metrics import confusion_matrix  
 import numpy as np

 def compute_iou(y_pred, y_true):
     # ytrue, ypred is a flatten vector
     y_pred = y_pred.flatten()
     y_true = y_true.flatten()
     current = confusion_matrix(y_true, y_pred, labels=[0, 1])
     # compute mean iou
     intersection = np.diag(current)
     ground_truth_set = current.sum(axis=1)
     predicted_set = current.sum(axis=0)
     union = ground_truth_set + predicted_set - intersection
     IoU = intersection / union.astype(np.float32)
     return np.mean(IoU)

【讨论】:

  • 我必须在这里使用return np.nanmean,因为 0 可以在有效的混淆矩阵中(我们正确地从不尝试预测某些东西,留下 0 混淆)
【解决方案3】:

这应该会有所帮助

def computeIoU(y_pred_batch, y_true_batch):
    return np.mean(np.asarray([pixelAccuracy(y_pred_batch[i], y_true_batch[i]) for i in range(len(y_true_batch))])) 

def pixelAccuracy(y_pred, y_true):
    y_pred = np.argmax(np.reshape(y_pred,[N_CLASSES_PASCAL,img_rows,img_cols]),axis=0)
    y_true = np.argmax(np.reshape(y_true,[N_CLASSES_PASCAL,img_rows,img_cols]),axis=0)
    y_pred = y_pred * (y_true>0)

    return 1.0 * np.sum((y_pred==y_true)*(y_true>0)) /  np.sum(y_true>0)

【讨论】:

  • 输出 y_pred 的形状为 n_classes*h*w 我们希望将它们转换为单个图像,其中像素值等于该像素处的类,这就是我们在类中采用 arg max 的原因轴。
【解决方案4】:

jaccard_similarity_score (per How to find IoU from segmentation masks?) 可以用来获得与上面@Alex-zhai 的代码相同的结果:

import numpy as np
from sklearn.metrics import jaccard_score

y_true = np.array([[0, 1, 1],
                   [1, 1, 0]])
y_pred = np.array([[1, 1, 1],
                   [1, 0, 0]])

labels = [0, 1]
jaccards = []
for label in labels:
    jaccard = jaccard_score(y_pred.flatten(),y_true.flatten(), pos_label=label)
    jaccards.append(jaccard)
print(f'avg={np.mean(jaccards)}')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 2013-11-05
    相关资源
    最近更新 更多