Precision,Recall,F1score,Accuracy等的理解加代码

    科技2025-05-04  10

    图像分类、目标检测、语义分割、实例分割和全景分割的区别::: https://blog.csdn.net/kk123k/article/details/86584216?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-2-86584216.nonecase&utm_term=%E8%AF%AD%E4%B9%89%E5%88%86%E5%89%B2%E7%AE%97%E6%B3%95%E5%A6%82%E4%BD%95%E9%A2%84%E6%B5%8B%E6%8E%A9%E7%A0%81%E4%BD%8D%E7%BD%AE&spm=1000.2123.3001.4430

    语义分割评价指标:: https://blog.csdn.net/qq_40234695/article/details/88633094?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-3-88633094.nonecase&utm_term=%E8%AF%AD%E4%B9%89%E5%88%86%E5%89%B2%E7%AE%97%E6%B3%95%E5%A6%82%E4%BD%95%E9%A2%84%E6%B5%8B%E6%8E%A9%E7%A0%81%E4%BD%8D%E7%BD%AE&spm=1000.2123.3001.4430 当然看了一些语义分割的指标,也需要实现一下代码: 本文记录了语义分割准确性评价指标的总结以及代码实现

    对于像素级别的分类,最常用的评价指标是Pixel Accuracy(像素准确率)和Mean Inetersection over Union(平均交并比),二者的计算都是建立在混淆矩阵的基础上的。因此首先来介绍一下混淆矩阵,之后分别介绍PA,MPA,MIoU,FWIoU,最后附上代码实现。 首先假定数据集中有n+1类(0~n+1),0通常表示背景。使用Pii表示原本为i类同时预测为i类,即真正(TP)和真负(TN), Pij表示原本为i类被预测为j类,即假正(FP)和假负(FN),如果第i类为正类,i!=j时,那么Pii表示TP,Pjj表示TN,Pij表示FP,Pji表示FN。

    像素准确率(PA)

    像素准确率是所有分类正确的像素数占像素总数的比例。公式化如下:

    利用混淆矩阵计算则为(对角线元素之和除以矩阵所有元素之和) 平均像素准确率(MPA)

    平均像素准确率是分别计算每个类别分类正确的像素数占所有预测为该类别像素数的比例,即精确率,然后累加求平均。公式化如下:

    利用混淆矩阵计算公式为(每一类的精确率Pi都等于对角线上的TP除以对应列的像素数)

    平均交并比(mloU)

    平均交并比是对每一类预测的结果和真实值的交集与并集的比值求和平均的结果。公式化如下

    IoU利用混淆矩阵计算:

    解释如下:     如图所示,仅仅针对某一类来说,红色部分代表真实值,真实值有两部分组成TP,FN;黄色部分代表预测值,预测值有两部分组成TP,FP;白色部分代表TN(真负);

    所以他们的交集就是TP+FP+FN,并集为TP

    频权交并比(FWloU)

    频权交并比是根据每一类出现的频率设置权重,权重乘以每一类的IoU并进行求和。公式化如下:

    利用混淆矩阵计算:每个类别的真实数目为TP+FN,总数为TP+FP+TN+FN,其中每一类的权重和其IoU的乘积计算公式如下,在将所有类别的求和即可

    代码实现:

    #https://blog.csdn.net/kkkkk0826/article/details/102962168 代码连接地址 import numpy as np from PIL import Image import cv2 __all__ = ['SegmentationMetric'] """ confusionMetric P\L P N P TP FP N FN TN """ class SegmentationMetric(object): def __init__(self, numClass): self.numClass = numClass self.confusionMatrix = np.zeros((self.numClass,) * 2) def pixelAccuracy(self): # return all class overall pixel accuracy # acc = (TP + TN) / (TP + TN + FP + TN) acc = np.diag(self.confusionMatrix).sum() / self.confusionMatrix.sum() return acc def classPixelAccuracy(self): # return each category pixel accuracy(A more accurate way to call it precision) # acc = (TP) / TP + FP classAcc = np.diag(self.confusionMatrix) / self.confusionMatrix.sum(axis=1) return classAcc def meanPixelAccuracy(self): classAcc = self.classPixelAccuracy() meanAcc = np.nanmean(classAcc) return meanAcc def meanIntersectionOverUnion(self): # Intersection = TP Union = TP + FP + FN # IoU = TP / (TP + FP + FN) intersection = np.diag(self.confusionMatrix) union = np.sum(self.confusionMatrix, axis=1) + np.sum(self.confusionMatrix, axis=0) - np.diag( self.confusionMatrix) IoU = intersection / union mIoU = np.nanmean(IoU) return mIoU def genConfusionMatrix(self, imgPredict, imgLabel): # remove classes from unlabeled pixels in gt image and predict mask = (imgLabel >= 0) & (imgLabel < self.numClass) label = self.numClass * imgLabel[mask] + imgPredict[mask] count = np.bincount(label, minlength=self.numClass ** 2) confusionMatrix = count.reshape(self.numClass, self.numClass) return confusionMatrix def Frequency_Weighted_Intersection_over_Union(self): # FWIOU = [(TP+FN)/(TP+FP+TN+FN)] *[TP / (TP + FP + FN)] freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix) iu = 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] * iu[freq > 0]).sum() return FWIoU def addBatch(self, imgPredict, imgLabel): assert imgPredict.shape == imgLabel.shape self.confusionMatrix += self.genConfusionMatrix(imgPredict, imgLabel) def reset(self): self.confusionMatrix = np.zeros((self.numClass, self.numClass)) if __name__ == '__main__': ppath="D:/1/fcn_segment/test/precdict/10-p.png" # 用PIL中的Image.open打开图像 mpath= "D:/1/fcn_segment/test/mask1/10-m.png" imgPredict =cv2.imread(ppath) # 转化成numpy数组 imgLabel = cv2.imread(mpath) print("imgPredict:", imgPredict.shape) print("imgPredict:", type(imgPredict)) print("imgLabel:", imgLabel.shape) print("imgLabel:", type(imgLabel)) metric = SegmentationMetric(256) metric.addBatch(imgPredict, imgLabel) acc = metric.pixelAccuracy() #pa 像素准确率 mIoU = metric.meanIntersectionOverUnion() #平均像素准确率 print(acc, mIoU)

    连接:https://blog.csdn.net/sinat_29047129/article/details/103642140?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-4-103642140.nonecase&utm_term=resnet34%E5%88%86%E7%B1%BB%E5%87%86%E7%A1%AE%E7%8E%87&spm=1000.2123.3001.4430 是对上面的一个小总结。这个代码说明一下遇到的坑,首先可以用两张图像去对比,然后你这个图像不一定保证是像素是0-255之间的对吧,这样你可以输入

    if __name__ == '__main__': ppath="D:/1/fcn_segment/test/predict1/2-p.png" # 用PIL中的Image.open打开图像 mpath= "D:/1/fcn_segment/test/mask1/2-m.png" #D:/1/fcn_segment/test/predict1/5-p.png imgPredict =cv2.imread(ppath) # 转化成numpy数组 imgLabel = cv2.imread(mpath) print("imgPredict:", imgPredict.shape) print("imgPredict:", type(imgPredict)) print("imgLabel:", imgLabel.shape) print("imgLabel:", type(imgLabel)) metric = SegmentationMetric(256) #3表示有3个分类,有几个分类就填几 metric.addBatch(imgPredict, imgLabel) pa = metric.pixelAccuracy() #pa 像素准确率 cpa = metric.classPixelAccuracy() mpa = metric.meanPixelAccuracy() mIoU = metric.meanIntersectionOverUnion() #平均像素准确率 print('pa is : %f' % pa) print('cpa is :') # 列表 print(cpa) print('mpa is : %f' % mpa) print('mIoU is : %f' % mIoU)

    这个256,必须是256,代表0-255这么多像素之间,你的两个图片去对比值一样不一样。通过看博客,你会发现别人也有这个问题,具体解答我也再博客留言地方回答了咋解决这个问题,其实也不用解决。。。就是 方法不一样而已,结果是正确的,cpa矩阵输出是256个值 其中其他无用的值是nan !! 你也可以,把输入的两个图统一规定只有二值化,0和1,这样图看起来就是黑色的。。。以为人眼看不见1这个像素值。。。这样你可以把 metric = SegmentationMetric(2) 这样就对了 结果还是一样 cpa显示的矩阵只有两个值了。

    链接:https://blog.csdn.net/zsc201825/article/details/93487506?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight 举例子的形式讲述这些指标值,其中acc和precises并不一样。细看

    链接:https://blog.csdn.net/weixin_42990464/article/details/105339266?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight 给出了iou miou f1 kappa的代码实现。

    连接:https://blog.csdn.net/zichen_ziqi/article/details/80408465 这个讲的很好,给了代码,matlab和py都可以跑通,建议看这个连接。其中有roc曲线和结果。 可以换自己的数据集。

    Processed: 0.017, SQL: 8