图像分割评价指标:Dice和MIoU

news2024/11/6 7:27:35

目录

  • Dice
    • 理论
    • 代码
  • MIou
    • 理论
      • 查准率 precison
      • 查全率 recall
      • MIoU 平均交并比
    • 代码
      • 高效的矩阵运算
      • 低效的好理解的
      • 计算混淆矩阵
  • Dice和MIoU两者的关系
  • 参考链接

Dice

理论

Dice用来衡量预测结果pred和标签label的相似度,公式如下图所示,即两个集合的交集/并集。
在这里插入图片描述

注意:对于多分类的分割任务,网络的输出结果是多通道的,使用Dice计算准确度需要将标签转换为多通道的one_hot形式。

代码

def dice_acc(predict, label):
    """
        计算多个batch的dicc
        @param predict: 模型预测值,Shape:[B, C, W, H]
        @param label: one_hot形式的标签,Shape:[B, C, W, H]
    """
    batch_num, class_num = predict.shape[0: 2]
    
    assert predict.size() == label.size(), "the size of predict and target must be equal."
    
    # 计算交集
    intersection = (predict * label).reshape((batch_num, class_num, -1)).sum(dim=2)

    # 计算并集
    union = (predict + label).reshape((batch_num, class_num, -1)).sum(dim=2)
    
    dice = (2. * intersection + 1) / (union + 1)

    dice = dice.mean()

    # loss = 1 - dice

    return dice
  • 如果需要计算dice loss,只需要 1- dice_acc即可。
  • 可以借助torch.nn.functional.one_hot()函数将标签转化为one_hot形式。
  • 以上代码传入的predictlabel都是tensor,需要调用dice.item()只返回数值。

MIou

理论

为了计算MIoU,我们需要先引入混淆矩阵的概念。所谓混淆矩阵,就是真实结果和预测结果所组成的矩阵,将整个结果集划分为TPTNFPFN四类。
在这里插入图片描述

  • TP:True Positive 真正的正类,即label是正标签,predict也是正标签。
  • FN:False Negative 假的负类,即label是正标签,predict却预测是负标签。
  • FP:False Positive 假的正类,即label是负标签,predict却预测是正标签。
  • TN:True Negative 真正的负类,即label是负标签,predict也是负标签。

有了混淆矩阵后,我们可以在此基础上计算各种评价指标:

查准率 precison

在这里插入图片描述

查全率 recall

在这里插入图片描述

MIoU 平均交并比

在这里插入图片描述
上面的公式对应到混淆矩阵A上为 A(i, i) / A(i, : ) + A(:, j) - A(i, j),即对角线元素比上(对角线元素所在行和列的元素和 - 对角线元素)
在这里插入图片描述

注意:为了计算MIoU,我们需要把多通道的预测结果通过torch.argmax()函数转化为单通道的预测类别,然后和单通道的label计算交并比。

代码

为了计算MIoU,这里提供两种方式,一种是比较高效的矩阵运算,另一种是常规的好理解的但效率不高的方式,两者都可以用。

高效的矩阵运算

def miou(predict, label, class_num=3):
    """
        计算多个batch的moiu
        @param predict: 模型预测值,Shape:[B, W, H]
        @param label: 标签,Shape:[B, W, H]
    """
    batch = label.shape[0]

    predict, label = predict.flatten(), label.flatten()

    # 忽略背景的话就 >0
    k = (predict >= 0) & (predict < class_num)

    # 计算混淆矩阵
    hist = torch.bincount(class_num * predict[k].type(torch.int32) + label[k], minlength=batch * (class_num ** 2)).reshape(batch, class_num, class_num)

    # 将多个batch合并为一个,如果传入的参数没有batch这个维度,可以注释掉这句话
    hist = hist.sum(0)

    # 计算各个类的iou
    miou = torch.diag(hist) / torch.maximum((hist.sum(1) + hist.sum(0) - torch.diag(hist)), torch.tensor(1))

    # 计算平均值miou
    return miou.mean()

低效的好理解的

def IOU(pred, target, n_classes = 3 ):
    """
        计算miou
        @param predict: 模型预测值,Shape:[W, H]
        @param label: 标签,Shape:[W, H]
    """
    ious = []
    # 从1开始,即忽略背景
    # 依次计算每个类
    for cls in range(1, n_classes):
        pred_inds = pred == cls
        target_inds = target == cls

        # 计算两个集合在该类上的交集
        intersection = (pred_inds[target_inds]).sum()

        # 计算并集
        union = pred_inds.sum() + target_inds.sum() - intersection

        if union == 0:
            ious.append(float('nan')) # If there is no ground truth,do not include in evaluation
        else:
            ious.append(float(intersection.item()) / float(max(union.item(), 1)))

    # 计算多类的平均值 
    return torch.mean(torch.tensor(ious))

注意,这种的传入的参数是二维的,不能有batch维度。

计算混淆矩阵

这里提供一个计算混淆矩阵的快速实现,但很低效,仅供看看,实际还是要用上面torch.bincount计算混淆矩阵快。

# TP predict 和 label 同时为1
TP = ((pred1 == 1) & (label == 1)).cpu().sum()
# TN    predict 和 label 同时为0
TN = ((pred1 == 0) & (label == 0)).cpu().sum()
# FN    predict 0 label 1
FN = ((pred1 == 0) & (label == 1)).cpu().sum()
# FP    predict 1 label 0
FP = ((pred1 == 1) & (label == 0)).cpu().sum()

Dice和MIoU两者的关系

对于二分类的任务来说,二者思想都是交集/并集,但dice并不是在分母上减去交集,而是将交集在分子上算了两次

对于多分类来说,Dice是将预测结果转为了多通道,而MIoU只在一个通道上计算。

参考链接

