语义分割之评价指标

语义分割之评价指标

摘录自arxiv.org/abs/1704.0685

本文将介绍语义分割的三大评价指标,分别是执行时间、内存占用以及准确度,其中本文着重介绍准确度并给出相应的python实现

1、执行时间(execution time)

2、内存占用(memory footprint)

3、准确度(accuracy)

假定一定有k+1类(包括k个目标类和1个背景类), p_{ij} 表示本属于i类却预测为j类的像素点总数,具体地, p_{ii} 表示true postives, p_{ij} 表示false positives, p_{ji} 表示false negatives

  • Pixel Accuracy (PA)

分类正确的像素点数和所有的像素点数的比例

PA = \frac{\sum_{i=0}^{k}{p_{ii}}}{\sum_{i=0}^{k}{\sum_{j=0}^{k}{p_{ij}}}}

  • Mean Pixel Accuracy (MPA)

计算每一类分类正确的像素点数和该类的所有像素点数的比例然后求平均

MPA = \frac{1}{k+1}\sum_{i=0}^{k}{\frac{p_{ii}}{\sum_{j=0}^{k}{p_{ij}}}}

  • Mean Intersection over Union (MIoU)

计算每一类的IoU然后求平均。一类的IoU计算方式如下,例如i=1, p_{11} 表示true positives,即本属于1类且预测也为1类, \sum_{j=0}^{k}{p_{1j}}表示本属于1类却预测为其他类的像素点数(注意,这里包含了 p_{11} ), \sum_{j=0}^{k}{p_{j1}} 表示本属于其他类却预测为1类的像素点数(注意,这里也包含了 p_{11} ),在分母处 p_{11} 计算了两次所以要减去一个p_{11}

MIoU = \frac{1}{k+1}\sum_{i=0}^{k}{\frac{p_{ii}}{\sum_{j=0}^{k}{p_{ij}} + \sum_{j=0}^{k}{p_{ji}} - p_{ii}}}

  • Frequency Weighted Intersection over Union (FWIoU)

可以理解为根据每一类出现的频率对各个类的IoU进行加权求和

FWIoU = \frac{1}{\sum_{i=0}^{k}{\sum_{j=0}^{k}{p_{ij}}}}\sum_{i=0}^{k}{\frac{p_{ii}\sum_{j=0}^{k}{p_{ij}}}{\sum_{j=0}^{k}{p_{ij}} + \sum_{j=0}^{k}{p_{ji}} - p_{ii}}}


评价指标python实现

(摘录自github.com/jfzhang95/py

这里用到了混淆矩阵(confusion matrix en.wikipedia.org/wiki/C

import numpy as np


class Evaluator(object):
    def __init__(self, num_class):
        self.num_class = num_class
        self.confusion_matrix = np.zeros((self.num_class,)*2)

    def Pixel_Accuracy(self):
        Acc = np.diag(self.confusion_matrix).sum() / self.confusion_matrix.sum()
        return Acc

    def Pixel_Accuracy_Class(self):
        Acc = np.diag(self.confusion_matrix) / self.confusion_matrix.sum(axis=1)
        Acc = np.nanmean(Acc)
        return Acc

    def Mean_Intersection_over_Union(self):
        MIoU = np.diag(self.confusion_matrix) / (
                    np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
                    np.diag(self.confusion_matrix))
        MIoU = np.nanmean(MIoU)
        return MIoU

    def Frequency_Weighted_Intersection_over_Union(self):
        freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix)
        iu = np.diag(self.confusion_matrix) / (
                    np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
                    np.diag(self.confusion_matrix))

        FWIoU = (freq[freq > 0] * iu[freq > 0]).sum()
        return FWIoU

    def _generate_matrix(self, gt_image, pre_image):
        mask = (gt_image >= 0) & (gt_image < self.num_class)
        label = self.num_class * gt_image[mask].astype('int') + pre_image[mask]
        count = np.bincount(label, minlength=self.num_class**2)
        confusion_matrix = count.reshape(self.num_class, self.num_class)
        return confusion_matrix

    def add_batch(self, gt_image, pre_image):
        assert gt_image.shape == pre_image.shape
        self.confusion_matrix += self._generate_matrix(gt_image, pre_image)

    def reset(self):
        self.confusion_matrix = np.zeros((self.num_class,) * 2)

编辑于 04-27

文章被以下专栏收录