YOLOv8预测流程-原理解析[目标检测理论篇]

        接下来是我最想要分享的内容,梳理了YOLOv8预测的整个流程,以及训练的整个流程。

        关于YOLOv8的主干网络在YOLOv8网络结构介绍-CSDN博客介绍了,为了更好地介绍本章内容,还是把YOLOv8网络结构图放在这里,方便查看。

1.前言

        前面已经提到了Head层网络是根据类别数来设计生成特定的特征图,那么为什么要将预测box的特征图设计成64个维度?box特征图和预测Cls的特征图又是怎么解码用来预测图片中目标框的位置和类别的?这都是这一节要重点介绍的内容。

         在对box和cls解码之前首先要把三个尺度的特征图展开,box变成(1,64,6400)、(1,64,1600)、(1,64,400),cls变成(1,nc,6400)、(1,nc,1600)、(1,nc,400),然后各自进行合并,从而得到box(1,64,8400),cls(1,nc,8400),一张图片在输入网络后就会得到这两个向量,分别用来预测目标的位置和类别,接下来看一下是如何对这两个向量解码得到预测的结果,并且了解下预测的完整流程。

        预测模块分成了以下三个部分,图像预处理、模型推理以及后处理模块。接下来将按照这三个顺序来展开说明。

2.图像预处理模块

        图像预处理模块:对输入的图片进行预处理,包括letterBox、归一化等操作,这里主要介绍一下letterBox操作:(1)LetterBox的目的就是将原图的尺寸(1280,720)转换成网络输入尺寸(640,640);(2)缩放采用的是等比例缩放方式,即找出长边将其缩放成640,然后按照长边的缩放比例(1280/640=2),同时给短边进行缩放,得到720/2=360,然后把短边补充灰边至640;(3)如图所示经过LetterBox后的图片尺寸并不是640*640而是(640,384),这是为什么呢?这种是改进后的LetterBox,只要保证填充短边是32的倍数即可,这样可以加快推理速度。而至于为什么是32的倍数,我理解的是YOLOv8最大进行了5次下采样,为了保证每个像素都有效并且可以整除,那么输入尺寸必须是32的倍数。

3.推理模块

        推理模块:介绍下Box分支和Cls分支是如何进行解码的。 

        首先来看一下Box分支,由前面可知经过网络后会输出一个(1,64,8400)的向量,64是通过4*reg_max(reg_max=16)计算得到的,4是指预测的中心点到预测边框的左边(l)、上边(t)、右边(r)、下边(b)的距离,reg_max是指预测边框的范围,举个例子就很容易就能理解了。

         当reg_max=16时,在每个预测特征图下(20*20,40*40,80*80),能够预测的最大预测框的大小为30*30,如何理解30*30呢?如下表所示,4*16可以理解成一个4行16列的矩阵,l/t/r/b的值经过softmax后遵循着\sum value=1规定,并且最终预测的结果为Index和对应的value的乘积,比如网络预测的ltrb长度为:

                Left: 5*0.25+6*0.75=5.75 ;Top: 4*0.40+5*0.60=4.60; 

                Right: 5*0.35+6*0.65=5.65;Bottom: 4*0.4+6*0.6=5.20;

        既然如此,那么当Index=15时,value=1,此时预测的l、t、r、b均为最大值,且都为15,也就是说在每个特征图尺度下(20*20,40*40,80*80),能够预测的最大的边框大小均为30*30。比如在20*20尺寸的特征图中,这是专门用来预测大目标尺寸的特征图,而30*30已经超出了特征图20*20的尺寸,说明不会漏掉任何一个大目标。在40*40尺寸的特征图中,30*30能够预测大部分的中等目标(映射回640*640中,目标大小大概为480*480)。在80*80尺寸的特征图中,30*30主要也是用于预测小目标。

         最后,会根据缩放比例,把8400个grid cell预测的边框大小映射回640*640尺度,即输入到网络的尺寸上,并且把预测的LTRB表示方式更改为XYWH方式,即中心点/宽高方式。

        接着是cls分支,Cls分支仅是对所有元素做一个Sigmoid()操作,也就是说每个元素都会独立地经过Sigmoid()函数,从而得到一个(0,1)区间范围内的值。

4.后处理模块

         后处理模块:主要由两部分组成,分别是NMS模块和Scale_boxes.

         NMS模块即非极大值抑制,NMS流程分成了三部分,第一部分主要是通过置信度阈值过滤掉一部分(每个gird cell会有nc个预测类别的值,且经过sigmoid后均在(0,1)之间,取nc个里面的最大值和阈值进行比较),并且将XYWH格式转换为XYXY格式,由此8400个grid cell经过过滤后只剩下29个。第二部分主要通过Cls张量挑出这29个grid cell的类别置信度及其标签下标。第三部分是给box加上一个偏移量通过torchvision自带的NMS来完成标签框的过滤,给不同类别加上一个偏移量是为了在区分不同的类别。最后将得到一个3行6列的矩阵,代表预测出的三个目标及其对应的XYXY格式的Box,类别的置信度,以及类别的下标。

        下面是对于不同类别需要加上一个偏移量的理解,见图知意。 

        Scale_boxes模块是将预测结果映射回到原始输入图片尺寸的,首先将预测的框减去因为latter box产生的偏移量,复原到等比例缩放(640,360)时的每个框的XYXY坐标,然后再将XYXY坐标等比例放大到原始图像(1280,720)的坐标,最后把得到的XYXY坐标信息进行裁剪到指定的图像尺寸范围内,确保边界框不会超出图像的实际尺寸,简而言之就是不让预测框超出原始图像尺寸。

         至此,YOLOv8模块的预测部分就到此结束,下一章节将介绍目标检测任务中训练流程,有了对预测流程的理解,训练流程就比较容易理解了,详细可以见本专栏文章YOLOv8训练流程-原理解析[目标检测理论篇]-CSDN博客。

            

             

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

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

相关文章

1053: 输出利用先序遍历创建的二叉树中的指定结点的度

解法&#xff1a; c语言 #include<iostream> #include<vector> using namespace std; typedef struct tNodes{char val;tNodes* left, * right; }* tNode;void creat(tNode& t) {char ch;cin >> ch;if (ch #) t NULL;else {t new tNodes;t->val …

2024高安全个人密码本程序源码,贴身密码管家-随机密码备忘录二代密码

项目概述&#xff1a; 在这个网络高度发展的时代&#xff0c;每个人都需要上网&#xff0c;而上网就不可避免地需要使用账号和密码。 在众多账号的情况下&#xff0c;你是否还在为复杂难记的密码感到烦恼&#xff1f;现在只需要记录一次&#xff0c; 就可以随时查看你的密码…

微信小程序绕开wx.uploadFile,上传图片,(直接把图片上传到服务器)

用wx.request是可以上传文件的&#xff0c;区别在于需要通过路径读取文件&#xff0c;上传文件&#xff0c; 而wx.uploadFile的方法只需要用路径&#xff0c;无需读取文件 wx.chooseMedia({count: 1,mediaType: [image], // 只允许选择图片sourceType: [album, camera], // 可…

AI跟踪报道第41期-新加坡内哥谈技术-本周AI新闻:本周Al新闻: 准备好了吗?事情即将変得瘋狂

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Python函数基础详解(狠狠爱住)

函数的定义 在Python中&#xff0c;函数定义是指创建函数并定义其行为的过程。 一个简单的函数定义示例&#xff1a; def greet(name):"""这是一个向用户打招呼的函数"""print(f"Hello, {name}!")greet("Alice")在上面的…

【matlab基础知识代码】(十八)无约束最优化问题

min下面的x称为优化向量或者是决策变量 匿名函数法 >> f(x)(x(1)^2-2*x(1))*exp(-x(1)^2-x(2)^2-x(1)*x(2)); x0[0; 0]; [x,b,c,d]fminsearch(f,x0), x 0.6111 -0.3056 b -0.6414 c 1 d 包含以下字段的 struct: iterations: 72 funcCount: 137 algor…

STM32:GPIO输入输出

文章目录 1、GPIO介绍1.1 GPIO的基本结构1.1 GPIO的位结构 2、 GPIO工作模式3、GPIO标准外设库接口函数3.1 RCC接口函数3.2 GPIO接口函数3.2.1 GPIO的读取函数3.2.1 GPIO的写入函数 4、GPIO的初始化 1、GPIO介绍 GPIO&#xff08;General Purpose Input Output&#xff09;通用…

bugfix:若依框架下对某个url接口权限放行,登陆后调用却提示403无权限

引言 在构建基于若依(RuoYi)框架的现代Web应用时&#xff0c;API接口的安全与权限管理是不可或缺的一环。Spring Security作为业界广泛采用的安全框架&#xff0c;为若依提供了强大的权限控制能力。然而&#xff0c;在实际开发过程中&#xff0c;开发者常会遇到登录用户访问特…

synchronized对象锁和类锁

一、什么是对象锁和类锁 顾名思义 对象锁可以锁住同一对象下synchronized修饰的方法&#xff0c;但不会影响其他对象。synchronized修饰普通方法就为对象锁。 类锁static synchronized修饰一个方法&#xff0c;当一个线程在执行该方法时&#xff0c;其他任何线程用任何对象调…

软件测试之 接口测试 Postman使用

接口测试 URL HTTP协议 HTTP 请求部分 HTTP响应部分 Postman使用 界面介绍 这里 注意 如果你无法访问 那么 captchaImage这个打错了&#xff0c;给的资料中是错误的地址 https://kdtx-test.itheima.net/api/captchaImage登录接口 科大天下 第一个接口的登录设置 https://kd…

使用map类型的参数在mapper.xml中使用案例

使用map类型的参数在mapper.xml中使用案例 简介&#xff1a;在常见的开发中&#xff0c;对于参数的装载一般使用map类型方式&#xff0c;这样可以避免创建很多参数实体类&#xff0c;不管嵌套多层的数据参数都可以通过map拿取&#xff0c;对于嵌套多层的map&#xff0c;我们需…

如何在Java中使用异常处理机制

如何在Java中使用异常处理机制在Java中&#xff0c;异常处理是一种在程序运行时识别和响应错误情况的机制。它允许程序在出现异常时继续执行&#xff0c;而不是崩溃。Java异常处理机制的核心概念包括try、catch、finally、throw和throws关键字。下面详细介绍这些概念&#xff0…

已知哈夫曼节点个数,求哈夫曼字符编码数

哈夫曼编码(Huffman Coding)是一种用于无损数据压缩的嫡编码(权编码)算法。 在哈夫曼树中&#xff0c;每个叶子节点都代表一个字符&#xff0c;而节点的权重通常代表字符的频率。在哈夫曼编码中&#xff0c;每个字符都会被赋予一个二进制编码。为了获得这些编码&#xff0c;我…

云渲染动画300帧需要多久呢?瑞云渲染为你揭秘

在动画制作过程中&#xff0c;渲染的速度非常关键。对于一个项目需要渲染的300帧来说&#xff0c;由于硬件的限制&#xff0c;许多公司的设备可能无法快速完成这项任务。此时&#xff0c;借助云渲染服务的强大计算能力&#xff0c;可以显著减少完成时间&#xff0c;从而提速整个…

独孤思维:副业拉新排名第一很牛吗

01 30年河东&#xff0c;30年河西。 我从来不觉得&#xff0c;自己星球拉新第一&#xff0c;或者小报童直播一场卖80份有多牛。 因为比我牛比的&#xff0c;比我拉新多的大佬多了去了。 这个5月&#xff0c;比我潜在爆发的牛人也有很多。 过去的历史成绩&#xff0c;代表当…

【Java基础】初识正则表达式

正则表达式只适用于字符串 匹配matches 实际使用的是String类中定义的方法boolean matches(String regex) public static void piPei( ){String regex"[1][356789]\\d{9}";boolean boo"14838384388".matches(regex);System.out.println(boo); }验证qq号…

QtConcurrent::run操作界面ui的注意事项(2)

前面的“QtConcurrent::run操作界面ui的注意事项&#xff08;1&#xff09;”&#xff0c;末尾说了跨线程的问题&#xff0c;引出了Qt千好万好&#xff0c;就是跨线程不好。下面是认为的最简单的解决办法&#xff1a;使用QMetaObject::invokeMethod&#xff08;相比较信号-槽&a…

构建无服务器数仓(二)Apache DolphinScheduler 集成以及 LOB 粒度资源消费分析

引言 在数据驱动的世界中&#xff0c;企业正在寻求可靠且高性能的解决方案来管理其不断增长的数据需求。本系列博客从一个重视数据安全和合规性的 B2C 金融科技客户的角度来讨论云上云下混合部署的情况下如何利用亚马逊云科技云原生服务、开源社区产品以及第三方工具构建无服务…

18 分页:介绍

目录 简单例子 页表存在哪里 列表中究竟有什么 分页&#xff1a;也很慢 内存追踪 小结 在解决大多数空间管理问题上面&#xff0c;操作系统有两种方法&#xff1a; 第一种就是将空间分割成不同长度的分片&#xff0c;类似于虚拟内存管理中的分段&#xff0c;但是这个方法…

电商平台自动回复脚本制作的流程!

随着电子商务的快速发展&#xff0c;电商平台在日常运营中面临着大量的客户咨询和服务需求&#xff0c;为了提高客户服务效率和质量&#xff0c;许多电商平台采用了自动回复脚本&#xff0c;以快速响应客户问题并提供准确的信息。 本文将详细介绍电商平台自动回复脚本制作的流…