yolov8添加FPPI评价指标

这里写自定义目录标题

    • yolov8 中FPPI实现
    • 测试中调用
  • 效果
  • 结语

续yolov7添加FPPI评价指标 。之前在yolov7中增加了fppi指标,有不少网友问有没有yolov8中增加,最近没有做算法训练,也一直没时间弄。这几天晚上抽了点时间,弄了一下。不过我本地的yolov8挺久没更新了,所以不一定能直接用,权当参考吧。

yolov8 中FPPI实现

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

def fppi_per_class(tp, conf, pred_cls, target_cls, image_num, plot=False, on_plot=None, save_dir=Path(), names=(), eps=1e-16, prefix=""):"""Compute the false positives per image (FPPW) metric, given the recall and precision curves.Source:# Argumentstp:  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.5save_dir:  Plot save directory# ReturnsThe fppi curve"""# Sort by objectnessi = np.argsort(-conf)tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]# Find unique classesunique_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 classpx, py = np.linspace(0, 1, 1000), np.linspace(0, 100, 1000)  # for plottingr = 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.01p_miss_rate = np.array([1, 0.1, 0.01])for ci, c in enumerate(unique_classes):i = pred_cls == cn_l = (target_cls == c).sum()  # number of labelsn_p = i.sum()  # number of predictionsif n_p == 0 or n_l == 0:continueelse:# Accumulate FPs and TPsfpc = (1 - tp[i]).cumsum(0)tpc = tp[i].cumsum(0)# Recallrecall = tpc / (n_l + eps)  # recall curver[ci] = np.interp(-px, -conf[i], recall[:, 0], left=0)  # negative x, xp because xp decreasesmiss_rate[ci] = 1 - r[ci]fp_per_image = fpc / image_numfppi[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:names = [v for k, v in names.items() if k in unique_classes]  # list: only classes that have datanames = dict(enumerate(names)) plot_fppi_curve(fppi, miss_rate, miss_rate_at_fppi, save_dir / f"{prefix}fppi_curve.png", names, on_plot=on_plot)return miss_rate, fppi, miss_rate_at_fppi

将fppi以对数坐标画图:

@plt_settings()
def plot_fppi_curve(px, py, fppi, save_dir=Path("pr_curve.png"), names=(), on_plot=None):"""Plots a missrate-fppi curve."""fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True)py = np.stack(py, axis=1)# semi logfor i, y in enumerate(py.T):ax.semilogx(px[i],y, linewidth=1, label=f'{names[i]} {fppi[i].mean():.3f}')  # plot(recall, precision)ax.semilogx(px.mean(0), py.mean(1), linewidth=3, color='blue', label='all classes %.3f' % 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)plt.close(fig)if on_plot:on_plot(save_dir)

至此,fppi相关实现就完成了,接下来就是在代码中调用了。

测试中调用

通过调试,metrics的调用是在ultralytics/models/yolo/detect/val.py中的DetectionValidator中的get_stats函数中,在调用get_stats之前,会调用update_metrics计算tp, fp等。首先我们需要解决的时fppi计算需要图片的张数这个参数。在update_metrics我们可以获取这个值,在init_metrics增加参数self.image_num=0,在update_metrics中更新:

def update_metrics(self, preds, batch):"""Metrics."""self.image_num+=len(batch['im_file'])for si, pred in enumerate(preds):idx = batch['batch_idx'] == sicls = batch['cls'][idx]bbox = batch['bboxes'][idx]...

ap的计算在ultralytics/utils/metrics.py的DetMetrics中,我们给它也增加一个self.image_num=0参数, 并且在get_stats函数中设置它:

def get_stats(self):"""Returns metrics statistics and results dictionary."""# set image_num for fppi calculationself.metrics.image_num = self.image_numstats = [torch.cat(x, 0).cpu().numpy() for x in zip(*self.stats)]  # to numpyif len(stats) and stats[0].any():self.metrics.process(*stats)self.nt_per_class = np.bincount(stats[-1].astype(int), minlength=self.nc)  # number of targets per classreturn self.metrics.results_dict

然后修改其process函数,在这个函数中调用乐ap_per_class来计算map, 我们在后面增加计算fppi的函数即可( def keys(self)中要加一个fppi的key):

def process(self, tp, conf, pred_cls, target_cls):"""Process predicted results for object detection and update metrics."""results = ap_per_class(tp,conf,pred_cls,target_cls,plot=self.plot,save_dir=self.save_dir,names=self.names,on_plot=self.on_plot,)[2:]self.box.nc = len(self.names)self.box.update(results)results_fppi = fppi_per_class(tp,conf,pred_cls,target_cls,self.image_num,plot=self.plot,save_dir=self.save_dir,names=self.names,on_plot=self.on_plot,)self.box.update_fppi(results_fppi)@propertydef keys(self):"""Returns a list of keys for accessing specific metrics."""return ["metrics/precision(B)", "metrics/recall(B)", "metrics/mAP50(B)", "metrics/mAP50-95(B)",  "metrics/missrate_fppi_1"]

指标的计算结果是保存在ultralytics/utils/metrics.py的Metric结构中,所以还需要增加存储fppi相关指标(fitness也修改):

class Metric(SimpleClass):"""Class for computing evaluation metrics for YOLOv8 model.Attributes:p (list): Precision for each class. Shape: (nc,).r (list): Recall for each class. Shape: (nc,).f1 (list): F1 score for each class. Shape: (nc,).all_ap (list): AP scores for all classes and all IoU thresholds. Shape: (nc, 10).ap_class_index (list): Index of class for each AP score. Shape: (nc,).nc (int): Number of classes.Methods:ap50(): AP at IoU threshold of 0.5 for all classes. Returns: List of AP scores. Shape: (nc,) or [].ap(): AP at IoU thresholds from 0.5 to 0.95 for all classes. Returns: List of AP scores. Shape: (nc,) or [].mp(): Mean precision of all classes. Returns: Float.mr(): Mean recall of all classes. Returns: Float.map50(): Mean AP at IoU threshold of 0.5 for all classes. Returns: Float.map75(): Mean AP at IoU threshold of 0.75 for all classes. Returns: Float.map(): Mean AP at IoU thresholds from 0.5 to 0.95 for all classes. Returns: Float.mean_results(): Mean of results, returns mp, mr, map50, map.class_result(i): Class-aware result, returns p[i], r[i], ap50[i], ap[i].maps(): mAP of each class. Returns: Array of mAP scores, shape: (nc,).fitness(): Model fitness as a weighted combination of metrics. Returns: Float.update(results): Update metric attributes with new evaluation results."""def __init__(self) -> None:self.p = []  # (nc, )self.r = []  # (nc, )self.f1 = []  # (nc, )self.all_ap = []  # (nc, 10)self.ap_class_index = []  # (nc, )self.nc = 0self.missrate = [] #miss rate, (nc, )self.fppi = [] #false positives per image, (nc, )self.missrate_fppi = [] #miss rate at fppi 1, 0.1, 0.01, (nc, 3)@propertydef missrate_fppi_1(self):return self.missrate_fppi[:, 0].mean() if len(self.missrate_fppi) else []@propertydef ap50(self):"""Returns the Average Precision (AP) at an IoU threshold of 0.5 for all classes.Returns:(np.ndarray, list): Array of shape (nc,) with AP50 values per class, or an empty list if not available."""return self.all_ap[:, 0] if len(self.all_ap) else []@propertydef ap(self):"""Returns the Average Precision (AP) at an IoU threshold of 0.5-0.95 for all classes.Returns:(np.ndarray, list): Array of shape (nc,) with AP50-95 values per class, or an empty list if not available."""return self.all_ap.mean(1) if len(self.all_ap) else []@propertydef mp(self):"""Returns the Mean Precision of all classes.Returns:(float): The mean precision of all classes."""return self.p.mean() if len(self.p) else 0.0@propertydef mr(self):"""Returns the Mean Recall of all classes.Returns:(float): The mean recall of all classes."""return self.r.mean() if len(self.r) else 0.0@propertydef map50(self):"""Returns the mean Average Precision (mAP) at an IoU threshold of 0.5.Returns:(float): The mAP50 at an IoU threshold of 0.5."""return self.all_ap[:, 0].mean() if len(self.all_ap) else 0.0@propertydef map75(self):"""Returns the mean Average Precision (mAP) at an IoU threshold of 0.75.Returns:(float): The mAP50 at an IoU threshold of 0.75."""return self.all_ap[:, 5].mean() if len(self.all_ap) else 0.0@propertydef map(self):"""Returns the mean Average Precision (mAP) over IoU thresholds of 0.5 - 0.95 in steps of 0.05.Returns:(float): The mAP over IoU thresholds of 0.5 - 0.95 in steps of 0.05."""return self.all_ap.mean() if len(self.all_ap) else 0.0def mean_results(self):"""Mean of results, return mp, mr, map50, map."""return [self.mp, self.mr, self.map50, self.map, self.missrate_fppi_1]def class_result(self, i):"""class-aware result, return p[i], r[i], ap50[i], ap[i]."""return self.p[i], self.r[i], self.ap50[i], self.ap[i]@propertydef maps(self):"""mAP of each class."""maps = np.zeros(self.nc) + self.mapfor i, c in enumerate(self.ap_class_index):maps[c] = self.ap[i]return mapsdef fitness(self):"""Model fitness as a weighted combination of metrics."""w = [0.0, 0.0, 0.1, 0.9]  # weights for [P, R, mAP@0.5, mAP@0.5:0.95]return (np.array(self.mean_results()[:4]) * w).sum()def update(self, results):"""Args:results (tuple): A tuple of (p, r, ap, f1, ap_class)"""self.p, self.r, self.f1, self.all_ap, self.ap_class_index = resultsdef update_fppi(self, results):"""Args:results (tuple): A tuple of (missrate, fppi, missrate_fppi)"""self.missrate, self.fppi, self.missrate_fppi = results

效果

训练过程中会在mAP的后面打印fppi, 训练完成后以及调用test.py测试时,会画fppi图:
在这里插入图片描述

结语

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

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

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

相关文章

学习中...【京东价格/评论数据】数据获取方式——采用Selenium★

近期闲来无事学学selenium爬虫技术,参考崔庆才《Python3网络爬虫开发实战》的淘宝商品信息爬取,我也照猫画虎的学了京东的价格和商品评论数据。废话不多说,直接开始吧! 1. 浏览器初始化 from selenium import webdriver from se…

红黑树的平衡

1.红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路 径会比其他路径长出俩倍&#xff0c…

合合信息:TextIn文档解析技术与高精度文本向量化模型再加速

文章目录 前言现有大模型文档解析问题表格无法解析无法按照阅读顺序解析文档编码错误 诉求文档解析技术技术难点技术架构关键技术回根溯源 文本向量化模型结语 前言 随着人工智能技术的持续演进,大语言模型在我们日常生活中正逐渐占据举足轻重的地位。大模型语言通…

Scala基础

目录 1.安装与运行Scala 任务描述 了解Scala语言 了解Scala特性 安装Scala 运行Scala 2.定义函数识别号码类型 了解数据类型 定义与使用常量、变量 使用运算符 定义与使用数组 任务实现 3.基本语法 1 变量 2 字符串 3 数据类型&操作符 4 条件表达式 5 循环…

idea使用gitee基本操作流程

1.首先,每次要写代码前,先切换到自己负责的分支 点击签出。 然后拉取一次远程master分支,保证得到的是最新的代码。 写完代码后,在左侧栏有提交按钮。 点击后,选择更新的文件,输入描述内容(必填…

五分钟“手撕”时间复杂度与空间复杂度

目录 一、算法效率 什么是算法 如何衡量一个算法的好坏 算法效率 二、时间复杂度 时间复杂度的概念 大O的渐进表示法 推导大O阶方法 常见时间复杂度计算举例 三、空间复杂度 常见时间复杂度计算举例 一、算法效率 什么是算法 算法(Algorithm):就是定…

C++|多态性与虚函数(2)|虚析构函数|重载函数|纯虚函数|抽象类

前言 看这篇之前,可以先看多态性与虚函数(1)⬇️ C|多态性与虚函数(1)功能绑定|向上转换类型|虚函数-CSDN博客https://blog.csdn.net/weixin_74197067/article/details/138861418?spm1001.2014.3001.5501这篇文章会…

【十大排序算法】----C语言版插入排序(详细图解)

目录 一:插入排序——原理 二:插入排序——分析 三:插入排序——实现 四:插入排序——效率 一:插入排序——原理 插入排序的原理和基本思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序…

Django使用

一、根目录下安装 pip install django 二、创建djiango项目 django-admin startproject 项目名称 三、创建app python manage.py startapp app名称 四、启动 python manage.py runserver 五、编写URL与视图关系,相对路径 1、manage.py(见资源绑定…

多元化、高辨识显示丨基于G32A1445的汽车尾灯解决方案

由刹车灯、倒车灯、转向灯、雾灯等组成的汽车尾灯,既能在光线低暗时发出照明信息,也可向周围环境传递车辆的行驶状态与意图信号,对于行车安全起着至关重要的作用。与传统尾灯相比,贯穿式汽车尾灯更加醒目、美观、安全,…

CSS2(一):CSS选择器

文章目录 1、CSS基础1.1 CSS简介1.2 CSS编写位置1.2.1 行内样式1.2.2 内部样式1.2.3 外部样式1.2.4 样式优先级 1.2.5 CSS代码风格 2、CSS选择器2.1、基本选择器2.1.1 通配选择器2.1.2 元素选择器2.1.3 类选择器2.1.4 ID选择器2.1.5 总结 2.2、CSS复合选择器2.2.1 交集选择器2.…

海外媒体宣发:新加坡.马来西亚如何在海外媒体投放新闻通稿-大舍传媒

导言 随着全球化的进程加速,海外市场对于企业的发展越来越重要。而在海外媒体上宣传企业的新闻通稿,成为了拓展海外市场和提升企业知名度的重要手段之一。本文将介绍大舍传媒对于如何在海外媒体上投放新闻通稿的经验和策略。 准备工作:了解…

Hive 特殊的数据类型 Array、Map、Struct

Array 数组类型,存储数据类型一致的列表数据。 我们可以使用 array 方法来创建一个数组,如下所示: select array(1,2,3,4,5);如果其中的数据类型不一致,那么它会转换成统一的数据类型(前提是能够进行转换&#xff0…

力扣HOT100 - 322. 零钱兑换

解题思路&#xff1a; 动态规划 class Solution {public int coinChange(int[] coins, int amount) {int[] dp new int[amount 1];Arrays.fill(dp, amount 1);dp[0] 0;for (int i 1; i < amount; i) {for (int j 0; j < coins.length; j) {if (coins[j] < i) …

宠物管理系统带万字文档

文章目录 宠物管理系统一、项目演示二、项目介绍三、19000字论文参考四、部分功能截图五、部分代码展示六、底部获取项目源码和万字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 宠物管理系统 一、项目演示 宠物管理系统 二、项目介绍 基于springbootvue的前后端分离…

新串口通道打通纪实

在计算机系统中&#xff0c;串口是“古老”的通信方式&#xff0c;和它同时代的“并口”通信方式已经消失了。但它仍然顽强的存活着&#xff0c;主要原因是在开发和调试底层软件时还经常用到串口。 正因为有这样的需求&#xff0c;幽兰代码本是支持串口的&#xff0c;而且有两种…

【现代C++】概念的使用

现代C&#xff08;特别是C20及以后的版本&#xff09;引入了概念&#xff08;Concepts&#xff09;&#xff0c;这是一种指定模板参数必须满足的约束的方式。概念使得模板代码更清晰&#xff0c;更容易理解和使用&#xff0c;并且能在编译时提供更好的错误信息。以下是C概念的关…

UStaticMesh几何数据相关(UE5.2)

UStaticMesh相关类图 UStaticMesh的数据构成 UStaticMesh的FStaticMeshSourceModel UStaticMesh的Mesh几何元数据来自于FStaticMeshSourceModel&#xff0c; 一级Lod就存在一个FStaticMeshSourceModel. FStaticMeshSourceModel几何数据大致包含以下几类: Vertex(点), VertexI…

玩转Matlab-Simscape(初级)- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真(理论部分2)

** 玩转Matlab-Simscape&#xff08;初级&#xff09;- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真&#xff08;理论部分2&#xff09; ** 目录 玩转Matlab-Simscape&#xff08;初级&#xff09;- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真&am…