图像分割中的混淆矩阵和利用混淆矩阵计算指标

news2024/11/19 14:48:24

目录

1. 介绍

2. 创建混淆矩阵

2.1 update 方法

2.2 compute 方法

2.3 str 方法

3. 测试

4. 完整代码


1. 介绍

语义分割中,性能指标可以利用混淆矩阵进行计算

这里实现的方法和图像分类中不一样,需要的可以参考:混淆矩阵Confusion Matrix

 

这里采用的测试数据如下:

 

2. 创建混淆矩阵

混淆矩阵的实现如下

init 是初始化混淆矩阵

update 更新混淆矩阵的数值

reset 将矩阵的值清零

compute 根据update 算出来的混淆矩阵计算相应的性能指标

str 是返回的字符串,就是实例化混淆矩阵后,print的值

 

这里讲解混淆矩阵类的测试数据都是上面的:

2.1 update 方法

如下:

a传入的是真实的label,b传入的是网络预测的值,注:这里的预测值也是和label一样的整型数组

首先通过init初始化方法将混淆矩阵的大小赋值给n(分类类别的个数+1 背景),然后创建混淆矩阵mat,先初始化为0

接下来,k在真正标签a中找到对应的索引,

这里目的是为了将不感兴趣的区域设为False,其余的具体分割标签应该为1,2,3这样的排序方式。因为通常0为背景,255为不感兴趣的区域。

例如,当分割类别为2(1,2),那么加上背景传入的n就是3(0,1,2),同时不感兴趣的区域设置为255(0,1,2,255)。那么在k在真实标签a(0,1,2,255)中的索引,就会将a>=0 & a<n ,也就是0,1,2 的区域设置为True,从而满足了分割要求且拍出来255不感兴趣的

所以,dataset加载数据中,要将前景从1,2,3这样排序

 

然后,通过下面的操作就能将横坐标为true,纵坐标为pred的混淆矩阵update

中间的inds大概是将a和b变为一维向量,那么n*a就会将一维向量变为n个为一组的样子,然后在里面进行计算,最后reshape成n*n的矩阵就行了。具体的可以自己调试一下

 例如,true = 1,pred = 0 的个数是一个,同样在混淆矩阵的值也是1(第0行,第1列)

 

2.2 compute 方法

compute 是利用update产生的混淆矩阵,计算分割任务中的性能指标,关于分割任务的性能指标,可以查看:关于语义分割常见的评价指标

混淆矩阵:横坐标为true,纵坐标为pred

像素准确率 = 混淆矩阵对角线 / 混淆矩阵的sum

acc 这里是指各个类别的召回率 = 各个对角线的值 / 真实值(矩阵的行为ture,所以对行求和)

recall 召回率就是在...召回的个数,...就是label,召回的个数就是预测正确的个数。所以召回率就是在label中,预测正确个数的占比

iou 就是各个对角线的值 / (对应行 + 对应列 - 重复的对角线的值)

2.3 str 方法

python类中str方法,是返回实例化类的print的值

 

因此混淆矩阵类中的str方法返回的是compute计算出的性能指标。

因为这里的str方法自动调用了compute,而compute是根据update计算的。所以调用str之前,一定要先调用update方法,更新混淆矩阵的值

这里的recall和iou都是针对不同类别的,所以返回是个列表

 

3. 测试

测试的代码如下:

 测试的样本为:

这里手动计算分割的参数,验证混淆矩阵

首先是像素准确率:4 / 9 = 0.4444

然后是各个类别的召回率:这里是三个类别0 1 2 

然后是iou:

对于0:1 / 3 =0.3333

对于1:1 / 6 =0.1667

对于2:2 / 5 =0.4

最后mean iou就是iou的均值:(0.3333+0.1667+0.4) / 3 = 0.9 / 3 = 0.3

4. 完整代码

混淆矩阵的代码:

import torch


