图像分割任务中的评价指标简析

2024-04-21 04:18

本文主要是介绍图像分割任务中的评价指标简析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在图像分割领域中,我们需要使用特定的指标来评估实验效果。
在这里插入图片描述

上图源自《Fully Convolutional Networks for Semantic Segmentation》

整个评价体系中,被广泛应用的几个评价指标有:

  • Precision
  • Recall
  • Accuracy
  • IoU
  • F1-Score
  • Mean Accuracy / Frequency Weighted Accuracy / Mean IoU / Frequency Weighted IoU等衍生指标

在此对上述用到的指标做出简要分析。这一切还需要从分类任务中的TP/FP/FN/TN的概念说起。
在这里插入图片描述

评估指标

TP/FP/FN/TN

在二分类场景(记为类别0和类别1)中,有四种分类结果,即:

  • 本该是0被分为0
  • 本该是0被分为1
  • 本该是1被分为0
  • 本该是1被分为1

若以类别1为正例(positive),类别0为负例(negative)。则分类结果可以如下图所示:
在这里插入图片描述
则上述四种分类结果分别可以概括为:

  • 本该是0被分为0 (True negative,TN,真阴)
  • 本该是0被分为1 (False positive,FP,假阳)
  • 本该是1被分为0 (False negative,FN,假阴)
  • 本该是1被分为1 (True positive,TP,真阳)

上图中,selected elements表示在本次分类任务中被分类为positives的元素,包括TPs和NPs。relevant elements表示在本次分类任务中本应是positives的元素,包括TPs和FNs。

注:TPs是所有TP的意思,类同。

Precision和Recall

指标Precision和Recall是基于对正例分类正确率的评估而建立的。

其中Precision是要评估在所有被分类为positives的元素中实际分类正确的概率,即:

P r e c i s i o n = T P s T P s + F P s Precision = \frac {TPs}{TPs+FPs} Precision=TPs+FPsTPs
在这里插入图片描述
而Recall则是要评估正例分类正确占本应是positives的所有元素的概率,即:

R e c a l l = T P s T P s + F N s Recall = \frac {TPs}{TPs+FNs} Recall=TPs+FNsTPs
在这里插入图片描述
简而言之,Precision和Recall的分子都是TPs,都是要评估正例分类正确的水平。

不同的是分母,Precision是以被分类的所有样本为分母,分母可随每次采样元素变化而变化。Precision的意义在于衡量是否有误判,希望误判越少越好。

而Recall则是以原本所有的positives元素为分母,分母不随采样元素变化而变化。Recall的意义在于衡量是否有遗漏,希望遗漏越少越好。

Accuracy

说到Accuracy,很容易和Precision搞混,实际上二者不一样。Accuracy实际上衡量范围更广,相比于Precision只将TP作为考虑范围,Accuracy则是将TP和TN都纳入评估范围。

A c c u r a c y = T P s + T N s T P s + F P s + T N s + F N s = T P s + T N s T o t a l s \begin{aligned}Accuracy &= \frac {TPs+TNs}{TPs+FPs+TNs+FNs}\\ &=\frac {TPs+TNs}{Totals}\end{aligned} Accuracy=TPs+FPs+TNs+FNsTPs+TNs=TotalsTPs+TNs

IoU

IoU和Precision/Recall比较相近,同样是对正例分类正确的水平进行衡量,不同的是IoU的分母是Precision和Recall分母的并集。正如其全名Intersection over Union(交并比),即selected elements和relevant elements的交集比上两者的并集,实际上就是:

I o U = T P s T P s + F P s + F N s IoU = \frac {TPs}{TPs+FPs+FNs} IoU=TPs+FPs+FNsTPs

在这里插入图片描述

F1-Score

F1-Score是Precision和Recall的调和平均数。
在这里插入图片描述
在上面说到Precision和Recall,提到Precision是以被分类的所有样本为分母,Recall则是以原本所有的positives元素为分母。二者之间并没有建立直接联系,如果一个分类器,Precision很高但是Recall很低,或者Recall很高但是Precision很低,这两种分类器都是不好的,都是我们不希望的。所以我们采用F1-Score来建立Precision和Recall的联系。

在数学中,我们知道调和平均数是永远小于等于算术均值平均数的,当用于求两个数的平均数时,如果直接用算术平均作为结果,那么两数之间的差异将被大的值削平,而调和平均数则不会极大削平这种大的差异,得到的结果更倾向于小的值。

例如,1和9的平均,算术平均数为5,而调和平均数约为2。

采用F1-Score能够更好的同时衡量Precision和Recall,也就是希望在遗漏少的前提下误判也少,这样得到的F1-Score才会高。

Mean / Frequency Weighted 衍生

用于多分类任务中,其中Mean IoU表示计算每一类的IoU后求均值,Frequency Weighted IoU表示根据每一类出现的频率对各个类的IoU进行加权求和。Mean Accuracy和Frequency Weighted Accuracy类同。

Python实现

对于上述评估指标,一般由混淆矩阵计算后处理得到。
在这里插入图片描述
对于猫狗二分类问题,分类结果如下:
在这里插入图片描述
若以猫为正类,则混淆矩阵如下:
在这里插入图片描述

