Semantic Segmentation | 评价指标代码解析

news2024/12/23 16:00:24

如有错误,恳请指出。


文章目录

  • 1. 定义解析
  • 2. 代码解析

之前有记录过关于图像语义分割的相关评价指标与经典网络,在看PointNet++的语义分割训练脚本的时候,图像的语义分割和点云的语义分割其实本质上是一致的。所以这里想记录一下语义分割的评价指标代码。

1. 定义解析

对于语义分割的准确率评价方法来说,经过资料查询有4种方式:

  • 1. pixel accuracy(PA)

定义:分类正确的像素点与所有的像素点数的比例

  • 2. mean pixel accuracy(MPA)

定义:计算每一类分类正确的像素点和该类的所有的像素点的比例然后求平均

  • 3. mean intersection over union(MIOU)

定义:计算每一类的iou然后求平均(真是集合与预测集合的交并比)

  • 4. frequencecy weighted intersection over union (FWIOU)

定义:根据每一类出现的频率对每一类的iou进行加权求和

直观理解:
在这里插入图片描述

M I O U = 1 k + 1 ∑ k + 1 k T P F N + F P + T P MIOU = \frac{1}{k+1} \sum^k_{k+1}\frac{TP}{FN+FP+TP} MIOU=k+11k+1kFN+FP+TPTP
TP(真正): 预测正确, 预测结果是正类, 真实是正类
FP(假正): 预测错误, 预测结果是正类, 真实是负类
FN(假负): 预测错误, 预测结果是负类, 真实是正类
TN(真负): 预测正确, 预测结果是负类, 真实是负类 #跟类别1无关,所以不包含在并集中


2. 代码解析

  • 先求出混淆矩阵

在这里插入图片描述

  • 再根据混淆矩阵进行各指标计算
import numpy as np
import cv2
"""
confusionMetric,真真假假
P\L     P    N
 
P      TP    FP
 
N      FN    TN
 
"""


class Evaluator(object):
    def __init__(self, num_class):
        self.num_class = num_class
        self.confusion_matrix = np.zeros((self.num_class,)*2)
	
	# PA指标计算
    def Pixel_Accuracy(self):
        # acc = (TP + TN) / (TP + TN + FP + TN)
        Acc = np.diag(self.confusion_matrix).sum() / \	# 预测正确总个数
            self.confusion_matrix.sum()					# 全部预测总个数
        return Acc
	
	# MPA指标计算
    def Pixel_Accuracy_Class(self):
        # acc = (TP) / TP + FP
        Acc = np.diag(self.confusion_matrix) / \	# 预测该类别的正确个数
            self.confusion_matrix.sum(axis=1)		# 预测该类别的总个数
        Acc_class = np.nanmean(Acc)
        return Acc_class
	
	# MIOU指标计算
    def Mean_Intersection_over_Union(self):
    	# MIOU = TP / [FN + FP + TP] 
        MIoU = 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(MIoU)
        return MIoU
	
	# FWIOU指标计算
    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) / (				# 每个类别的iou
            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()	# 根据频率对iou进行加权
        return FWIoU
	
	# 混淆矩阵生成
	# 参数说明:以图片来说明
	# 		gt_image: target  图片的真实标签            [batch_size, 512, 512]
    # 		per_image: preb   网络生成的图片的预测标签   [batch_size, 512, 512]
    # 如果是点云的话,每个点会预测一个值,所以维度应该如下所示
    # 		gt_point: target  点云的真实标签			   [batch_size, n_points]
    # 		pre_point: pred   网络生成的点云的预测标签   [batch_size, n_points]
    def _generate_matrix(self, gt_image, pre_image):
    	# 对于gt值需要在类别范围内
        mask = (gt_image >= 0) & (gt_image < self.num_class)
        # 核心代码:混淆矩阵是num_class*num_class大小,利用num_class * gt_image是进行预测值的偏移,
      	# 如果预测值与真实值一直,那么相加得到的值会在混淆矩阵的对角线上,表示预测正确(TP),否则会偏移到其他位置则是预测错误
        label = self.num_class * gt_image[mask].astype('int') + pre_image[mask]
        # 利用bincount统计label中每个位置出现的次数
        count = np.bincount(label, minlength=self.num_class**2)
        # reshape构建真正的混淆矩阵,行代表真实类别,列代表预测的类别
        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)

测试例子,帮助理解(其中a是预测值, b是ground truth):

>>> b
array([[0, 0, 0, 2],
       [0, 0, 2, 1],
       [1, 1, 1, 0],
       [1, 0, 1, 2]])
