1.背景介绍
在训练的模型的时候,需要评价模型的好坏,就涉及到混淆矩阵、准确率、查准率、查全率、DSC、IoU、敏感度的计算。
2、混淆矩阵的概念
所谓的混淆矩阵如下表所示:
TP:真正类,真的正例被预测为正例
FN:假负类,样本为正例,被预测为负类
FP:假正类 ,原本实际为负,但是被预测为正例
TN:真负类,真的负样本被预测为负类。
从混淆矩阵当中,可以得到更高级的分类指标:Accuracy(准确率),Precision(查准率),Recall(查全率),Specificity(特异性),Sensitivity(灵敏度)。
3. 常用的分类指标
3.1 Accuracy(准确率)
不管是哪个类别,只要预测正确,其数量都放在分子上,而分母是全部数据量。常用于表示模型的精度,当数据类别不平衡时,不能用于模型的评价。
3.2 Precision(查准率)
即所有预测为正的样本中,预测正确的样本的所占的比重。
3.3 Recall(查全率)
真实的为正的样本,被正确检测出来的比重。
3.4 Specificity(特异性)
特异性指标,也称 负正类率(False Positive Rate, FPR),计算的是模型错识别为正类的负类样本占所有负类样本的比例,一般越低越好。
3.5 DSC(Dice coefficient)
Dice系数,是一种相似性度量,度量二进制图像分割的准确性。
如图所示红色的框的区域时Groudtruth,而蓝色的框为预测值Prediction。
3.6 IoU(交并比)
3.7 Sensitivity(灵敏度)
反应的时预测正确的区域在Groundtruth中所占的比重。
4. 计算程序
为了更好的理解混淆矩阵,画了以下示意图,展示TP、FP、FN、TN的位置,在一个100×100的区域中,有一个50×50的红色预测区域和黑色框的groundtruth区域。接下来计算各项评价指标。
ConfusionMatrix 这个类可以直接计算出混淆矩阵
4.1 首先绘制出上图所示的图像,并填充颜色
import torch
import torch.nn as nn
from torchmetrics import ConfusionMatrix
import cv2 as cv
import numpy as np
# pre = torch.tensor([[1,0],[1,1]])
# gt = torch.tensor([[0,0],[1,1]])
# 定义一个函数,填充绘制的轮廓
def fill_img(img):
contours, hierarchy = cv.findContours(img, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
area = []
for k in range(len(contours)):
area.append(cv.contourArea(contours[k]))
# 轮廓索引
max_idx = np.argsort(np.array(area))
# 按轮廓索引填充颜色
for idx in max_idx:
# 填充轮廓
img = cv.drawContours(img, contours, idx, 255, cv.FILLED)
return img
# 创建两幅图像
image1 = np.zeros((100, 100, 1), dtype=np.uint8)
cv.rectangle(image1, (0,0), (49,49), 255, 1)
image2 = np.zeros((100, 100, 1), dtype=np.uint8)
cv.rectangle(image2, (40,40), (89,89), 255, 1)
#得到两幅图像,
gt = fill_img(image1)
pre = fill_img(image2)
gt = torch.from_numpy(gt)
pre = torch.from_numpy(pre)
gt =gt/255
pre =pre/255
4.2 计算各类评价指标
#计算各类评价指标
def calulate_metrics(gt,pre):
# 初始化混淆矩阵
conf_matrix = ConfusionMatrix(task='binary', threshold=0.5, num_classes=2)
# 更新混淆矩阵,对于二分类任务
conf_matrix.update(gt, pre)
'''
这里要注意各个元素代表的含义,获得混淆矩阵:
m00=True negatives;
m01= False positives;
m10=False negatives;
m11=True positives
'''
matrix = conf_matrix.compute().numpy()
# print("Confusion Matrix:")
# print(matrix)
#准确率ACC=(TP+TN)/(TP+TN+FP+FN)
ACC=(matrix[0,0]+matrix[1,1])/np.sum(matrix)
print("ACC:{}".format(ACC))
#精确率PPV=(TP)/(TP+FP)
PPV=matrix[1,1]/(matrix[0,1]+matrix[1,1])
print("PPV:{}".format(PPV))
#灵敏度/召回率:Recall= TP/(TP+FN)
Recall= matrix[1,1]/(matrix[1,1]+matrix[1,0])
print("Recall:{}".format(Recall))
#特异度TNR=TN/(TN+FP)
TNR = matrix[0,0]/(matrix[0,0]+matrix[0,1])
print("TNR:{}".format(TNR))
return ACC, PPV, Recall, TNR
if __name__ == '__main__':
ACC, PPV, Recall, TNR = calulate_metrics(gt,pre)
4.3 运行结果
可见运行结果是正确的。
参考文献: