YOLOv8原理深度解读,超级详细

整体架构

在这里插入图片描述
在这里插入图片描述

  • BackboneFeature Extractor提取特征的网络,其作用就是提取图片中的信息,供后面的网络使用

  • Neck : 放在backbonehead之间的,是为了更好的利用backbone提取的特征,起着“特征融合”的作用。

  • Head:利用前面提取的特征,做出识别

常见的一些Backbone, Neck, Head网络

在这里插入图片描述

我们在后文讲述YOLOv8模型过程中会使用大量的术语和缩写。同样地,当我们在阅读网上这些YOLOv8的帖子的时候,我们会发现这些帖子(包括本文)都是默认你已经十分了解YOLOv1到YOLOv7的这些模型知识。或者说你起码要非常熟悉YOLOv5。

这是因为YOLOv8是博采众长的集大成之作。它参考了YOLOv1到YOLOv7系列的模型,博采众长,集各家优点于一身。

Backbone

借鉴了其他算法的这些设计思想

  • 借鉴了VGG的思想,使用了较多的3×3卷积,在每一次池化操作后,将通道数翻倍;

  • 借鉴了network in network的思想,使用全局平均池化(global average pooling)做预测,并把1×1的卷积核置于3×3的卷积核之间,用来压缩特征;(我没找到这一步体现在哪里)

  • 使用了批归一化层稳定模型训练,加速收敛,并且起到正则化作用。

以上三点为Darknet19借鉴其他模型的点。

Darknet-53:53指的是“52层卷积”+output layer

Darknet53当然是在继承了Darknet19的这些优点的基础上再新增了下面这些优点的。因此列在了这里

  • 借鉴了ResNet的思想,在网络中大量使用了残差连接,因此网络结构可以设计的很深,并且缓解了训练中梯度消失的问题,使得模型更容易收敛。

  • 使用步长为2的卷积层代替池化层实现降采样。(这一点在经典的Darknet-53上是很明显的,output的长和宽从256降到128,再降低到64,一路降低到8,应该是通过步长为2的卷积层实现的;在YOLOv8的卷积层中也有体现,比如图中我标出的这些位置)

  • 特征融合

模型架构图如下

Darknet-53的特点可以这样概括:(Conv卷积模块+Residual Block残差块)串行叠加4次

Conv卷积层+Residual Block残差网络就被称为一个stage

在这里插入图片描述

上面红色指出的那个,原始的Darknet-53里面有一层 卷积,在YOLOv8里面,把一层卷积移除了

为什么移除呢?

  • 原始Darknet-53模型中间加的这个卷积层做了什么?滤波器(卷积核)的个数从 上一个卷积层的512个,先增加到1024个卷积核,然后下一层卷积的卷积核的个数又降低到512个

  • 移除掉这一层以后,少了1024个卷积核,就可以少做1024次卷积运算,同时也少了1024个3×3的卷积核的参数,也就是少了9×1024个参数需要拟合。这样可以大大减少了模型的参数,(相当于做了轻量化吧)

  • 移除掉这个卷积层,可能是因为作者发现移除掉这个卷积层以后,模型的score有所提升,所以才移除掉的。为什么移除掉以后,分数有所提高呢?可能是因为多了这些参数就容易,参数过多导致模型在训练集删过拟合,但是在测试集上表现很差,最终模型的分数比较低。你移除掉这个卷积层以后,参数减少了,过拟合现象不那么严重了,泛化能力增强了。当然这个是,拿着你做实验的结论,反过来再找补,再去强行解释这种现象的合理性。

在这里插入图片描述

通过MMdetection官方绘制册这个图我们可以看到,进来的这张图片经过一个“Feature Pyramid Network(简称FPN)”,然后最后的P3、P4、P5传递给下一层的Neck和Head去做识别任务。 PAN(Path Aggregation Network)

在这里插入图片描述

“FPN是自顶向下,将高层的强语义特征传递下来。PAN就是在FPN的后面添加一个自底向上的金字塔,对FPN补充,将低层的强定位特征传递上去,

