目标检测评估指标mAP:从Precision,Recall,PR曲线到AP

news2025/2/25 20:55:40

1. TP, FP, FN, TN

True Positive

满足以下三个条件被看做是TP

        1. 置信度大于阈值(类别有阈值,IoU判断这个bouding box是否合适也有阈值)

        2. 预测类型与标签类型相匹配(类别预测对了)

        3. 预测的Bouding Box和Ground Truth的IoU大于阈值(框 打对了)。 当存在多个满足条件的预选框,则选择置信度最大的作为TP,其余的作为FP

False Positive

       1. 预测的 类别  和 真实的标签类型不匹配(分类错误)

        2. 预测的Bounding box和Ground Truth的IoU小于阈值(框  打的不是那么好, 定位错误)

False Negative

        分类争取,定位正确,但是被检测成了负样本

True Negative

        负样本被检测出的数量,太多了,绝大多数的框都是这个类型。后面计算precision和recall的时候用不到,所以这个东西也就不统计数量了。

2. Precision和Recall

Precision = TP/(TP+FP) = TP/(所有被我判定为正例的个数)

Recall = TP/(TP+FN) = TP/(所有世界是正例的个数)

3. PR曲线

Precision-Recall曲线是根据阈值 从0到1这个区间的变动,每个阈值下模型的precision和recall的值分别作为纵坐标和横坐标来连线绘制而成的。(每个阈值θ对应于一个(Precision,Recall)点,把这些点连起来就是PR曲线)

比如假设我们收集了20个sample的数据,他们的真实标签和置信度如下

 此时我们为了绘制PR曲线,计算出了PR曲线上下面这些点的坐标

