評價指標(biāo)

假定一定有k+1類(包括k個目標(biāo)類和1個背景類),p_{ij}表示本屬于i類卻預(yù)測為j類的像素點總數(shù)俄认,具體地电媳,
p_{ii}表示true postives,p_{ij}表示false negatives锻全,p_{ji}表示false positives
參考的原文章的p_{ij}p_{ji}弄反了
True Positive(TP):預(yù)測為正例狂塘,實際為正例
False Positive(FP):預(yù)測為正例,實際為負(fù)例
True Negative(TN):預(yù)測為負(fù)例鳄厌,實際為負(fù)例
False Negative(FN):預(yù)測為負(fù)例荞胡,實際為正例
從這我們可以看出,TP和TN都是預(yù)測對了了嚎,F(xiàn)P和FN都是預(yù)測錯了泪漂。
注:后面一個字母代表預(yù)測類別,前面一個代表是否預(yù)測對

1.像素準(zhǔn)確率 Pixel Accuracy (PA)

最簡單的評價指標(biāo)歪泳,計算正確分類像素的數(shù)量與總數(shù)之間的比值
PA=\frac{\sum_{i=0}^{k} p_{i i}}{\sum_{i=0}^{k} \sum_{j=0}^{k} p_{i j}}

2.評價像素準(zhǔn)確率 Mean Pixel Accuracy (MPA)

計算每一類分類正確的像素點數(shù)和該類的所有像素點數(shù)的比例然后求平均
MPA=\frac{1}{k+1} \sum_{i=0}^{k} \frac{p_{i i}}{\sum_{j=0}^{k} p_{i j}}

3.平均交并比 Mean Intersection over Union (MIoU)

計算每一類的IoU然后求平均萝勤。一類的IoU計算方式如下,例如i=1呐伞,p_{11}表示true positives敌卓,即本屬于1類且預(yù)測也為1類,p_{1j}表示本屬于1類卻預(yù)測為其他類的像素點數(shù)(注意伶氢,這里包含了p_{11})趟径,p_{j1}表示本屬于其他類卻預(yù)測為1類的像素點數(shù)(注意瘪吏,這里也包含了p_{11}),在分母處p_{11}計算了兩次所以要減去一個p_{11}
MIoU=\frac{1}{k+1} \sum_{i=0}^{k} \frac{p_{i i}}{\sum_{j=0}^{k} p_{i j}+\sum_{j=0}^{k} p_{j i}-p_{i i}}

4.頻率加權(quán)交并比Frequency Weighted Intersection over Union (FWIoU)

根據(jù)每一類出現(xiàn)的頻率對各個類的IoU進行加權(quán)求和
FWIoU=\frac{1}{\sum_{i=0}^{k} \sum_{j=0}^{k} p_{i j}} \sum_{i=0}^{k} \frac{p_{i i} \sum_{j=0}^{k} p_{i j}}{\sum_{j=0}^{k} p_{i j}+\sum_{j=0}^{k} p_{j i}-p_{i i}}

混淆矩陣

二分類

維基百科混淆矩陣

混淆矩陣從定義來看舵抹,橫著的是真實類別肪虎,豎著的是預(yù)測類別
但是sklearn的混淆矩陣不是這樣,橫著的是預(yù)測類別惧蛹,豎著的是真實類別
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html

>>> from sklearn.metrics import confusion_matrix
>>> y_true = [2, 0, 2, 2, 0, 1]
>>> y_pred = [0, 0, 2, 2, 0, 2]
>>> confusion_matrix(y_true, y_pred)
array([[2, 0, 0],
       [0, 0, 1],
       [1, 0, 2]])
tn, fp, fn, tp = confusion_matrix([0, 1, 0, 1], [1, 1, 1, 0]).ravel()

下面的程序?qū)崿F(xiàn)的混淆矩陣也是橫著的是預(yù)測類別扇救,豎著的是真實類別

程序?qū)崿F(xiàn)

# !/usr/bin/python3
# -*-coding:utf-8-*-
# Author: blair liu
# CreatDate: 2021/4/22 20:59
# Description: 

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, self.num_class))  # n*n

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

    def Pixel_Accuracy_Class(self):
        """
        self.confusion_matrix.sum(axis=1)表示
        本來是第i類預(yù)測成其他類(包含第i類),也就是真實值中第i類的像素數(shù)量
        """
        Acc = np.diag(self.confusion_matrix) / self.confusion_matrix.sum(axis=1)
        Acc = np.nanmean(Acc)
        return Acc

    def Mean_Intersection_over_Union(self):
        """
        self.confusion_matrix.sum(axis=1)表示本來是第i類預(yù)測成其他類(包含第i類)
        self.confusion_matrix.sum(axis=0)表示本來是其他類(包含第i類)預(yù)測成第i類
        """
        # 每一類IoU
        IoU = 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(IoU)
        return MIoU

    def Frequency_Weighted_Intersection_over_Union(self):
        # 真實值中第i類的像素數(shù)量與總數(shù)量比值
        freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix)
        # 每一類IoU
        iou = 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] * iou[freq > 0]).sum()
        return FWIoU

    def Confusion_Matrix(self):
        return self.confusion_matrix

    def _generate_matrix(self, gt_image, pre_image):
        mask = (gt_image >= 0) & (gt_image < self.num_class)
        # print(gt_image.shape, pre_image.shape, mask.shape, gt_image[mask].shape)
        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)

    # 下面的函數(shù)針對二分類
    """ 
            預(yù)   測
            0    1
    真  0   TN   FP
    實  1   FN   TP
    """
    def Recall(self):
        """
        召回率
        預(yù)測正確的正例與所有真實正例的比值 TP/(TP + FN)
        """
        assert self.num_class == 2
        return self.confusion_matrix[1][1] / (self.confusion_matrix[1][1] + self.confusion_matrix[1][0])

    def Precision(self):
        """
        準(zhǔn)確率
        預(yù)測正確的正例與所有預(yù)測為正例的比值 TP/(TP + FP)
        """
        assert self.num_class == 2
        return self.confusion_matrix[1][1] / (self.confusion_matrix[1][1] + self.confusion_matrix[0][1])

    def F1(self):
        """
        F-score相當(dāng)于precision和recall的調(diào)和平均香嗓,用意是要參考兩個指標(biāo)迅腔。recall和precision任何一個數(shù)值減小,F(xiàn)-score都會減小靠娱,反之亦然
        """
        assert self.num_class == 2
        # return 2.0 * self.Recall() * self.Precision() / (self.Recall() + self.Precision())
        return 2.0 * self.confusion_matrix[1][1] / (
                    2.0 * self.confusion_matrix[1][1] + self.confusion_matrix[0][1] + self.confusion_matrix[1][0])


if __name__ == '__main__':
    gt = np.array([[0, 1],
                   [1, 0]])
    pred = np.array([[1, 1],
                     [1, 1]])
    evaluator = Evaluator(2)
    evaluator.add_batch(gt, pred)
    print(evaluator.Confusion_Matrix())
    # [[0. 2.]
    #  [0. 2.]]

參考:
https://zhuanlan.zhihu.com/p/61880018
https://en.wikipedia.org/wiki/Confusion_matrix
https://github.com/jfzhang95/pytorch-deeplab-xception/blob/master/utils/metrics.py
https://arxiv.org/abs/1704.06857
http://www.reibang.com/p/8d1dd2d37f87

簡書markdown公式:
https://zhuanlan.zhihu.com/p/110756681

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沧烈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子像云,更是在濱河造成了極大的恐慌锌雀,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迅诬,死亡現(xiàn)場離奇詭異腋逆,居然都是意外死亡,警方通過查閱死者的電腦和手機侈贷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門惩歉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俏蛮,你說我怎么就攤上這事撑蚌。” “怎么了搏屑?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵争涌,是天一觀的道長。 經(jīng)常有香客問我辣恋,道長第煮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任抑党,我火速辦了婚禮,結(jié)果婚禮上撵摆,老公的妹妹穿的比我還像新娘底靠。我一直安慰自己,他們只是感情好特铝,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布暑中。 她就那樣靜靜地躺著壹瘟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳄逾。 梳的紋絲不亂的頭發(fā)上稻轨,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音雕凹,去河邊找鬼殴俱。 笑死,一個胖子當(dāng)著我的面吹牛枚抵,可吹牛的內(nèi)容都是我干的线欲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼汽摹,長吁一口氣:“原來是場噩夢啊……” “哼李丰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逼泣,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤趴泌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拉庶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗜憔,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年砍的,在試婚紗的時候發(fā)現(xiàn)自己被綠了痹筛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡廓鞠,死狀恐怖帚稠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情床佳,我是刑警寧澤滋早,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站砌们,受9級特大地震影響杆麸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜浪感,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一昔头、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧影兽,春花似錦揭斧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盅视。三九已至,卻和暖如春旦万,著一層夾襖步出監(jiān)牢的瞬間闹击,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工成艘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赏半,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓狰腌,卻偏偏與公主長得像除破,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子琼腔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容