假定一定有k+1类(包括k个目标类和1个背景类),表示本属于i类却预测为j类的像素点总数,具体地,
表示true postives,表示false negatives,表示false positives
参考的原文章的和弄反了
True Positive(TP):预测为正例,实际为正例
False Positive(FP):预测为正例,实际为负例
True Negative(TN):预测为负例,实际为负例
False Negative(FN):预测为负例,实际为正例
从这我们可以看出,TP和TN都是预测对了,FP和FN都是预测错了。
注:后面一个字母代表预测类别,前面一个代表是否预测对
1.像素准确率 Pixel Accuracy (PA)
最简单的评价指标,计算正确分类像素的数量与总数之间的比值
2.评价像素准确率 Mean Pixel Accuracy (MPA)
计算每一类分类正确的像素点数和该类的所有像素点数的比例然后求平均
3.平均交并比 Mean Intersection over Union (MIoU)
计算每一类的IoU然后求平均。一类的IoU计算方式如下,例如,表示true positives,即本属于1类且预测也为1类,表示本属于1类却预测为其他类的像素点数(注意,这里包含了),表示本属于其他类却预测为1类的像素点数(注意,这里也包含了),在分母处计算了两次所以要减去一个
4.频率加权交并比Frequency Weighted Intersection over Union (FWIoU)
根据每一类出现的频率对各个类的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()
下面的程序实现的混淆矩阵也是横着的是预测类别,竖着的是真实类别
程序实现
# !/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类的像素数量
"""
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类的像素数量与总数量比值
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)
# 下面的函数针对二分类
"""
预 测
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任何一个数值减小,F-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
https://www.jianshu.com/p/8d1dd2d37f87
简书markdown公式:
https://zhuanlan.zhihu.com/p/110756681
网友评论