>>> a
array([[0, 0, 0, 2],
       [0, 0, 2, 1],
       [1, 1, 1, 2],
       [1, 0, 1, 2]])
>>> label = 3 * b[mask] + a[mask]
>>> count = numpy.bincount(label)
>>> count
array([6, 0, 1, 0, 6, 0, 0, 0, 3])
>>> count = count.reshape(3, 3)
>>> numpy.sum(count, axis=1)
array([7, 6, 3])
>>> numpy.sum(count, axis=0)
array([6, 6, 4])
>>> numpy.sum(count, axis=1) + numpy.sum(count, axis=0)
array([13, 12,  7])
>>> numpy.sum(count, axis=1) + numpy.sum(count, axis=0) - numpy.diag(count)
array([7, 6, 4])

参考资料:

1. 语义分割代码阅读—评价指标mIoU的计算

2. 语义分割评价指标,附代码可直接运行

3. Semantic Segmentation | 评价指标与经典网络(FCN,DeepLab系列,UNet,LR-ASPP)

4. MIoU 源码解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/144639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL下载及使用navicat连接mysql数据库(含下载地址、超具体细节、推荐数据库教程)

目录下载地址安装流程第一步&#xff1a;开始安装第二步&#xff1a;类型选择第三步&#xff1a;developer default第四步&#xff1a;execute第五步&#xff1a;服务器配置窗口第六步&#xff1a;网络类型配置窗口第七步&#xff1a;第八步&#xff1a;服务器密码设置窗口第九…

Vue全家桶 Pinia状态管理

Pinia状态管理1. Pinia和Vuex的对比2. 创建Pinia的Store3. Store 简介与使用4. Pinia核心概念State5. Pinia核心概念Getters6. Pinia核心概念ActionsPinia开始于大概2019年&#xff0c;最初是作为一个实验为Vue重新设计状态管理&#xff0c;让它用起来像组合式API&#xff0c;从…

[C语言]初步的来了解一下指针(多图详解)

目录 1.指针是什么 2.指针类型 2.1指针类型的意义(-整数) 2.2指针的解引用 3.野指针 3.1野指针出现的情况 3.2 如何规避野指针 4.指针运算 4.1指针-整数 4.2指针-(减)指针 5.二级指针 1.指针是什么 指针是内存中最小的单元编号&#xff0c;也就是地址。指针还可以是一种…

录屏软件电脑版免费哪个好?4款免费屏幕录制软件下载

在电脑上经常能使用的录屏功能&#xff1a;录制软件的操作过程、精彩的游戏瞬间、经典的影视故事、网络教学等。许多人都在问&#xff0c;录屏软件电脑版哪个好&#xff1f;Windows平台上有很多录屏软件&#xff0c;如果对录屏需求不高的朋友&#xff0c;可以通过内置的视频软件…

08线性回归+基础优化算法

P2基础优化算法 1.最常见的优化算法——梯度下降&#xff0c;用在模型没有显示解的情况下&#xff08;线性回归有显示解&#xff0c;但是现实中很少有这样理想的情况&#xff09; 2.梯度下降的实现方法&#xff1a;沿着反梯度更新方向参数求解 解释&#xff1a; 超参数&#x…

HTTP_day03

当键入网址后&#xff0c;到网页显示&#xff0c;其间发生了什么&#xff08;下&#xff09; 掘金地址 键入 localhost ,通过 Wireshark 抓包分析&#xff0c;抓包结果如下图所示 抓包结果 我们知道 HTTP 协议是运行在 TCP/IP 基础 之上的。 浏览器 通过 HTTP 接收和发送数据…

怎么才能写出好的代码

前言这是一篇如何写好代码的水文&#xff0c;因为最近输出了不少干货&#xff0c;但是大家点赞太少&#xff0c;我越来越没有激情了&#xff0c;那就放放水啦。所以如果大家觉得我的分享对你有用&#xff0c;动动发财小手&#xff0c;赞起来吧&#xff01;虽然是一篇水文&#…

谷粒学苑项目-第一章数据库设计与项目结构-1.1

