假定一定有k+1類(包括k個目標類和1個背景類),表示本屬于i類卻預測為j類的像素點總數(shù),具體地,
表示true postives,
表示false negatives,
表示false positives
參考的原文章的和
弄反了
True Positive(TP):預測為正例,實際為正例
False Positive(FP):預測為正例,實際為負例
True Negative(TN):預測為負例,實際為負例
False Negative(FN):預測為負例,實際為正例
從這我們可以看出,TP和TN都是預測對了,F(xiàn)P和FN都是預測錯了。
注:后面一個字母代表預測類別,前面一個代表是否預測對
1.像素準確率 Pixel Accuracy (PA)
最簡單的評價指標,計算正確分類像素的數(shù)量與總數(shù)之間的比值
2.評價像素準確率 Mean Pixel Accuracy (MPA)
計算每一類分類正確的像素點數(shù)和該類的所有像素點數(shù)的比例然后求平均
3.平均交并比 Mean Intersection over Union (MIoU)
計算每一類的IoU然后求平均。一類的IoU計算方式如下,例如,
表示true positives,即本屬于1類且預測也為1類,
表示本屬于1類卻預測為其他類的像素點數(shù)(注意,這里包含了
),
表示本屬于其他類卻預測為1類的像素點數(shù)(注意,這里也包含了
),在分母處
計算了兩次所以要減去一個
4.頻率加權交并比Frequency Weighted Intersection over Union (FWIoU)
根據(jù)每一類出現(xiàn)的頻率對各個類的IoU進行加權求和
混淆矩陣
二分類

混淆矩陣從定義來看,橫著的是真實類別,豎著的是預測類別
但是sklearn的混淆矩陣不是這樣,橫著的是預測類別,豎著的是真實類別
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()
下面的程序實現(xiàn)的混淆矩陣也是橫著的是預測類別,豎著的是真實類別
程序實現(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類預測成其他類(包含第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類預測成其他類(包含第i類)
self.confusion_matrix.sum(axis=0)表示本來是其他類(包含第i類)預測成第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ù)針對二分類
"""
預 測
0 1
真 0 TN FP
實 1 FN TP
"""
def Recall(self):
"""
召回率
預測正確的正例與所有真實正例的比值 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):
"""
準確率
預測正確的正例與所有預測為正例的比值 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相當于precision和recall的調和平均,用意是要參考兩個指標。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.itdecent.cn/p/8d1dd2d37f87
簡書markdown公式:
https://zhuanlan.zhihu.com/p/110756681