FPN是自顶(小尺寸,卷积次数多得到的结果,语义信息丰富)向下(大尺寸,卷积次数少得到的结果),将高层的强语义特征传递下来,对整个金字塔进行增强,不过只增强了语义信息,对定位信息没有传递。PAN就是针对这一点,在FPN的后面添加一个自底(卷积次数少,大尺寸)向上(卷积次数多,小尺寸,语义信息丰富)的金字塔,对FPN补充,将低层的强定位特征传递上去,又被称之为“双塔战术”。

FPN层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行参数聚合,这样的操作确实很皮。
自底向上增强

而 PAN(Path Aggregation Network)是对 FPN 的一种改进,它的设计理念是在 FPN 后面添加一个自底向上的金字塔。PAN 引入了路径聚合的方式,通过将浅层特征图(低分辨率但语义信息较弱)和深层特征图(高分辨率但语义信息丰富)进行聚合,并沿着特定的路径传递特征信息,将低层的强定位特征传递上去。这样的操作能够进一步增强多尺度特征的表达能力,使得 PAN 在目标检测任务中表现更加优秀。

FPN Explained | Papers With Code

https://jonathan-hui.medium.com/understanding-feature-pyramid-networks-for-object-detection-fpn-45b227b9106c

正常的YOLOv8对象检测模型输出层是P3、P4、P5三个输出层,为了提升对小目标的检测能力,新版本的YOLOv8 已经包含了P2层(P2层做的卷积次数少,特征图的尺寸(分辨率)较大,更加利于小目标识别),有四个输出层。Backbone部分的结果没有改变,但是Neck跟Header部分模型结构做了调整。这就是为什么v8模型yaml文件里面https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models/v8有p2这个模型

新增加的这个P6,是为了引入更多的参数量,多卷积了一层,是给xlarge那个参数量准备的,属于专门适用于高分辨图片(图片尺寸很大,有大量可挖掘的信息)的版本。

model=yolov8n.ymal 使用正常版本
model=yolov8n-p2.ymal 小目标检测版本
model=yolov8n-p6.ymal 高分辨率版本

在这里插入图片描述

整个YOLOv8的backbone,画出图来是下面这样

我们可以看到这个backbone由三种模块组成,CBS、C2f、SPPF

在这里插入图片描述

卷积模块使用CBS

三部分组成(1)一个二维卷积+(2)二维BatchNorm+(3)SiLU激活函数

在这里插入图片描述

SiLU的激活是通过sigmoid函数乘以其输入来计算的,即xσ(x)。

在这里插入图片描述

SiLU的优势:

  • 无上界(避免过拟合)(Diss:哪个激活函数是有上界的?)

  • 有下界(产生更强的正则化效果)(Diss,同上,很多的激活函数都是有下界的,这句话有没有必要)

  • 平滑(处处可导 更容易训练)(agree:确实比relu平滑)

  • x<0具有非单调性,函数值先降后增,-1以前是减函数,-1以后是增函数(对分布有重要意义 这点也是Swish和ReLU的最大区别)

你去看棕黄色的那条线,是d(SiLU),也就是SiLU激活函数的导函数,你可以看到,当x趋近于正无穷的时候,它的导函数趋近于一个比1大一点点的恒定的值

从下界那个点的自变量值(函数值最低的那个点,对应的横坐标,也就是接近-1的那个点),往正半轴走,整个函数的单调递增的

Residual block使用C2f

在这里插入图片描述

在这里插入图片描述

一个CBS卷积层

一个split,就是把 height × width × c_out这个feature mapchannel这一维度(c_out)切成两半,一半的feature maph × w × 0.5c_cout,另一半是h × w × 0.5c_cout。这个把channel一劈两半的行为称之为split

bottleneck之前的feature map和bottleneck之后的feature map进行concat融合,这叫残差连接

n个Bottleneck串行,每个Bottleneck都和最后一个Bottleneck concatenate起来,类似于做了特征融合

优势:让YOLOv8可以在保证轻量化的同时获得更加丰富的梯度流信息

SPPF

在这里插入图片描述

进来一个CBS卷积层,然后串行的三个Maxpooling,未做Maxpooling的feature map和每多做一次Maxpooling后得到的feauture map进行concat 拼接,实现特征融合

用CSP的“网络设计方法“对Darknet进行轻量化

把原始的feature map和原始feauture map经过卷积操作后得到的结果进行concat,就是CSP的思想

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

你单独去看backbone,你发现好像这些模块之间似乎没有使用CSP思想。一路串行下来,没有任何的跨层融合。

在这里插入图片描述

其实CSP思想的用在了组成backbone的这几个模块上,C2f模块和SPPF模块。C2f模块里面的DarknetBottleneck(add=True)也使用了CSP网络结构设计思想。

在这里插入图片描述

Neck

Neck上CSP思想的运用。

下图有四个 红心"c" 使用了CSP的思想。统统都是没做过卷积的原始feature map和将“原始特征图”进行过很多个卷积操作的feauture map进行融合,融合的位置就是在 四个 红心"c" 那里。

在这里插入图片描述

PAN-FPN

PAN-FPN,是指的在在YOLOv8的neck部分模仿PANet里面的backbone,也就是FPN网络(feature pyramid network)进行组织。PAN-FPN这个网络的特点进行简单概括,就是先下采样,然后再上采样,上采样和下采样的这两个分支之间还有两个跨层融合连接。(也可以反过来,先上采样,再下采样)

在这里插入图片描述

用C2f模块作为residual block

没啥好说的,就是图中这四个绿蓝色的模块

在这里插入图片描述

Head

先分叉开两个CBS卷积模块,然后过一个Conv2d,最后分别算出classifcation loss和Bbox loss

Decoupled-Head解耦头

Head 部分相比 YOLOv5 改动较大,从原先的耦合头换成了目前主流的解耦头结构(Decoupled-Head),将分类和检测头分离。同时由于使用了DFL(Distributional Focal Loss) 的思想,因此回归头的通道数也变成了4*reg_max的形式,reg_max默认16。

在这里插入图片描述

在这里插入图片描述

它这个解耦头Decoupled Head,具体是怎么把分类和识别这两个任务分离开的,你要去看代码,就是下面这段。(我现在还没搞懂是怎么做到拆分开的,后面需要用到这一块的时候,再来详细看,详细了解)

在这里插入图片描述

一个head做目标识别,用Bbox Loss来衡量。损失函数包括两部分CIoU和DFL

一个head做分类,用用BCE 二分类交叉熵损失函数 衡量,实际用的是VFL(Varifocal Loss)

在这里插入图片描述

损失函数的设计

分类损失函数

这里注意,虽然在“\ultralytics\yolo\utils\loss.py” line 11 像下面这样定义了VarifocalLoss,,但是在最后训练的时候,实际采用的分类损失是BCE loss

class VarifocalLoss(nn.Module):
    # Varifocal loss by Zhang et al. https://arxiv.org/abs/2008.13367
    def __init__(self):
        super().__init__()
 
    def forward(self, pred_score, gt_score, label, alpha=0.75, gamma=2.0):
        weight = alpha * pred_score.sigmoid().pow(gamma) * (1 - label) + gt_score * label
        with torch.cuda.amp.autocast(enabled=False):
            loss = (F.binary_cross_entropy_with_logits(pred_score.float(), gt_score.float(), reduction="none") *
                    weight).sum()
        return loss

证据我提供在下面。在\ultralytics\yolo\v8\detect\train.py line 187有下面这段代码。是train.py文件中这个类下面的代码“class Loss:”

首先我们可以看到对于cls. loss, YOLOv8的作者,没有使用varifocal loss,(尽管前面在loss.py作者定义了varifocal loss),而是使用了BCE loss

然后bbox loss 是 CIoU和DFL

然后这三个loss加权平均得到最终的loss

# cls loss
# loss[1] = self.varifocal_loss(pred_scores, target_scores, target_labels) / target_scores_sum  # VFL way
loss[1] = self.bce(pred_scores, target_scores.to(dtype)).sum() / target_scores_sum  # BCE
 
# bbox loss
if fg_mask.sum():
    loss[0], loss[2] = self.bbox_loss(pred_distri, pred_bboxes, anchor_points, target_bboxes, target_scores,
                                              target_scores_sum, fg_mask)
 
loss[0] *= self.hyp.box  # box gain
loss[1] *= self.hyp.cls  # cls gain
loss[2] *= self.hyp.dfl  # dfl gain
 
return loss.sum() * batch_size, loss.detach()  # loss(box, cls, dfl)

分类损失VFL Loss

样本不均衡,正样本极少,负样本极多,需要降低负样本对 loss 的整体贡献了,于是用了focal loss。VFL当然具备focal loss拥有的所有特性。

VFL独有的:

  • (1)学习 IACS 得分( localization-aware 或 IoU-aware 的 classification score)
  • (2)如果正样本的 gt_IoU 很高时,则对 loss 的贡献更大一些,可以让网络聚焦于那些高质量的样本上,也就是说训练高质量的正例对AP的提升比低质量的更大一些。

在这里插入图片描述

目标识别损失1-DFL(Distribution Focal Loss)

这个东西的公式入下

在这里插入图片描述

https://arxiv.org/pdf/2006.04388.pdf

将框的位置建模成一个 general distribution,让网络快速的聚焦于和目标位置距离近的位置的分布

在这里插入图片描述

目标识别损失2-CIOU Loss

CIoU讲述的最清楚的一篇文章:

​​​​​目标检测中的损失函数IoU、GIoU、DIoU、CIoU、SIoU_siou和ciou__-CHEN-_的博客-CSDN博客

考虑到长宽比

在这里插入图片描述

三角形凑成一堆,三角形匹配问题

在这里插入图片描述

样本匹配

YOLOv8则是

  • (1)抛弃了Anchor-Base方法,转而使用Anchor-Free方法,
  • (2)找到了一个替代边长比例的匹配方法——TaskAligned

Anchor-Based是什么?——Anchor-Based是指的利用anchor匹配正负样本,从而缩小搜索空间,更准确、简单地进行梯度回传,训练网络。

Anchor-Based方法的劣势是什么?——但是因为下列这些劣势,我们抛弃掉了anchor 这一多余的步骤:anchor也会对网络的性能带来影响,(1)如巡训练匹配时较高的开销、(2)有许多超参数需要人为尝试调节等

Anchor-free的优势是什么?——Anchor-free模型则摒弃或是绕开了锚的概念,用更加精简的方式来确定正负样本,同时达到甚至超越了两阶段anchor-based的模型精度,并拥有更快的速度。

为与NMS(non maximum suppression非最大抑制)搭配,训练样例的Anchor分配需要满足以下两个规则:——设计TaskAligned这个规则初衷

  • 正常对齐的Anchor应当可以预测高分类得分,同时具有精确定位;

  • 不对齐的Anchor应当具有低分类得分,并在NMS阶段被抑制。 基于上述两个目标,TaskAligned设计了一个新的Anchor alignment metric 来在Anchor level 衡量Task-Alignment的水平。并且,Alignment metric 被集成在了 sample 分配和 loss function里来动态的优化每个 Anchor 的预测。(完全没看懂这句话)

Anchor alignment metric:

分类得分和 IoU表示了这两个任务的预测效果,所以,TaskAligned使用分类得分和IoU的高阶组合来衡量Task-Alignment的程度。使用下列的方式来对每个实例计算Anchor-level 的对齐程度:

在这里插入图片描述

s 和 u 分别为分类得分和 IoU 值,α 和 β 为权重超参。 从上边的公式可以看出来,t 可以同时控制分类得分和IoU 的优化来实现 Task-Alignment,可以引导网络动态的关注于高质量的Anchor。TaskAlignedAssigner 的匹配策略简单总结为: 根据分类与回归的分数加权的分数选择正样本。

Training sample Assignment:

为提升两个任务的对齐性,TOOD(Task-aligned One-stage Object Detection)聚焦于Task-Alignment Anchor,采用一种简单的分配规则选择训练样本:对每个实例,选择m个具有最大t值的Anchor作为正样本,选择其余的Anchor作为负样本。然后,通过损失函数(针对分类与定位的对齐而设计的损失函数)进行训练。

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

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

相关文章

金蝶云星空协同开发环境应用内执行SQL脚本

文章目录 金蝶云星空协同开发环境应用内执行SQL脚本 金蝶云星空协同开发环境应用内执行SQL脚本

电阻的运用

本文引注 https://baijiahao.baidu.com/s?id1749115196647029942&wfrspider&forpc 一、零欧电阻 在电子电路设计时经常用到的一种元件就是电阻&#xff0c;我们都知道电阻在电路中起到分压限流的作用。然而&#xff0c;实际使用时会用到一种特殊的电阻&#xff1a;零…

mysql数据恢复

使用MySQL第三方工具binlog2sql binlog2sql&#xff0c;一款基于python开发的开源工具&#xff0c;是由大众点评团队的DBA使用python开发出来的&#xff0c;从MySQL binlog解析出你要的SQL。根据不同选项&#xff0c;你可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。其功…

STM32CubeIDE串口空闲中断实现不定长数据接收

STM32F051空闲中断实现串口不定长数据接收 目的编程软件配置串口开中断中断程序 运行结果碰到的问题 目的 在串口输入不定长数据时&#xff0c;通过串口空闲中断来断帧接收数据。 编程软件 STM32CubeIDE STM32CubeMX配置MCU。通过对端口配置&#xff0c;自动生成程序&#x…

AI抽烟识别系统研发关键

为了设计一个有效的AI抽烟识别系统&#xff0c;我们需要考虑几个关键组成部分&#xff1a;图像捕捉、数据处理、模型训练、以及实际应用场景。下面是这个方案的详细阐述&#xff1a; 1. 图像捕捉与数据收集 摄像头部署&#xff1a;首先&#xff0c;在需要监控的区域安装高分辨…

springboot自定义starter步骤

引入相关依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional> </dependency><dependency><groupId>org.pro…

SpringBoot基础使用及对其他项目进行整合

目录 一、简介 1-讲述 2-特点 二、创建配置 1.创建 2.配置 3.代码生成 三、项目整合 每篇一获 一、简介 1-讲述 众所周知 Spring 应用需要进行大量的配置&#xff0c;各种 XML 配置和注解配置让人眼花缭乱&#xff0c;且极容易出错&#xff0c;因此 Spring 一度被称…

Ignoring query to other database

登录数据库执行查看database的脚本提示 仔细观察才发现&#xff0c;登录的时候我写的是&#xff0c;没写 -u 退出重新登录&#xff0c;好了~

继续看回溯问题

关卡名 继续看回溯问题 我会了✔️ 内容 1.复习递归和N叉树&#xff0c;理解相关代码是如何实现的 ✔️ 2.理解回溯到底怎么回事 ✔️ 3.掌握如何使用回溯来解决二叉树的路径问题 ✔️ 1 复原IP地址 这也是一个经典的分割类型的回溯问题。LeetCode93.有效IP地址正好由四…

垃圾回收 (GC) 在 .NET Core 中是如何工作的?(二)

接上一篇文章垃圾回收 (GC) 在 .NET Core 中是如何工作的&#xff1f;-CSDN博客 GC 会分配堆段&#xff0c;其中每个段都是一系列连续的内存。 置于堆中的对象归类为 3 个代系之一&#xff1a;0、1 或 2。 代系可确定 GC 尝试在应用不再引用的托管对象上释放内存的频率。 编号…

C++_构造函数与析构函数

