yolov7添加FPPI评价指标

学术上目标检测大多用mAP去评价一个模型的好坏,mAP用来作为比较模型的指标是挺好的,不过有个问题就是不够直观,比如mAP=0.9到底代表什么呢?平均一个图会误检几个呢?该取什么阈值呢?mAP说明不了,所以有时候我们还需要其他更直观的指标。

FPPI

fppi:false positive per image, 顾名思义就是平均每张图误检的个数。是目标检测中也比较常见的指标。FPPI与missrate(漏检率)可以构成如下的图像,曲线越低越好。
image.png
通过FPPI曲线图,我们可以知道在一个FPPI下面的漏检率,可以作为阈值选取的指导。

yolov7中增加FPPI

FPPI实现

yolo7中的评价指标实现位于utils/metrics.py中,我们只需要参照mAP指标在其中增加FPPI的内容即可:

def fppi_per_class(tp, conf, pred_cls, target_cls, image_num, plot=False, save_dir='.', names=(), return_plt=False):
    """ Compute the false positives per image (FPPW) metric, given the recall and precision curves.
    Source:
    # Arguments
        tp:  True positives (nparray, nx1 or nx10).
        conf:  Objectness value from 0-1 (nparray).
        pred_cls:  Predicted object classes (nparray).
        target_cls:  True object classes (nparray).
        plot:  Plot precision-recall curve at mAP@0.5
        save_dir:  Plot save directory
    # Returns
        The fppi curve 
    """
    # Sort by objectness
    i = np.argsort(-conf)
    tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]

    # Find unique classes
    unique_classes = np.unique(target_cls)
    nc = unique_classes.shape[0]  # number of classes, number of detections

    # Create Precision-Recall curve and compute AP for each class
    px, py = np.linspace(0, 1, 1000), np.linspace(0,100,1000) # for plotting
    r = np.zeros((nc, 1000))
    miss_rate = np.zeros((nc, 1000))
    fppi = np.zeros((nc, 1000))
    miss_rate_at_fppi = np.zeros((nc, 3)) # missrate at fppi 1, 0.1, 0.01
    p_miss_rate = np.array([1, 0.1, 0.01])
    for ci, c in enumerate(unique_classes):
        i = pred_cls == c
        n_l = (target_cls == c).sum()  # number of labels
        n_p = i.sum()  # number of predictions

        if n_p == 0 or n_l == 0:
            continue
        else:
            # Accumulate FPs and TPs
            fpc = (1 - tp[i]).cumsum(0)
            tpc = tp[i].cumsum(0)

            # Recall
            recall = tpc / (n_l + 1e-16)  # recall curve
            r[ci] = np.interp(-px, -conf[i], recall[:, 0], left=0)  # negative x, xp because xp decreases
            miss_rate[ci] = 1 - r[ci]

            fp_per_image = fpc/image_num
            fppi[ci] = np.interp(-px,-conf[i], fp_per_image[:,0], left=0)

            miss_rate_at_fppi[ci] = np.interp(-p_miss_rate, -fppi[ci], miss_rate[ci])
    
    if plot:
        fig = plot_fppi_curve(fppi, miss_rate, miss_rate_at_fppi, Path(save_dir) / 'fppi_curve.png', names)

    if return_plt:
        return fppi, miss_rate, miss_rate_at_fppi, fig

    return miss_rate, fppi, miss_rate_at_fppi

和mAP比较类似
f p p i = f p / i m a g e _ n u m fppi=fp/{image\_num} fppi=fp/image_num
m i s s r a t e = 1 − r e c a l l missrate=1-recall missrate=1recall
将fppi以对数坐标画图:

def plot_fppi_curve(px,py, missrate_at_fppi, save_dir='fppi_curve.png', names=()):
    fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True)
    py = np.stack(py, axis=1)
    # semi log
    for i, y in enumerate(py.T):
        ax.semilogx(px[i],y, linewidth=1, label=f'{names[i]} {missrate_at_fppi[i].mean():.3f}')  # plot(recall, precision)
    
    ax.semilogx(px.mean(0), py.mean(1), linewidth=3, color='blue', label='all classes %.3f' % missrate_at_fppi.mean())

    ax.set_xlabel('False Positives Per Image')
    ax.set_ylabel('Miss Rate')
    ax.set_xlim(0, 100)
    ax.set_ylim(0, 1)
    ax.grid(True)
    plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left")
    fig.savefig(Path(save_dir), dpi=250)

    return fig

训练中调用

在test.py中在map计算的下方增加fppi的计算:

p, r, f1, mp, mr, map50, map, t0, t1, mfppi_1 = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
........
........
stats = [np.concatenate(x, 0) for x in zip(*stats)]  # to numpy
if len(stats) and stats[0].any():
	p, r, ap, f1, ap_class = ap_per_class(*stats, plot=plots, save_dir=save_dir, names=names)
	miss_rate, fppi, miss_rate_at_fppi = fppi_per_class(*stats, plot=plots, image_num= image_num, save_dir=save_dir, names=names)
	mfppi_1 = miss_rate_at_fppi[:,0].mean()
	ap50, ap = ap[:, 0], ap.mean(1)  # AP@0.5, AP@0.5:0.95
	mp, mr, map50, map = p.mean(), r.mean(), ap50.mean(), ap.mean()
	nt = np.bincount(stats[3].astype(np.int64), minlength=nc)  # number of targets per class
else:
	nt = torch.zeros(1)# Print results
pf = "%20s" + "%12i" * 2 + "%12.3g" * 5  # print format
print(pf % ("all", seen, nt.sum(), mp, mr, map50, map, mfppi_1))
········
#返回fppi
return (mp, mr, map50, map, *(loss.cpu() / len(dataloader)).tolist(), mfppi_1), maps, t

wandb中增加,我习惯使用wandb, 所以加了这步,如果不使用wandb的话,上面的函数不返回fppi就不用修改train.py了:

train.py# Log
            tags = [
                "train/box_loss",
                "train/obj_loss",
                "train/cls_loss",  # train loss
                "metrics/precision",
                "metrics/recall",
                "metrics/mAP_0.5",
                "metrics/mAP_0.5:0.95",
                "val/box_loss",
                "val/obj_loss",
                "val/cls_loss",  # val loss,
                "val/missrate@fppi=1",
                "x/lr0",
                "x/lr1",
                "x/lr2",
            ]  # params

效果

训练过程中会在mAP的后面打印fppi, 训练完成后以及调用test.py测试时,会画fppi图:
image.png

结语

本文简述了在yolov7中增加FPPI评价指标,可以用来直观的表现模型的效果,指导阈值的选取。
f77d79a3b79d6d9849231e64c8e1cdfa~tplv-dy-resize-origshort-autoq-75_330.jpeg

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

获取android签名

1、安装安卓模拟器,比如MuMu模拟器; 2、打包需要签名的apk,记住包名,比如org.ungleyou.uy,后面签名用得着; 3、下载签名工具,Gen_Signature_Android.apk: http://dlied5.qq.com/msdk/Gen_Sig…

【力扣题解】P101-对称二叉树-Java题解

👨‍💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P101-对称二叉树-Java题解🌏题目描述💡题解🌏总结…

揭秘Pod状态与生命周期管理的秘密(上)

写在前面 前几篇文章中主要分享了k8s的几种控制器,本文将着重分享一下k8s最小的创建和部署单位pod的状态与生命周期管理。 点击 这里 可以查看所有相关文章。 Pod 概览 Pod 是 kubernetes 中你可以创建和部署的最小也是最简的单位。Pod 代表着集群中运行的进程。…

C# LINQ

一、前言 学习心得&#xff1a;C# 入门经典第8版书中的第22章《LINQ》 二、LINQ to XML 我们可以通过LINQ to XML来创造xml文件 如下示例&#xff0c;我们用LINQ to XML来创造。 <Books><CSharp Time"2019"><book>C# 入门经典</book><…

Quadratic Assignment Problem 二次分配问题

1 问题定义 二次分配问题&#xff08;Quadratic Assignment Problem&#xff0c;QAP&#xff09;是一种组合优化问题&#xff0c;涉及确定将设施分配到位置的最优方案。它的目标是找到最佳分配&#xff0c;以最小化设施对之间的总成本或距离&#xff0c;考虑到它们之间的相互作…

枚举(蓝桥杯备赛系列)acwing版

枚举 前言 hello&#xff0c;大家好&#xff0c;前面一段时间已经是把acwing Linux基础课讲完了&#xff0c;其实那些内容完全可以带领小白入门Linux我说过如果有人留言要Linux和Windows server 配置DNS Web ftp 的内容我就做一期&#xff0c;但是没人留言我也就先不自作多情了…

SpringSecurity6 | 退出登录后的跳转

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringSecurity6 ✨特色专栏: MySQL学习 🥭本文内容: SpringSecurity6 | 登录失败后的JSON处理 📚个人知识库: Leo知识库,…

联想发布天禧AI生态四端一体战略,聚焦智能体小程序开发

12月26日&#xff0c;2023联想天禧AI生态伙伴大会在北京正式召开&#xff0c;联想与英特尔、百度、网易有道等头部企业、400余家行业开发者和媒体齐聚一堂&#xff0c;以“AI生态 共赢未来”为主题&#xff0c;共同探讨未来AI生态发展及应用。联想集团副总裁、中国区消费业务群…

如何优化SEO的网站架构

通过优先考虑网站架构来提升你的SEO游戏–这是经常被忽视的有机性能的动力源。了解为什么清晰的结构至关重要&#xff0c;并获得对 SEO 友好的网站的提示。 当人们谈论高优先级的SEO活动时&#xff0c;他们通常会指出关键词研究、内容规划和链接建设等关键领域。 网站架构很少…

Text to image论文精读 TISE (Text-to-Image Synthesis Evaluation):用于文本到图像合成的评估度量工具包

TISE (Text-to-Image Synthesis Evaluation)是一款用于评估文本生成图像的Python评估工具箱。文章由Tan M. Dinh, Rang Nguyen, and Binh-Son Hua等人发表。 其以统一的方式促进、倡导公平的评估度量&#xff0c;并为未来的文本到图像综合研究提供可重复的结果。 文章链接&am…

医院手术麻醉系统源码,基于PHP、 js 、mysql、laravel、vue2技术开发,实现患者数据的自动采集和医疗文书自动生成

手麻系统作为医院信息化系统的一环&#xff0c;由监护设备数据采集系统和麻醉信息管理系统两个子部分组成。手麻信息系统覆盖了患者术前、术中、术后的手术过程&#xff0c;可以实现麻醉信息的电子化和手术麻醉全过程动态跟踪。 以服务围术期临床业务工作的开展为核心&#xf…

Android Studio问题解决:java.lang.NoSuchMethodException

文章目录 一、遇到问题二、分析与思考三、解决问题 一、遇到问题 java.lang.NoSuchMethodException: com.zkteco.android.biometric.b.a.ajni方法调用不到 二、分析与思考 新建了一个最简单的demo发现问题依旧 三、解决问题 通过交叉对比&#xff0c;最后发现是minifyEnable…

数据结构思维导图

数据结构思维导图&#xff0c;目前先写这些&#xff0c;后续有更新会继续。 1 数据结构思维导图

redis 从0到1完整学习 (七):ZipList 数据结构

文章目录 1. 引言2. redis 源码下载3. zipList 数据结构3.1 整体3.2 entry 数据结构分析3.3 连锁更新 4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&am…

让马达转动起来(motor)

代码&#xff1a; #include "reg51.h"sbit P2_0 P2^0; sbit P2_7 P2^7;void main(){while(1){P2_0 1;P2_7 0;} } 仿真&#xff1a; 介绍&#xff1a; 当2.0和2.7端口均为低电平或高电平时&#xff0c;马达保持不转动&#xff1b; 当2.0和2.7端口分别为高电平和…

数据库开发之内连接和外连接的详细解析

1.2 内连接 内连接查询&#xff1a;查询两表或多表中交集部分数据。 内连接从语法上可以分为&#xff1a; 隐式内连接 显式内连接 隐式内连接语法&#xff1a; select 字段列表 from 表1 , 表2 where 条件 ... ; 显式内连接语法&#xff1a; select 字段列表 …

ElasticSearch之RestClient笔记

1. ElasticSearch 1.1 倒排索引 1.2 ElasticSearch和Mysql对比 1.3 RestClient操作 导入依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.15.…

带大家做一个,易上手的家常辣椒炒香肠

搞两根香肠 我这里选择的哈尔滨红肠 切成片 打开下图这么大块姜 三瓣蒜 姜蒜切小片 三分之一个大葱 切段 一个螺丝椒 螺丝椒切片 起锅烧油 下葱姜蒜翻炒 翻炒一会儿 然后下入螺丝椒 翻炒出辣椒的辣味后 倒入一勺生抽调味 翻炒均匀后下入香肠 翻炒个几分钟 就可以放入…

Github项目推荐:快写鸭

项目地址 GitHub - oncework/kuaixieya: 「快写鸭」是一款专为开发者开发的一站式写作、管理、发布的更简单且下载即用的效率工具&#xff0c;去除繁琐配置但又极具丰富且自定义性质等功能。 项目简介 这是一个多平台的内容分发工具。可以用来加快博文的多平台发布。 项目截…

jar 运行清单文件MANIFEST.MF生成定义Main-Class Premain-Class IDEA maven-assembly-plugin

可运行jar文件中的启动清单文件 META-INF/MANIFEST.MF 内容自定义生成 清单文件中的 Main-Class: Premain-Class: Can-Retransform-Classes: 在maven-assembly-plugin插件中的生成配置如下, 注意命名 <archive> <manifest> <mainClass>c…