# 混淆矩阵
class ConfusionMatrix(object):
    def __init__(self, num_classes):
        self.num_classes = num_classes      # 分类个数(加了背景之后的)
        self.mat = None         # 混淆矩阵

    def update(self, a, b):      # 计算混淆矩阵,a = Ture,b = Predict
        n = self.num_classes
        if self.mat is None:         # 创建混淆矩阵
            self.mat = torch.zeros((n, n), dtype=torch.int64, device=a.device)
        with torch.no_grad():
            k = (a >= 0) & (a < n)
            inds = n * a[k].to(torch.int64) + b[k]      # 统计像素真实类别a[k]被预测成类别b[k]的个数(这里的做法很巧妙)
            self.mat += torch.bincount(inds, minlength=n**2).reshape(n, n)

    def reset(self):
        if self.mat is not None:
            self.mat.zero_()

    def compute(self):      # 计算分割任务的性能指标
        h = self.mat.float()

        acc_global = torch.diag(h).sum() / h.sum()     # 计算全局预测准确率(混淆矩阵的对角线为预测正确的个数)
        acc = torch.diag(h) / h.sum(1)                 # 计算每个类别的 recall
        iou = torch.diag(h) / (h.sum(1) + h.sum(0) - torch.diag(h))     # 计算iou
        return acc_global, acc, iou

    def __str__(self):
        acc_global, acc, iou = self.compute()
        return (
            'global correct: {:.4f}\n'
            'recall: {}\n'
            'IoU: {}\n'
            'mean IoU: {:.4f}').format(
            acc_global.item() ,
            ['{:.4f}'.format(i) for i in acc.tolist()],
            ['{:.4f}'.format(i) for i in iou.tolist()],
            iou.mean().item())

测试的代码:

confmat = ConfusionMatrix(num_classes=3)    # 实例化混淆矩阵

ture = torch.LongTensor([[1,2,1],[0,2,2],[0,1,1]])
pred = torch.LongTensor([[1,2,0],[1,2,1],[0,2,2]])

confmat.update(ture, pred)  # update 混淆矩阵的值
print(confmat)
'''
global correct: 0.4444
recall: ['0.5000', '0.2500', '0.6667']
IoU: ['0.3333', '0.1667', '0.4000']
mean IoU: 0.3000
'''

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

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

相关文章

大数据技术——spark集群搭建

目录 spark概述 spark集群搭建 1.Spark安装 2.环境变量配置 3.Spark集群配置 4.启动Spark集群 存在问题及解决方案 请参考以下文章 spark概述 Spark是一个开源的大数据处理框架&#xff0c;它可以在分布式计算集群上进行高效的数据处理和分析。Spark的特点是速度快、易…

多路I/O转接 poll(了解)

poll() 的机制与 select() 类似&#xff0c;与 select() 在本质上没有多大差别&#xff0c;管理多个描述符也是进行轮询&#xff0c;根据描述符的状态进行处理&#xff0c;但是 poll() 没有最大文件描述符数量的限制&#xff08;但是数量过大后性能也是会下降&#xff09;。 p…

Java 进阶(8) 线程常用方法

常用方法 方法名 说明 public static void sleep(long millis) 当前线程主动休眠 millis 毫秒。 public static void yield() 当前线程主动放弃时间⽚&#xff0c;回到就绪状态&#xff0c;竞争下⼀次时间⽚。 public final void join() 允许其他线程加⼊到当前线程中。…

什么是缓存穿透、缓存雪崩、缓存击穿

缓存穿透 缓存穿透 &#xff1a;缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库&#xff0c;失去了缓存保护后端存储的意义。 解决方案 缓存空值 如果访问数据库后还未命中&#xff0c;则把一…

JVM OOM问题排查与解决思路

OOM原因 1. 堆溢出 报错信息&#xff1a; java.lang.OutOfMemoryError: Java heap space 代码中可能存在大对象分配&#xff0c;无法获得足够的内存分配 可能发生内存泄露&#xff0c;导致内存被无效占用以至于耗尽 2. 永久代/元空间溢出 报错信息&#xff1a; java.lang.O…

Python黑马程序员(Spark实战)笔记

1、基础准备 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspark # 导包 from pyspark import SparkConf,SparkContext #创建SparkConf类对象 confSparkConf().setMaster("local[*]").setAppName("test_spark_app") #基于SparkXConf类对象创…

(十一)排序算法-选择排序

1 基本介绍 选择排序也属于内部排序法&#xff0c;是从欲排序的数据中&#xff0c;按指定的规则选出某一元素&#xff0c;再依规定交换位置后达到排序的目的。 动画展示&#xff1a; 选择排序思想&#xff1a; 选择排序&#xff08;select sorting&#xff09;也是一种简单的…

【刷题篇】栈和队列

目录 一.前言&#x1f308; 二.有效的括号✨ a.题目 b.题解分析 c.AC代码 三. 用队列实现栈&#x1f4cf; a.题目 b.题解分析&#xff08;辅助队列法&#xff09; c.AC代码&#xff08;辅助队列法&#xff09; d.题解分析&#xff08;就地存储法&#xff09; c.AC代…

全面带你了解AIGC的风口

前言 一、AIGC的介绍 二、AIGC 的几个主要作用 三、实现AIGC过程的步骤 四、科技新赛道AIGC开始火了 五、AIGC对世界产生广泛的影响 六、AIGC技术的主要风口 &#x1f618;一、AIGC的介绍 AIGC (AI Generated Content) 是指通过人工智能技术生成的各种类型的内容&#xff0c;…

SpringBoot学习3

一、JSR303数据验证 使用Validated进行数据验证&#xff0c;如果数据异常则会统一抛出异常&#xff0c;方便异常中心统一处理。 空检查 Null 对象为null NotNull 对象不能为 null&#xff0c;但可以是 空字符串(无法检验长度为0的字符串) NotBlank 检查约束字符串是不是为nul…

20230403在WIN10下通过ffmpeg调用NVIDIA的硬件加速wmv视频转码为MP4格式

20230403在WIN10下通过ffmpeg调用NVIDIA的硬件加速wmv视频转码为MP4格式 2023/4/3 15:50 最近向学习日语&#xff0c;找到日语发音的视频中&#xff0c;大多数是MP4格式&#xff0c;少量是WMV格式&#xff0c;PR2023貌似不能识别WMV格式。 于是&#xff1a;万能的ffmpeg上场了&…

使用GPT-4生成QT代码

一、概述最近ChatGPT火爆起来了&#xff0c;ChatGPT是一种基于GPT的自然语言处理模型&#xff0c;可以用于生成自然语言文本&#xff0c;例如对话、文章等。最近又发现了一个优秀且免费的代码生成工具Cursor &#xff0c;Cursor集成了 GPT-4 &#xff0c;可以帮助你快速编写、编…

动态规划:状态机DP和买卖股票问题【零神基础精讲】

买卖股票的最佳时机&#xff1a;无限次/冷冻期/k次【基础算法精讲 21】 来自0x3f&#xff1a;https://www.bilibili.com/video/BV1ho4y1W7QK/ 介绍了【买卖股票系列问题】与【状态机 DP】&#xff0c;包括【至多/恰好/至少】的讲解。 文章目录买卖股票问题和状态机DP(无限次)[1…

【CocosCreator入门】CocosCreator组件 | DragonBones(骨骼动画)组件

Cocos Creator 是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中DragonBones&#xff0c;它可以帮助您创建出色的2D骨骼动画。在本文中&#xff0c;我们将探讨CocosCreator引擎的DragonBones组件&#xff0c;以及如何使用它来创建精美的动画。 目录 …

VisualGC插件使用

下载安装VisualVM 下载地址&#xff1a;Visual VM mac系统选择macOS Application Bundle&#xff0c;下载完成后&#xff0c;双击dmg包安装即可&#xff0c;之后双击启动。 安装Visual GC 插件 点击菜单栏Tools&#xff0c;选择Pulgins&#xff0c;在第二个选项中找到Visua…

【CSS】更改用户界面样式 ③ ( 取消文本域拖拽 | 代码示例 )

文章目录一、取消文本域拖拽二、文本域拖拽示例三、取消文本域拖拽示例一、取消文本域拖拽 textarea 文本域 在 默认状态下是可以进行拖拽的 , 在网页布局中 , 一般不会允许这种情况发生 , 任意拖拽文本域会影响网页的整体布局 ; 设置文本域不可拖拽样式 : resize: none;文本…

windows编程(4) - GDI绘图基础

基础概念 GDI&#xff1a;Graphic Device Interface 图形设备接口。GUI&#xff1a;Graphic User Interface 图形用户接口。HDC&#xff1a;Handle of Device Context&#xff1a; 图形设备上下文句柄。 字符界面的基本单位是字符。 图形界面的基本单位是像素。 像素&#…

从数据展示中汉字缺失了解字符编码知识

有人在使用皕杰报表时遇到如下问题&#xff1a; 有些汉字变成了“&#xff1f;”&#xff0c;这是为什么呢&#xff1f;实际上就是你用的字符集里没有这个汉字导致的&#xff0c;要想搞懂这个问题&#xff0c;还得从字符、字符集、字符编码说起。 所谓字符&#xff0c;就是各…

定时任务练习----Linux 定时发送邮件 ( QQ 邮箱 为例)

邮件设置 &#xff1a; 在 QQ 邮箱的最上面 &#xff0c;点击设置。 在账户 这一栏&#xff0c;往下面走 找POP3 开头的栏目 在 POP3/SMTP 服务这一行&#xff0c;点击开启 &#xff08; 本身是 关闭状态 &#xff09; 关于 POP3 和 SMTP 服务需要做以说明 ; >>> 我…

技术管理笔记1

看点杂篇&#xff0c;整理下笔记&#xff1a; 目录&#xff1a; 1技术的本质 2 技术团队管理的本质 3 技术管理者的能力要求 4 技术管理者风格类型 5 实战案例分析&#xff1a; 一技术的本质 技术存在感低&#xff0c;缺乏话语权&#xff0c;以业务导向为主。 二 技术团…