目录 1、构造函数的写法 1.2 构造函数优化写法 2、默认构造函数与默认成员函数 2.1 默认成员函数对不同类型的处理 3、对内置类型的补丁 4、析构函数 4.1 析构函数的写法 5、默认析构函数 6、初始化列表 6.1 初始化列表的写法 6.2 初始化列表的作用 6.3 回顾与总结 …

引迈信息-JNPF平台怎么样?值得入手吗?

目录 1.前言 2.引迈低代码怎么样&#xff1f; 3.平台亮点展示 4.引迈产品特点 5.引迈产品技术栈&#xff1a; 1.前言 低代码是近几年比较火的一种应用程序快速开发方式&#xff0c;它能帮助用户在开发软件的过程中大幅减少手工编码量&#xff0c;并通过可视化组件加速应用…

高效电商策略:小红书集成CRM与广告推广无代码化

无代码开发的优势 随着科技的不断进步&#xff0c;无代码开发&#xff08;No-Code Development&#xff09;已经成为快速构建系统和应用的新趋势。无代码开发指的是不需要传统编程知识&#xff0c;通过图形化的用户界面和模型驱动逻辑来创建应用程序。这种方式让非技术背景的用…

排序 | 冒泡插入希尔选择堆快排归并计数排序

排序 | 冒泡插入希尔选择堆快排归并计数排序 文章目录 排序 | 冒泡插入希尔选择堆快排归并计数排序冒泡排序插入排序希尔排序选择排序堆排序快速排序--交换排序三数取中快速排序hoare版本快速排序挖坑法快速排序前后指针法 快速排序--非递归实现归并排序归并排序非递归实现非比…

Window操作系统发展史

引言 当谈及计算机操作系统的丰富历史和多样性时&#xff0c;Windows操作系统无疑是其中的一颗璀璨明星。自1985年首次亮相以来&#xff0c;Windows经历了长足的发展&#xff0c;塑造了计算机使用体验的方方面面。从初始的简单图形用户界面到如今强大而多样的功能&…

【开源工程及源码】数字孪生乡村—经典开源项目实景三维数字孪生

智慧乡村可视化平台&#xff0c;旨在通过数字化和智能化手段提升乡村管理、服务和发展水平。通过飞渡科技强大的渲染引擎&#xff0c;1&#xff1a;1 建模还原乡村全貌&#xff0c;建立起具备信息化、智能化、绿色化的智慧乡村综合管理平台。 综合态势模块下&#xff0c;可以从…

C语言——预处理详解(#define用法+注意事项)

#define 语法规定 #define定义标识符 语法: #define name stuff #define例子 #include<stdio.h> #define A 100 #define STR "abc" #define FOR for(;;)int main() {printf("%d\n", A);printf("%s\n", STR);FOR;return 0; } 运行结果…

模板方法模式(行为型)

目录 一、前言 二、模板模式 三、带钩子的模板模式 四、总结 一、前言 模板方法模式是一种行为型设计模式&#xff0c;它定义了一个操作中的算法框架&#xff0c;将一些步骤延迟到子类中实现。这种模式是基于“开闭原则”的设计思想&#xff0c;即对扩展开放&#xff0c;对…

【Unity动画】综合案例完结-控制角色动作播放+声音配套

这个案例实现的动作并不复杂&#xff0c;主要包含一个 跳跃动作、攻击动作、还有一个包含三个动画状态的动画混合树。然后设置三个参数来控制切换。 状态机结构如下&#xff1a; 完整代码 using System.Collections; using System.Collections.Generic; using UnityEngine;pu…

数据挖掘-08-基于Python实现时间序列分析建模(ARIMA 模型)(包括数据和代码)

文章目录 0. 数据代码下载1. 背景描述2. 预测目的3. 数据总览4. 数据预处理4.1数据描述性统计与清洗a. 导入程序库b. 读取数据c. 查看统计信息和空值d. 查看是否有重复数据以及清理重复数据e. 空值清理f. 针对清洗后的数据进行统计分析 5. 探索性数据分析5.1 数据分析 6. 构建 …