cocomap计算原理

### 计算 mAP 的过程

1. **初始化和准备工作:**
   - 加载并初始化评估参数和结果,包括类别、IoU 阈值、召回率阈值、面积范围和最大检测数等。
   - 初始化用于存储精度、召回率、得分和 F1 分数的数组。

2. **遍历每个类别、面积范围和最大检测数量:**
   - 对于每个类别、面积范围和最大检测数组合,从 `self.evalImgs` 中提取相应的评估结果。
   - 合并所有图像的检测得分、匹配结果和忽略标记。

3. **排序和匹配处理:**
   - 根据检测得分进行排序。
   - 计算真阳性(TP)和假阳性(FP)。

4. **累积计算:**
   - 使用 `np.cumsum` 计算累积真阳性(TP)和假阳性(FP)。
   - 根据累积真阳性计算召回率(recall)。
   - 根据累积真阳性和假阳性计算精度(precision)。

5. **确保精度的单调递减性:**
   - 通过从后向前遍历,确保精度数组是单调递减的,以便于插值计算。

6. **插值计算和存储结果:**
   - 根据预定义的召回率阈值,使用 `np.searchsorted` 查找对应的召回率和精度值。
   - 计算并存储不同召回率下的精度值、得分和 F1 分数。

### 代码详解

```python
def accumulate(self, p=None):'''Accumulate per image evaluation results and store the result in self.eval:param p: input params for evaluation:return: None'''print('Accumulating evaluation results...')tic = time.time()if not self.evalImgs:print('Please run evaluate() first')if p is None:p = self.paramsp.catIds = p.catIds if p.useCats == 1 else [-1]T = len(p.iouThrs)R = len(p.recThrs)K = len(p.catIds) if p.useCats else 1A = len(p.areaRng)M = len(p.maxDets)precision = -np.ones((T, R, K, A, M))recall = -np.ones((T, K, A, M))f1 = -np.ones((T, K, A, M))scores = -np.ones((T, R, K, A, M))# create dictionary for future indexing_pe = self._paramsEvalcatIds = _pe.catIds if _pe.useCats else [-1]setK = set(catIds)setA = set(map(tuple, _pe.areaRng))setM = set(_pe.maxDets)setI = set(_pe.imgIds)k_list = [n for n, k in enumerate(p.catIds) if k in setK]m_list = [m for n, m in enumerate(p.maxDets) if m in setM]a_list = [n for n, a in enumerate(map(lambda x: tuple(x), p.areaRng)) if a in setA]i_list = [n for n, i in enumerate(p.imgIds) if i in setI]I0 = len(_pe.imgIds)A0 = len(_pe.areaRng)for k, k0 in enumerate(k_list):Nk = k0 * A0 * I0for a, a0 in enumerate(a_list):Na = a0 * I0for m, maxDet in enumerate(m_list):E = [self.evalImgs[Nk + Na + i] for i in i_list]E = [e for e in E if e is not None]if len(E) == 0:continuedtScores = np.concatenate([e['dtScores'][0:maxDet] for e in E])inds = np.argsort(-dtScores, kind='mergesort')dtScoresSorted = dtScores[inds]dtm = np.concatenate([e['dtMatches'][:, 0:maxDet] for e in E], axis=1)[:, inds]dtIg = np.concatenate([e['dtIgnore'][:, 0:maxDet] for e in E], axis=1)[:, inds]gtIg = np.concatenate([e['gtIgnore'] for e in E])npig = np.count_nonzero(gtIg == 0)if npig == 0:continuetps = np.logical_and(dtm, np.logical_not(dtIg))fps = np.logical_and(np.logical_not(dtm), np.logical_not(dtIg))tp_sum = np.cumsum(tps, axis=1).astype(dtype=np.float32)fp_sum = np.cumsum(fps, axis=1).astype(dtype=np.float32)for t, (tp, fp) in enumerate(zip(tp_sum, fp_sum)):tp = np.array(tp)fp = np.array(fp)nd = len(tp)rc = tp / npigpr = tp / (fp + tp + np.spacing(1))q = np.zeros((R,))ss = np.zeros((R,))if nd:recall[t, k, a, m] = rc[-1]else:recall[t, k, a, m] = 0pr = pr.tolist()q = q.tolist()for i in range(nd - 1, 0, -1):if pr[i] > pr[i - 1]:pr[i - 1] = pr[i]inds = np.searchsorted(rc, p.recThrs, side='left')try:for ri, pi in enumerate(inds):q[ri] = pr[pi]ss[ri] = dtScoresSorted[pi]except:passprecision[t, :, k, a, m] = np.array(q)scores[t, :, k, a, m] = np.array(ss)# 计算单一召回率下的 F1 分数single_recall = rc[-1]  # 取最大召回率q_array = pr[-1]if single_recall + q_array != 0:f1_score = 2 * (q_array * single_recall) / (q_array + single_recall + np.spacing(1))else:f1_score = np.zeros_like(q_array)f1[t, k, a, m] = f1_scoreself.eval = {'params': p,'counts': [T, R, K, A, M],'date': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'precision': precision,'recall': recall,'scores': scores,'f1': f1  # 新增 F1 分数}toc = time.time()print('DONE (t={:0.2f}s).'.format(toc - tic))


```

### 总结

- COCO 计算 mAP 的过程是逐步增加检测数量,计算相应的召回率和精度值。
- 通过累积真阳性和假阳性数 (`tp_sum` 和 `fp_sum`),计算累积召回率和精度。
- 确保精度数组是单调递减的,以便于插值计算。
- 根据预定义的召回率阈值,插值计算并存储不同召回率下的精度值和 F1 分数。

这一过程确保了 mAP 计算的准确性和一致性,使得评估结果能够反映模型在不同召回率阈值下的综合表现。

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

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

相关文章

关于FPGA对 DDR4 (MT40A256M16)的读写控制 2

关于FPGA对 DDR4 (MT40A256M16)的读写控制 2 语言 :Verilg HDL EDA工具:ISE、Vivado、Quartus II 关于FPGA对 DDR4 (MT40A256M16)的读写控制 2一、引言二、DDR4的简介四、DDR4 SDRAM状态框图 关键词&#x…

mysql5.7安装后未要求输入密码就能使用mysql登录原因

ubuntu20安装mysql5.7后,在root用户下直接运行mysql就能进入数据库。在其它用户下却无法登录,提示以下错误: Access denied for user ‘root’localhost’ 原因是root用户默认使用socket认证: mysql> select user,plugin fro…

Java 泛型与集合的深入解析:原理、应用与实践

泛型的基本原理 为什么需要泛型 在Java 5之前,Java的集合类只能存储Object类型的对象。这意味着,存储在集合中的对象在取出时需要进行类型转换,这不仅繁琐,而且容易出错。泛型通过在编译时进行类型检查,确保类型安全…

使用canvas制作一个无人机旋转特效

​ 使用HTML5的Canvas API来制作一个无人机旋转特效。这个特效将包括一个无人机图标(你可以使用任何你喜欢的图标),它会在一个固定的位置旋转。 首先,我们需要创建一个HTML文件,然后在其中添加一个canvas元素。canvas…

用Unity创造自己的绿洲

“谢谢你能玩我的游戏!” 希望将来我也能做出一款影响全世界的游戏,就比如现在的《英雄联盟》,或是电影里的《绿洲》!然后也说出这么一句话:谢谢你能玩我的游戏! 阶段性的总结一下 那就展示一下最近完成的…

【Hachker News】如果你不需要钱,你会干什么?

Hachker News上的一个问题,标题是“如果你不需要钱,你会做什么?” 回答摘要 问题链接:What would you spend your time working on if you didn’t need money? A1: 我会把时间投入到城市周围的农村地区&#xff0c…

Matlab使用Simulink仿真实现AM和BPSK信号的解调

前言 本篇实现了基于AM和BPSK调制的通信系统,采用Bernoulli Binary Generator生成随机二元序列,码元速率为0.5秒/个。AM调制使用Sine Wave模块生成载波,频率40Hz,相位π/2。BPSK调制通过Switch模块切换相位0和π的载波。信号传输…

【java计算机专业毕设】房屋租赁系统代码源码MySQL springboot vue html maven送文档ppt

1项目功能 【java计算机专业毕设】房屋租赁系统javaweb MySQL springboot vue html maven 送报告 2项目介绍 系统功能: 房屋租赁系统包括管理员和用户和房东三种角色。 该系统包含多个功能模块,分别为管理员、用户和房东提供服务。管理员功能包括个人中…

近期docker镜像加速器被封杀,需要的请看此内容 点赞加关注

{ “registry-mirrors”: [“https://docker.m.daocloud.io”], “insecure-registries”: [“harbor.sunya.com”], “exec-opts”: [“native.cgroupdriversystemd”], “data-root”: “/data/docker”, “log-driver”: “json-file”, “log-opts”: {“max-size”:“500m…

20.2 JSON-JSON解码、映射数据类型、处理JSON响应

1. JSON解码 JSON解码,即将JSON格式在字符串转换为Go语言数据类型的变量。 函数Unmarshal接受一个JSON字节切片和一个指定目标格式的接口。而这个借口即与JSON字符串中的结果相匹配的结构体类型的变量。 定义结构体类型 type Person struct { ... }创建结构体变量…

面试真题:消费者积压问题的答案

对这个问题,笔者给出如下的建议方案 消费者积压问题概述: 定义与影响: 消费者处理速度跟不上生产者发送速度消息队列长度不断增长,系统性能下降 常见问题场景: 高并发场景下,消费者处理能力不足消费者…

Python 3和Python 2之间主要区别

Python 3和Python 2之间存在多个显著的区别,这些区别主要体现在语法、数据类型、编码方式、库支持和错误处理等方面。以下是对这些主要区别的详细解释: 语法差异: print函数:Python 2使用print语句来输出内容,而Pytho…

聚鼎科技:现在的装饰画做起来难吗

在当代,装饰画作为一种体现个人品味和审美情趣的方式,已经广泛应用于各种室内空间。不少人会产生这样的疑问:在现代化技术和材料的支持下,制作一幅装饰画是变得容易了,还是依旧充满挑战? 现代科技的确为装饰画的制作带…

CAD如何延长具体长度线段

使用“OFFSET”命令 打开CAD软件,并打开需要编辑的图纸文件,并确定需要延长的线条。 在命令行中输入“OFFSET”命令,并按“Enter”键确认。 根据提示,输入所需的新长度,或者选择复制方式进行延长。 按“Enter”键确认&…

微信小程序查分易如何使用?

期末马上到了,老师们又开始为发放成绩而头疼了,堆积如山的试卷,密密麻麻的分数,还有那些不断响起的家长电话,真是让人心烦。别担心,今天就让我来介绍一个让老师“偷懒”神器——查分易微信小程序 第一步&am…

ROS中Twist消息类型

Twist消息类型在Robot Operating System (ROS)中是一个常见的数据结构,主要用于描述物体的线性速度和角速度。这种消息类型在ROS的geometry_msgs包中定义,常用于机器人运动控制,尤其是当需要向机器人发布速度指令时。 Twist消息由两个Vector…

【安装和使用Android Studio用于Android应用程序开发】

安装和使用Android Studio,这是Google推荐的官方IDE,用于Android应用程序开发。以下是详细的安装和使用教程: 安装Android Studio 1. 下载Android Studio 官网地址: Android Studio下载页面 根据你的操作系统(Windows、macOS …

6月14日 Qtday2

#include "widget.h" #include "ui_widget.h" #include <QTimer> using namespace std; Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), lab1(new QLabel(this)) //初始化一个标签显示登录状态 {//设置华清远见的标签图…

防止连续点击按钮,多次调用接口

防止连续点击按钮&#xff0c;导致多次调用接口问题 文章目录 防止连续点击按钮&#xff0c;导致多次调用接口问题一、为什么需要禁止按钮多次调用问题&#xff1f;二、实现步骤1.使用Vue.directive 自定义指令2.在入口文件main.js引入文件2.使用自定义指令 总结 一、为什么需要…

再谈 dijkstra 算法和最短路径问题

前置文章&#xff1a; dijkstra 算法为什么高效 有向图的负权值边与建模 求单源最短路径的新方法 前天晚上实现了一个基于 dijkstra 算法的求单源最短路径的新算法&#xff0c;整理了一篇文章。我非常不愿意把一些直观的问题太过于技术化&#xff0c;但多年的职业经历偏偏让一…