计算混淆矩阵

import numpy as npclass Metric(object):def __init__(self, n_classes):self.n_classes = n_classesself.confusion_matrix = np.zeros((n_classes, n_classes))def _fast_hist(self, label_true, label_pred, n_class):mask = (label_true >= 0) & (label_true < n_class)hist = np.bincount(n_class * label_true[mask].astype(int) + label_pred[mask], minlength=n_class ** 2).reshape(n_class, n_class)return histdef update(self, label_trues, label_preds):for lt, lp in zip(label_trues, label_preds):self.confusion_matrix += self._fast_hist(lt.flatten(), lp.flatten(), self.n_classes)

根据混淆矩阵计算评价指标

# For multi-classes
def get_scores(self):"""Returns accuracy score evaluation result.- Overall accuracy- Mean accuracy- Frequency Weighted acc- Mean IoU- Overall F1"""hist = self.confusion_matrixFP = hist.sum(axis=0) - np.diag(hist)FN = hist.sum(axis=1) - np.diag(hist)TP = np.diag(hist)precision = TP / (TP+FP)recall = TP / (TP+FN)f1 = (2 * (precision*recall) / (precision + recall)).mean()acc = np.diag(hist).sum() / hist.sum()acc_cls = np.diag(hist) / hist.sum(axis=1)acc_cls = np.nanmean(acc_cls)iou = np.diag(hist) / (hist.sum(axis=1) +hist.sum(axis=0) - np.diag(hist))mean_iou = np.nanmean(iou)freq = hist.sum(axis=1) / hist.sum()fwavacc = (freq[freq > 0] * iou[freq > 0]).sum()cls_iou = dict(zip(range(self.n_classes), iou))return ({"Overall Acc: \t": acc,"Mean Acc : \t": acc_cls,"FreqW Acc : \t": fwavacc,"Mean IoU : \t": mean_iou,"Overall F1: \t": f1},cls_iou,)

完整代码

import numpy as npclass Metric(object):def __init__(self, n_classes):self.n_classes = n_classesself.confusion_matrix = np.zeros((n_classes, n_classes))def _fast_hist(self, label_true, label_pred, n_class):mask = (label_true >= 0) & (label_true < n_class)hist = np.bincount(n_class * label_true[mask].astype(int) + label_pred[mask], minlength=n_class ** 2).reshape(n_class, n_class)return histdef update(self, label_trues, label_preds):for lt, lp in zip(label_trues, label_preds):self.confusion_matrix += self._fast_hist(lt.flatten(), lp.flatten(), self.n_classes)# For multi-classesdef get_scores(self):"""Returns accuracy score evaluation result.- Overall accuracy- Mean accuracy- Frequency Weighted acc- Mean IoU- Overall F1"""hist = self.confusion_matrixFP = hist.sum(axis=0) - np.diag(hist)FN = hist.sum(axis=1) - np.diag(hist)TP = np.diag(hist)precision = TP / (TP+FP)recall = TP / (TP+FN)f1 = (2 * (precision*recall) / (precision + recall)).mean()acc = np.diag(hist).sum() / hist.sum()acc_cls = np.diag(hist) / hist.sum(axis=1)acc_cls = np.nanmean(acc_cls)iou = np.diag(hist) / (hist.sum(axis=1) +hist.sum(axis=0) - np.diag(hist))mean_iou = np.nanmean(iou)freq = hist.sum(axis=1) / hist.sum()fwavacc = (freq[freq > 0] * iou[freq > 0]).sum()cls_iou = dict(zip(range(self.n_classes), iou))return ({"Overall Acc: \t": acc,"Mean Acc : \t": acc_cls,"FreqW Acc : \t": fwavacc,"Mean IoU : \t": mean_iou,"Overall F1: \t": f1},cls_iou,)def reset(self):self.confusion_matrix = np.zeros((self.n_classes, self.n_classes))

在这里插入图片描述

参考资料

[1] Fully Convolutional Networks for Semantic Segmentation
[2] F-score - Wikipedia
[3] 语义分割之评价指标 - 知乎
[4] 机器学习中的F1度量,为什么定义为precision和recall的调和平均,而不是算术平均? - 知乎
[5] 评估指标中IoU/precision/recall/tp/fp/fn/tn的个人理解_TracelessLe的专栏-CSDN博客
[6] Confusion matrix - Wikipedia
[7] FaceParsing.PyTorch/metrics.py at master · TracelessLe/FaceParsing.PyTorch
[8] python实现混淆矩阵 - 知乎
[9] 混淆矩阵 - 维基百科,自由的百科全书

这篇关于图像分割任务中的评价指标简析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922144

相关文章

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编

python+OpenCV反投影图像的实现示例详解

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前言二、什么是反投影图像三、反投影图像的概念四、反向投影的工作原理一、利用反向投影backproj

Django之定时任务django-crontab的实现

《Django之定时任务django-crontab的实现》Django可以使用第三方库如django-crontab来实现定时任务的调度,本文主要介绍了Django之定时任务django-cront... 目录crontab安装django-crontab注册应用定时时间格式定时时间示例设置定时任务@符号

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB