假定一定有k+1類(包括k個目標(biāo)類和1個背景類),表示本屬于i類卻預(yù)測為j類的像素點總數(shù)俄认,具體地电媳,
表示true postives,
表示false negatives锻全,
表示false positives
參考的原文章的和
弄反了
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ù)之間的比值
2.評價像素準(zhǔn)確率 Mean Pixel Accuracy (MPA)
計算每一類分類正確的像素點數(shù)和該類的所有像素點數(shù)的比例然后求平均
3.平均交并比 Mean Intersection over Union (MIoU)
計算每一類的IoU然后求平均萝勤。一類的IoU計算方式如下,例如呐伞,
表示true positives敌卓,即本屬于1類且預(yù)測也為1類,
表示本屬于1類卻預(yù)測為其他類的像素點數(shù)(注意伶氢,這里包含了
)趟径,
表示本屬于其他類卻預(yù)測為1類的像素點數(shù)(注意瘪吏,這里也包含了
),在分母處
計算了兩次所以要減去一個
4.頻率加權(quán)交并比Frequency Weighted Intersection over Union (FWIoU)
根據(jù)每一類出現(xiàn)的頻率對各個類的IoU進行加權(quán)求和
混淆矩陣
二分類
混淆矩陣從定義來看舵抹,橫著的是真實類別肪虎,豎著的是預(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