一、数据库设计 1、数据库 guli2、数据表 CREATE TABLE edu_teacher (id char(19) NOT NULL COMMENT 讲师ID,name varchar(20) NOT NULL COMMENT 讲师姓名,intro varchar(500) NOT NULL DEFAULT COMMENT 讲师简介,career varchar(500) DEFAULT NULL COMMENT 讲师资历,一句话说…

Java--经典九道练习题

文章内容 一、用户登录 二、遍历字符串 三、统计字符个数 四、拼接字符串 五、字符串反转 六、金额转换&#xff08;较难&#xff09; 七、手机号屏蔽 八、身份证号码信息查看 九、游戏骂人敏感词替换 一、用户登录 一直正确的用户名和密码&#xff0c;请用程序实现模…

获取当前进程的启动程序

本文迁移自本人网易博客&#xff0c;写于2012年3月23日&#xff0c;获取当前进程的启动程序 - lysygyy的日志 - 网易博客 (163.com)1.获取当前进程的启动程序CString sFile;GetModuleFileName(NULL, sFile.GetBuffer(), 255);2.获取文件类型3.Autocad文档交互时&#xff0c;使用…

Camera | 1.Camera基础知识

一口君最近在玩瑞芯微的板子&#xff0c;之前写了几篇基于瑞芯微的文章&#xff0c;大家可以学习一下。 《瑞芯微rk356x板子快速上手》 《Linux驱动|rtc-hym8563移植笔记》 《Linux驱动 | Linux内核 RTC时间架构》 《瑞芯微 | 摄像头ov13850移植笔记》 《rk3568 | 瑞芯微平…

图的生成树与生成森林

文章目录连通图与连通分量强连通图与强连通分量图的连通性判断生成树深度优先生成树邻接表邻接矩阵广度优先生成树邻接表邻接矩阵生成森林获取边弧的权值源代码连通图与连通分量 在无向图中, 若从顶点v到顶点w有路径存在, 则称v和w是连通的. 若图G中任意两个顶点都是连通的, 则…

动态规划--矩阵链相乘问题

明确原始问题A[1:n]&#xff1a;计算矩阵链 所需的最小乘法次数。 &#xff08;1&#xff09;是否满足最优子结构&#xff0c;问题的解是否包含子问题的优化解&#xff1f; 若计算A[1:n]的优化顺序在k处断开矩阵链&#xff0c;即A[1:n]A[1:k]A[k1:n],则在A[1:n]的优化顺序中&a…

ReFactor GNN:从消息传递角度重新审视FMs

分享嘉宾 | 陈艺虹 文稿整理 | William Knowledge Graph Completion(KGC) 知识图谱一般会有多个节点&#xff0c;包括性别、国家等各种各样的节点(也可理解为实体)&#xff0c;节点之间会有不同的关系&#xff0c;可以通过其他的一些节点预测出当前节点的其他信息。恢复这些信…

2023/1/6 Vue学习笔记-1

尝试 Vue.js 最简单的方法是使用 Hello World 例子。你可以在浏览器新标签页中打开它&#xff0c;跟着例子学习一些基础用法。或者你也可以创建一个 .html 文件&#xff0c;然后通过如下方式引入 Vue&#xff1a; <!-- 开发环境版本&#xff0c;包含了有帮助的命令行警告 -…

设计模式——建造者模式

文章目录模式理解基本概念使用示例建造者模式延展模式理解 建造者模式&#xff08;Builder Pattern&#xff09;&#xff1a;建造者模式是一种对象创建型模式。将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。这句话理解起来太抽象了&…

B. Dima and a Bad XOR(构造 + 异或性质)

Problem - 1151B - Codeforces 来自Kremland的学生Dima有一个大小为nm的非负整数矩阵a。 他希望从矩阵的每一行中选择一个整数&#xff0c;以便所选整数的按位互斥或严格大于0。帮助他! 形式上&#xff0c;他想选择一个整数序列c1,c2&#xff0c;…&#xff0c;cn(1≤cj≤m)&am…

Integer包装类详解(java)

文章目录&#x1f4d6;前言&#xff1a;&#x1f380;包装类概念&#xff1a;&#x1f380;包装类分类&#xff1a;&#x1f380;包装类integer介绍&#xff1a;&#x1f387;自动装箱和自动拆箱问题【⚠注意面试常考点】&#x1f387;Integer常用方法&#xff1a;&#x1f4d6…

2023真无线蓝牙耳机推荐:高性价比真无线蓝牙耳机各价位蓝牙耳机推荐!

2023年了&#xff0c;蓝牙耳机赛道依然很卷&#xff01;性价比是反映物品可买程度的一种量化的计量方式。现如今&#xff0c;蓝牙耳机市场上主打高性价比的不在少数&#xff0c;而高性价比的东西往往更能精准抓住用户“痛点”&#xff0c;从而受到了不少用户的欢迎。 既然高性…

面试20分钟就完事了,问的实在是太......

干了两年外包&#xff0c;本来想出来正儿八经找个互联网公司上班&#xff0c;没想到算法死在另一家厂子。 自从加入这家外包公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到11月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资…