https://www.jianshu.com/p/42939bf83b8a
https://blog.csdn.net/Pierce_KK/article/details/96505691

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

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

相关文章

Java-多线程-增强篇-锁强化第3篇

Java集合框架中的锁 今天我们继续来学习锁 字符串操作中的锁 String是线程安全的&#xff0c;因为使用final修饰Stringbuilder 是线程不安全的&#xff0c;其方法没有使用synchronized修饰StringBuffer 是线程安全的&#xff0c;其方法使用synchronized修饰 List集合中的锁 …

【人工智能 AI】可以从 RPA 中受益的 10 个行业 10 Industries That Can Benefit From RPA

目录 RPA技术介绍 Which industries can use robotic process automation?哪些行业可以使用机器人过程自动化? Robotic process automation in the retail industry零售业中的机器人过程自动化 Robotic process automation in the construction industry建筑行业的机器人…

RebbitMQ 消息队列(高级应用)

RabbitMQ 高级特性 消息可靠性投递&#xff0c;consumer ACK&#xff0c;消费端限流&#xff0c;TTL&#xff0c;死信队列&#xff0c;延迟队列&#xff0c;日志与监控&#xff0c;消息可靠性与追踪&#xff0c;管理 RabbitMQ 应用问题 消息可靠性保障&#xff0c;消息幂等性…

JavaScript 基础【快速掌握知识点】

目录 为什么要学JavaScript? 什么是JavaScript 特点&#xff1a; 组成&#xff1a; JavaScript的基本结构 基本结构 内部引用 外部引用 console对象进行输出 JavaScript核心语法 1、变量声明 2、数据类型 3、运算符 4、条件语句 5、循环语句 6、数组 7…

【shell】for while 循环的例子,快速了解

for 循环读一个文件的每一行 for i in cat temp.list;do echo $i;done for ip in $(cat ip.list);do ping -c 2 $ip;done循环打印数字 for a in {1…5};do echo $a;done for a in {1…5…2};do echo $a;done #等差 for a in $(seq 1 5);do echo $a;done for a in $(seq 1 2 5)…

内网穿透常用方法系列总结

前言在内网渗透时&#xff0c;一个WebShell或CobaltStrike、Metasploit上线等&#xff0c;只是开端&#xff0c;更多是要内网横向移动&#xff0c;扩大战果&#xff0c;打到核心区域。但后渗透的前提是需要搭建一条通向内网的“专属通道”&#xff0c;才能进一步攻击。可实战中…

【华为OD机试模拟题】用 C++ 实现 - 找出重复代码(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

C语言static关键字

目录static修饰局部变量static修饰全局变量static修饰函数static是C语言的关键字&#xff0c;它有静态的意思static的三种用法&#xff1a;修饰局部变量修饰全局变量修饰函数 static修饰局部变量 我们先看一个程序&#xff1a; void print() {int a 0;a;printf("%d\n&…

【华为OD机试模拟题】用 C++ 实现 - 数组组成的最小数字(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

更改tomcat访问端口()

1Centos7开启端口 查看防火墙状态命令&#xff1a; systemctl status firewalld 启动防火墙命令&#xff1a; systemctl start firewalld 关闭防火墙命令&#xff1a; systemctl stop firewalld 开放端口命令&#xff1a; firewall-cmd --zonepublic --add-port5011/tcp --pe…

23、高自由度下的E类波形理论计算(附Matlab代码)

23、高自由度下的E类波形理论计算&#xff08;附Matlab代码&#xff09; 0、代码 任意占空比、电压导数条件下的E类波形与阻抗条件计算Matlab 注意修改路径&#xff0c;我这边是&#xff1a;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#…

自适应池化、最大值池化和均值池化效率的比较分析

1 问题我们在深度学习的过程中&#xff0c;我们学到了自适应池化、最大值池化和均值池化。那么&#xff0c;我们想要探究一下自适应池化、最大值池化和均值池化效率&#xff0c;哪一个更高&#xff1f;2 方法在之前的学习中&#xff0c;我们学到了自适应池化、最大值池化和均值…

c++11 标准模板(STL)(std::unordered_set)(八)

定义于头文件 <unordered_set> template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templ…

【Rust 日报】2023-2-24 Dioxus 0.3 发布,巨大的更新

ascii-d - 画ASCII示意图的工具Rust写的画ASCII示意图的工具。支持各大平台。程序员的最爱啊。https://github.com/huytd/ascii-d/raw/master/_meta/toolbar-final.gifDioxus 0.3 发布&#xff0c;巨大的更新Dioxus 是新出的与 Yew 类似的 Rust Web 前端框架&#xff08;为什么…

【sciter】sciter数据可视化

一、柱状图 <div class="bar-chart item"></div> <!-- bar-chart --> <script type

【华为OD机试模拟题】用 C++ 实现 - 找单词(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

【华为OD机试模拟题】用 C++ 实现 - RSA 加密算法(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

猜数字游戏——C++

我们在有了一定的C基础了以后&#xff0c;简单的实现一个案例&#xff08;其实只要会while循环结构就行了&#xff09;&#xff0c;我们本章内容会实现猜数字游戏&#xff0c;大家有什么语法疑问可以看看我写的&#xff1a;C快速入门_染柒_GRQ的博客-CSDN博客&#xff0c;该博客…

【算法】最短路算法

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…

金三银四吃透这份微服务笔记,面试保准涨10K+

很多人对于微服务技术也都有着一些疑虑&#xff0c;比如&#xff1a; 微服务这技术虽然面试的时候总有人提&#xff0c;但作为一个开发&#xff0c;是不是和我关系不大&#xff1f;那不都是架构师的事吗&#xff1f;微服务不都是大厂在玩吗&#xff1f;我们这个业务体量用得着…