阈值=0.9——TP=len([ #1, ]) = 1; FP=0; FN=len([#2, #4, #5, #6, #9, #11, #13, # 17, #19])=9——Precision=TP/(TP+FP)=1/(1+0)=1——Recall=TP/(TP+FN)=1/(1+9)= 0.1

阈值0.8——TP=len([#1,#2])=2; FP=0; FN=len([#4, #5, #6, #9, #11, #13, # 17, #19])=8——Precision=2/(2+0)=1; Recall=2/(2+8)=0.2

阈值0.7——TP=len([#1,#2])=2; FP=len([#3])=1, #_of_True=10 ——Precision=2/(2+1)=0.67;Recall=2/10=0.2

阈值0.6——TP=len([#1, #2,#4])=3FP=len([#3])=1, #_of_True=10——Precision=3/(3+1)=0.75; Recall = 3/10=0.3

阈值0.5——TP=len([#1, #2, #4, #5, #6, #9])=6FP=len([#3, #7, #8, #10])=4,#_of_True=10——Precision=6/(6+4)=0.6; Recall = 6/10=0.6

阈值0.4——TP=len([#1, #2,#4, #5, #6, #9,  #11])=7; FP=len([#3, #7, #8, #10])=4, #_of_True=10——Precision=7/(7+4)=0.64; Recall = 7/10=0.7

阈值0.3——TP=len([#1, #2,#4, #5, #6, #9,  #11, #13, #17, #19])=10;FP=len([#3, #7, #8, #10, #12, #14, #15, #16, #18])=9; #_of_True=10; ——Precision=10/(10+9)=0.53; Recall = 10/10=1

用sklearn的下面这段代码就可以计算出答案

import numpy as np
from sklearn.metrics import precision_recall_curve

# 导入数据
y_true = np.array([1,1,0,1,1,1,0,0,1,0,1,0,1,0,0,0,1,0,1,0])
y_scores = np.array([0.9,0.8,0.7,0.6,0.55,0.54, 0.53,0.52,0.51,0.505, 0.4, 0.39,0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.30, 0.1])

# 计算出每个阈值下,precision和recall的值
precision, recall, thresholds = precision_recall_curve(y_true, y_scores)

# 写上这两行,中间的列就不会被用省略号省略,都显示出来
pd.options.display.max_rows = None
pd.options.display.max_columns = None


#整理成横向的dataframe,方便大家查看
precision = pd.DataFrame(precision).T
recall = pd.DataFrame(recall).T
thresholds= pd.DataFrame(thresholds).T
#纵向拼接
results = pd.concat([thresholds, recall,precision], axis=0)
# 仅仅保留2位小数
results = round(results, 2)
#行名改一下
results.index = ["thresholds", "recall", "precision"]
print(results)

绘制出来的precision-recall曲线是下面这样

import matplotlib.pyplot as plt
def plot_pr_curve(recall, precision):
    plt.plot(recall, precision, label='Precision-Recall curve')
    plt.xlabel('Recall')
    plt.ylabel('Precision')
    plt.title('PR Curve')
    plt.legend()
plot_pr_curve(recall, precision)

对于PR图中这种类似锯齿状的图形,我们一般采用平滑锯齿的操作。所谓平滑锯齿操作就是在Recall轴上,对于每个阈值θ计算出的Recall点,看看它的右侧(包含它自己)谁的Precision最大,然后这个区间都使用这个Precision值,在下图这个例子中,Recall=(0,0.4] 都使用 Precision=1, Recall=(0.4,0.8] 都使用 Precision=0.57, Recall=(0.8,1) 都使用 Precision=0.5

因此我们这个例子中的图形经过锯齿平滑化以后应该是下面这个样子

Precision和Recall之间的此消彼长的矛盾关系

        上图的右下角,recall高,说明所有所有的杀人犯中99%的都被抓住了,那就会造成一个结果,抓的人特别多。和这桩杀人案有一丁点关系的人都被逮捕了。这必然导致,所有被抓的人中,实际是罪犯的比例变得很低,也就是precision低。

        OK,如果你希望Police抓的人中,实际是罪犯的比例高一些,(也就是precision高一些)。那Police就不敢乱抓人了,没有十足的证据就不敢去逮人。那结果是啥?那就是大量隐藏额的很好的罪犯都被漏掉了,也就是说所有的罪犯中实际被抓住的比例降低了。也就是recall低了。这种情形对应的就是上图左上角的那个位置。

如何评估一个不同模型的好坏关系

        既然一个模型的precision和recall是此消彼长的关系,不可能两个同时大,那怎么判断哪个模型更优呢?答案是,P-R曲线越往右上角凸起的曲线对应的模型越优秀。正如上图中红线A和黑线B都是比模型C要优秀的

        但是问题来了,模型A和模型B之间,孰优孰劣呢?那就引出了平衡点("Balanced Error Point" (BEP))这个概念。平衡点就是曲线上的Precision值=Recall值的那个点,也就是上图中那三个点,平衡点的坐标越大,模型越好。

        除了平衡点,也可以用F1 score来评估。F1 = 2 * P * R /( P + R )。F1-score综合考虑了P值和R值,是精准率和召回率的调和平均值, 同样,F1值越大,我们可以认为该学习器的性能较好。

4. 从PR曲线到AP

AP的公式如下

\text{AP} = \sum_n (R_n - R_{n-1}) P_n

AP这个指标的实际意义:

        AP是,在“”阈值不同“”引发的“Recall值不同”的情况下,各种Precision值的均值。AP summarizes a precision-recall curve as the weighted mean of precisions achieved at each threshold, with the increase in recall from the previous threshold used as the weight:

        AP值可以理解为PR曲线向下、向左到X轴和Y轴这片面积之和

        这个阈值到前一个阈值之间的差是长方形的宽,precision值是长方形的高。宽乘以高就是长方形柱子的面积。

        AP这就是P-R曲线的积分,也就是面积

用sklearn的公式这样算

from sklearn.metrics import average_precision_score
AP = average_precision_score(y_true, y_scores, average='macro', pos_label=1, sample_weight=None)
print(AP)

# 0.7357475805927818

AP=(0.2-0)× 1 + (0.5-0.2)× 0.83 + (0.6-0.5) × 0.67 + (0.7-0.6)×0.64 +(0.8-0.7)×0.62 +(1-0.8)×0.53=0.7480

和上面那个程序算出来来的有0.1的误差,但是大体区别不大就不去追究是哪个小地方算错了

5. 从AP到mAP

把各个类别(比如汽车、行人、巴士、自行车)的AP值取平均

6. 从mAP到 mAP50, mAP75, mAP95

mAP中也有IoU, mAP50这个也有IoU,二者之间是什么关联?

        mAP里面那个IoU是指的分类里面 判断类别上predicted label是True或False

        mAP50里面这个IoU指的是定位 里面 判断predicted bbox和ground truth bbox之间的IoU大于多少才能被算作  定位爱上的True或False

        mAP

目前还不懂的知识

        ROC曲线是什么?表示什么含义?怎么用?

        AUC曲线同样的问题

Reference

PR曲线与ROC曲线_roc曲线和pr曲线_THE@JOKER的博客-CSDN博客

为什么平均精准度(Average Precision,AP)就是PR曲线的线下面积? - Mark Lue的回答 - 知乎 https://www.zhihu.com/question/422868156/answer/1523130474

sklearn.metrics.average_precision_score — scikit-learn 1.3.0 documentation

[CV] 目标检测中的map计算 - 知乎 

COCO - Common Objects in Context

https://www.cnblogs.com/ywheunji/p/13376090.html

准确率、召回率和mAP、AP50/75_map和ap50_dagongji10的博客-CSDN博客

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

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

相关文章

[react基础]关于v6版本route的变化,以及常见应用模式

该说不说,在做这些之前,你要记得一件事 route不是react或者vue等原本就有的组件!需要你手动下载!然后导入! 原本的框架只是最终挂载到一个html界面上!!! 别再问我为啥你扒下来的代码为啥不好使了! 讨厌 > _< 下载指令去看我另一篇推文 今天复盘了一下自己的实训…

pyCharm远程DEBUG

第一步&#xff0c;添加一个远程机器的解释器 ssh 远程机器解释器添加&#xff0c; 我本地ssh有配置目标机器。 如果没配置&#xff0c;那就选着new server configuration 新增一个。 interpreter 指定远程机器python&#xff0c; &#xff08;机器上有多个版本python里尤其要…

【LeetCode-中等题】22. 括号生成

文章目录 题目方法一&#xff1a;递归&#xff1a;方法二&#xff1a;递归回溯 题目 方法一&#xff1a;递归&#xff1a; 递归入口 空子结果集&#xff0c;左括号数目&#xff08;初始为0&#xff09;&#xff0c;右括号数目&#xff08;初始为0&#xff09; 递归出口 若左括…

Eviews用向量自回归模型VAR实证分析公路交通通车里程与经济发展GDP协整关系时间序列数据和脉冲响应可视化...

全文下载链接&#xff1a;http://tecdat.cn/?p27784 河源市是国务院1988年1月7日批准设立的地级市&#xff0c;为了深入研究河源市公路交通与经济发展的关系&#xff0c;本文选取了1988&#xff0d;2014年河源市建市以来24年的地区生产总值&#xff08;GDP&#xff09;和公路通…

vue 子组件向父组件传递参数 子传父

子组件中写&#xff1a; this.$emit(RowCount,res.data.RowCount); 父组件中写&#xff1a; getMFGLRowCount(val){ //父组件中的方法: 接收子组件传过来的参数值赋值给父组件的变量 //this.totalCount val; alert("这…

CSS整理

目录 CSS中的& 弹性&#xff08;display:flex&#xff09;布局 flex的属性 justify-content align-items flex:1 flex属性 flex-grow&#xff1a;项目的放大比例 flex-shrink&#xff1a;收缩 flex-basis&#xff1a;初始值&#xff0c;项目占据的主轴空间&…

javascript | 变量、函数、属性的命名规则

javascript标识符的命名规则 变量、函数、属性的名字、或者函数的参数&#xff0c;都可称为标识符。标识符可以是按照下列格式规则组合起来的一个或者多个字符。 第一个字符必须是一个字母、下划线_、或美元符号$。数字不可以作为标识符的首字符。其他字符可以是数字、字母、…

华为云云耀云服务器L实例评测|在 Centos Docker 中使用Nginx部署Vue项目

目录 前言 项目构建 使用CentOS部署 安装Nginx 配置Nginx 项目启动 访问重定向 使用Docker部署 编写docker文件 dockerfile nginx dockercompose 项目启动 前言 本期我们测试在云耀云服务器L实例中分别演示如何在 系统镜像Centos 与 应用镜像 Docker 中使用Nginx…

Java多线程(三)多线程的模式--(阻塞队列,定时器,线程池)

多线程的模式--&#xff08;阻塞队列&#xff0c;定时器&#xff0c;线程池&#xff09; 多线程模式&#xff1a; 阻塞队列&#xff08;线程安全&#xff09; 重点是如何自己去实现这种数据结构&#xff1a; ​编辑 定时器&#xff1a; 实现一个定时器&#xff1a; 线程…

两种解法解决LCR 008. 长度最小的子数组【C++】

文章目录 [LCR 008. 长度最小的子数组](https://leetcode.cn/problems/2VG8Kg/description/)解法暴力解法滑动窗口&#xff08;双指针法&#xff09; LCR 008. 长度最小的子数组 解法 暴力解法 //暴力解法&#xff1a; //使用双for循环依次遍历数组&#xff0c;罗列出所有情况…

HTML的段落中怎么样显示出标签要使用的尖括号<>?

很简单&#xff1a; 符号 < 用 < 替代&#xff1b; 符号 > 用 > 替代。 示例代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>HTML中怎样打出尖括号</title> </head> <b…

AI图片生成 discord 使用midjourney

参考: 不用找咒语了&#xff01;Midjourney图生文功能特征解析&#xff0c;玩转Describe命令&#xff0c;快速搞定AI绘画_哔哩哔哩_bilibili 1 登录 discord 2 点发现 找 midjourney 3 创建 服务器 -> 亲自创建 4 选 仅供我和我的朋友使用 5 起个 服务器名字 6 加bot 由于…

常见的旅游类软文类型分享

假期将至&#xff0c;越来越多人选择出门旅游度过假期&#xff0c;那么各大旅游品牌应该怎么让自己的旅游软文在众多品牌中脱颖而出呢&#xff1f;接下来媒介盒子就给大家分享几个最能吸引受众的旅游类型软文。 一、攻略类软文 和普通的攻略不一样&#xff0c;普通的攻略以用户…

Element--生成不定列的表格

1、对于一些场景&#xff0c;前端可能需要展示不定列数的数据&#xff1b;譬如考勤&#xff0c;可能有的人是一天一次上下班打卡&#xff0c;有的人是一天两次上下班打卡。这个时候统计就需要更具人员做不同的展示&#xff0c;不能固定在前端写死列的属性。 2、代码示例 &…

Linux命令200例:nohup用于在后台运行命令

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

直播APP源码搭建:核心的服务器系统

在现代科技的推动下&#xff0c;网络衍生出了各种各样的技术&#xff0c;每个技术都被应用到需要的APP上&#xff0c;直播APP源码搭建出来的APP就是其中的一个&#xff0c;然而&#xff0c;这些技术能够成功的在直播APP源码搭建的APP中稳定的为用户们提供功能与服务&#xff0c…

内网穿透实现Windows远程桌面访问Ubuntu,简单高效的远程桌面解决方案

文章目录 前言1. ubuntu安装XRDP2.局域网测试连接3.安装cpolar内网穿透4.cpolar公网地址测试访问5.固定域名公网地址 前言 XRDP是一种开源工具&#xff0c;它允许用户通过Windows RDP访问Linux远程桌面。 除了Windows RDP外&#xff0c;xrdp工具还接受来自其他RDP客户端(如Fre…

Windows环境下Springboot3+Graalvm+Idea 打包成原生镜像 踩坑

https://github.com/oracle/graal/https://github.com/graalvm/graalvm-ce-builds/releases/对应关系graalvm-ce-java17-windows-amd64-X.X.X.zipnative-image-installable-svm-java17-windows-amd64-X.X.X.jar本人使用:graalvm-ce-java17-windows-amd64-23.0.1.zipnative-imag…

华为云云耀云服务器L实例评测|华为云云耀云服务器L实例评测使用

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

Canonical 发布公告,Ubuntu可以在 Windows 10 商店找到

导读Canonical 前几天正式发布公告称&#xff0c;“Windows 10 Loves Ubuntu”&#xff0c;其 Ubuntu 16.04 LTS 在 Windows 10 商店中以应用的方式出现&#xff0c;这是继 openSUSE 及 SLES 之后&#xff0c;又一款可以从 Windows 10 商店中下载的 Linux 操作系统。 一些用户已…