YOLO目标检测理论详解,YOLOv1理论知识讲解,超w字精读(学习YOLO框架必备),全网最详细教程
文章目录
- 前言
- 一、目标检测理论
- 1.目标检测发展史
- 2.目标检测框架理论基础
- 3.本章小结
- 二、YOLOv1理论知识
- 1.YOLOv1网络结构
- 2.YOLOv1检测原理
- 3.YOLOv1的训练流程
- (1)边界框的位置参数
- (2)边界框的置信度
- (3)类别置信度
- 4.YOLOv1的损失函数
- 5.YOLOv1的推理
- 总结
前言
对于初学者的你来说,选择适合的论文、选择通俗易懂又全面的科普文章等,具有太多的偶然性。如果迟迟没有找到合适的文章,那就不能理解什么是 YOLO 检测器,什么又是 Detection with Transformers 框架。对于小白来说,直接上手开源项目难道比较大,而且网上直接带你上手的 YOLO 项目很多,虽然能明白一套训练流程和推理流程,但对于一些 YOLO 模型理论、损失函数和整体框架逻辑显得茫然不知,因此,这期文章我会一步一步带你了解 YOLO 目标检测理论,让你快速上手 YOLO。
一、目标检测理论
这里又有同学问什么是目标检测啊?别着急,接下来会带你理解什么是目标检测。首先,你要了解目标检测发展史吧;其次,需要理解一些主流框架;最后,了解它的一些经典工作。
1.目标检测发展史
在深度学习时代到来之前,目标检测的研究大致可以分为两个主要阶段。
第一个阶段是基于传统计算机视觉方法:
- 首先,通过区域选择方法,目前比较常用的就是滑动窗口的方法,通过使用不同尺度的 Anchor Box,根据图像的颜色、纹理、边缘等信息对整幅图像进行遍历选出大量的候选区域。
- 其次,将这些视觉特征输入到 HOG 特征提取中,还有其他 HAAR、SIFT、SURF、ORB 等特征提取方法,这里就不解释太久远的方法了,大家只要知道有这些方法就好了。
- 最后,通过分类器(如支持向量机、 Haar 分类器、DPM等) 输出预测的结果
小总结:对于传统的方法来说,要设计一个能够识别多种复杂物体的通用目标检测器,难度则大得多,这种难度的核心原因在于,我们难以用一套精确的语言或数学公式来定义世间万物。显然,待检测的物体种类越多,模型需要学习的特征也就越复杂,仅靠手工进行标记方法已经难以应对这一需求。因此,研究界大佬开始需求新的方法,下面开始详解第二个阶段方法。
第二个阶段是深度学习时代的到来:
-
两阶段(two-stage)目标检测算法:
直到2014年,R-CNN 由 Ross Girshick 等人提出的,标志着目标检测领域的一次重要突破。从整体上来看,R-CNN 的思路是先使用选择性搜索(Selective Search)算法,从图像中生成多个候选区域(Region Proposals,即感兴趣区域框),然后对这些候选区域进行裁剪,并将它们调整为固定大小的图像块,然后,使用一个卷积神经网络(convolutional neuralnetwork,CNN)分别处理每一个感兴趣区域(ROI),提取特征;最后,通过支持向量机(SVM)对这些特征进行分类,判断这些区域中是否包含目标对象,同时使用回归方法进一步调整边界框的位置。R-CNN 检测流程如下:
通常搜索算法会先给出约 2000 个候选区域,之后卷积神经网络对每个候选区域提取出相应的特征,显然,这一过程会十分耗时,因为 R-CNN需要对每个候选区域单独执行卷积神经网络的特征提取,导致计算量巨大且处理效率低。为了解决这一问题,在 R-CNN 工作的基础上,先后诞生了 Fast R-CNN 和 Faster R-CNN 。Fast R-CNN(2015 年提出)通过对 R-CNN 的过程进行优化,将候选区域的特征提取与分类过程结合起来,从而加快了检测速度。具体来说,Fast R-CNN 不再对每个候选区域单独进行卷积运算,而是对整张图像进行一次卷积操作后,利用区域建议网络(RoI Pooling)提取每个候选区域。而Faster RCNN 提出了候选区域网络(RPN)完成候选区域提取过程,Faster RCNN 相当于 Fast RCNN 和 RPN 的组合。R-CNN、Fast R-CNN、Faster RCNN 都是“先提取,后识别”的检测范式,简称两阶段(two-stage)目标检测算法,即先提取出可能包含目标的区域,再依次对每个区域进行识别,最后经过处理得到最终的检测结果。R-CNN、Fast R-CNN、Faster RCNN 检测流程图如下所示:
- 单阶段(one–stage)目标检测算法
而在 2015 年,另一个革命性的工作——YOLO(You Only Look Once) 由 Joseph Redmon 等人提出。与 R-CNN 系列的分阶段处理方式不同,YOLO 采用了全新的思路,将目标检测问题转化为一个端到端的回归问题,简单来说就是,提取候选区域(定位)和逐一识别(分类)完全可以由一个单独的网络同时完成,无须分成两个阶段,从而显著提升了检测速度,这也是为什么 YOLO 能在实时应用场景中表现出色的关键原因之一。大家感兴趣可以去看一下 YOLOv1 论文, 点击即可跳转,YOLOv1论文,YOLOv1 检测流程如下图:
显然,YOLO 直接通过一次前向传播同时预测目标的位置和类别标签,简称单阶段(one–stage)目标检测算法。YOLO 解决了以往目标检测算法在速度和精度之间的平衡问题,尤其是在需要实时检测的应用场景(如无人驾驶、安防监控、视频分析等)中,YOLO 表现出了巨大的潜力。因此在当年迅速走红,被广泛应用于工业界和研究领域。
小总结:通常来说,两阶段框架往往具备较高的检测精度,但速度较慢;相对的,单阶段框架则以较快的检测速度为优势,但精度通常稍逊。在许多计算机视觉任务中,精度和速度常常是互相制约的,也激励着研究界的大佬去探索和设计能够在二者之间找一个较为平衡的解决方案。随着研究的深入和技术的进步,现代的单阶段检测框架逐渐突破了这一限制,成功在精度与速度两方面都取得了显著的提升,实现了出色的平衡。
2.目标检测框架理论基础
从深度学习时代开始,目标检测网络的框架逐渐被确定,典型的目标检测网络通常可以分为三大部分:主干网络(Backbone Network)、颈部网络(Neck Network)和检测头(Detection Head)。这三部分共同协作,完成从特征提取、特征融合到目标检测的整个流程。
- 主干网络(Backbone Network):
主干网络是目标检测网络的核心部分,负责从输入图像中提取特征。主干网络通常基于卷积神经网络(CNN),如 VGG、ResNet、MobileNet 等,通过多层卷积、池化等操作,从低级到高级提取图像的特征,形成多尺度特征图。较深的层次能捕捉图像的抽象特征,而浅层则保留更多的空间细节信息。主干网络的选择对检测性能(包括速度和精度)有重要影响,因此许多目标检测方法都会根据实际应用需求选择不同的主干网络。简单来说,主干网络作用就是提取输入图像中的高级特征,减少图像中的冗余信息,以便于后续的网络去做深入的处理 - 颈部网络(Neck Network):
颈部网络是连接主干网络和检测头的中间层,主要用于特征融合。由于主干网络提取的特征是多尺度的,而不同尺度的特征对检测不同尺寸的目标物体有重要作用,因此颈部网络的主要任务是对这些不同尺度的特征进行融合与加强。常见的颈部网络结构包括 FPN(特征金字塔网络)和 PAN(路径聚合网络)。FPN 通过自顶向下的特征金字塔结构增强小目标的检测能力,而 PAN 则通过自底向上的路径聚合网络增强大目标的检测效果。除此之外还有很多单独的、可即插即用的模块,如 RFB、ASPP 和 YOLOv4 所使用的 SPP 模块等,这些模块都可以添加在主干网络之后,以进一步地处理和丰富特征信息,扩大模型的感受野。简单来说,颈部网络的主要作用是将由主干网络输出的特征进行二次处理。下面将详细解释常用的特征融合网络。
(1)FPN 特征金字塔:
FPN 网络中的不同大小的特征图所包含的信息是不一样的,即浅层特征图包含更多的位置信息,且分辨率较高,感受野较小,便于检测小物体;而深层特征图包含更多的语义信息,且分辨率较低,感受野较大,便于检测大物体。因此,FPN 设计了一种自顶向下的融合方式,将深层的特征不断融合到浅层特征中,通过将浅层与深层的信息进行融合,可以有效地提升网络对不同尺度物体的检测性能。网络结构如下图:
(2)SPP 空间金字塔池化模块:
在目标检测中,由 YOLOv3 作者设计的 SPP 结构,包含 4 条并行的分支,且每条分支用了不同大小的池化核。SPP主要是通过在特征图上应用多种不同尺度的池化窗口(如,1x1、5x5、9x9 和 13x13 等),然后将不同尺度的池化结果进行拼接,形成一个更加丰富的特征向量,能够同时获取到小物体的细节信息和大物体的全局信息。SPP 性价比比较高,我们可以看到在YOLOv4、YOLOv5、YOLOv6、YOLOv7、YOLOv8、和 YOLOv10 工作中广泛应用,需要注意的是,在YOLOv5-6.0版本以后,以及目前流行的 YOLOv8 和最新的 YOLOv10 中采用的是 SPPF 结构。 SPPF 是对 SPP 的优化版本,最早在 YOLOv5 中引入。SPPF 的目标是简化 SPP 的多尺度池化过程,在保持相似特征提取能力的同时,加快计算速度,减少计算成本。SPPF 通过递归使用 3x3 池化窗口,模拟多尺度特征提取,极大提高了计算速度和效率,适合对实时性要求较高的任务。而 SPP 使用多个不同尺度的池化窗口,能够捕捉多尺度特征,但池化次数较多,计算开销稍大。SPP 网络结构如下所示:
- 检测头(Detection Head):
检测头是目标检测网络的最后一部分,负责对主干网络和颈部网络输出的特征进行目标类别的分类和边界框的定位。在 two-stage 方法(如 Faster R-CNN)中,检测头首先生成候选区域,再对这些候选区域进行精细的分类和边界框回归;而在 one-stage 方法(如 YOLO 和 SSD)中,检测头直接从特征图上生成目标的类别和边界框。简单来说,检测头也被称为解码器(Decoder),其核心任务是将主干网络和颈部网络提取并融合的特征转换为具体的目标检测结果,即目标类别的分类和边界框的定位。通常,检测头的设计相对简单,例如 RetinaNet 采用了“解耦”结构的检测头,这是当前目标检测网络中较为常用的结构设计。所谓“解耦”结构,它将定位和分类这两个任务分开进行,每个任务由一条独立的分支来处理。RetinaNet的网络结构如下图所示:
3.本章小结
通过了解目标检测发展史,和目前主流的目标检测网络结构组成由主干网络、颈部网络、检测头。重点YOLO目标检测架构是非常重要的,市面上很多改进都是从这三部分出发,提出各种修改。接下来,我会继续带领大家学习 YOLOv1 框架理论 ,弄明白这些,那么学习 YOLOv5、YOLOv7、YOLOv8、YOLOv9、YOLOv10 简直湿湿碎(普通话翻译就是小事一桩)。
专栏地址->YOLOv8在主干网络、Neck网络、检测头等改进大家可以参考我写的专栏,点击可跳转订阅专栏!
专栏地址->YOLOv9在主干网络、Neck网络、检测头等改进大家可以参考我写的专栏,点击可跳转订阅专栏!
专栏地址->YOLOv10在主干网络、Neck网络、检测头等改进可以参考我写的专栏,点击可跳转订阅专栏!
二、YOLOv1理论知识
YOLOv1 作为 YOLO 系列的开山之祖,它也是最早的一阶段目标检测算法。YOLOv1 设计之处有相对其它算法极大优势,算法思想是将一整张目标图像输入神经网络,卷积层用卷积计算,然后直接进入输出层对 Bounding-box 位置进行运算,并在此过程进行类别的分类回归运算。与传统的二阶段目标检测算法不同它没有候选框阶段,会直接将目标检测问题转变为相对更加简单的回归问题。YOLOv1 的独特性引起众多码农关注,从此之后各类 one-stage 框架纷纷被提出,不断迭代更新,推动了这一新框架的持续优化,使其逐渐成为目标检测领域的主流,所以说 YOLOv1 在当时目标检测算法背景下,打开了新世界。接下来会详细讲解 YOLOv1 框架理论。
1.YOLOv1网络结构
YOLOv1 主干网络结构是模仿 GoogLeNet 网络结构,网络有24个卷积层,随后是2个全连接层,但没有采用 GoogLeNet 的 Inception 模块,YOLOv1 仅使用1×1的降维卷积层,接着是3×3的卷积层。YOLOv1网络结构如图下图所示:
在 YOLO 的年代,典型的图像分类网络会将卷积层的输出特征图展平(flatten)成一维特征向量,再通过全连接层进行分类。YOLOv1也是如此,YOLOv1 在最后的卷积层之后,特征图尺寸为 7×7×1024,这部分特征图通过全连接层后转变为 4096 维的向量,最终连接一层输出层。YOLOv1 输出特征图计算公式如下:
F ∈ R H o × W o × C o F \in \mathbb{R}^{H_o \times W_o \times C_o} F∈RHo×Wo×Co
其中:
- F 表示特征图
- R H o × W o × C o {R}^{H_o \times W_o \times C_o} RHo×Wo×Co表示特征图是一个实数空间的三维张量
- Ho 表示特征图的高度(Height)。
- Wo 表示特征图的宽度(Width)。
- Co 表示特征图的通道数(Channels)
可以看到 YOLOv1 输出层是一个三维向量,因为考虑到目标检测是一个空间任务,YOLOv1 又将这个特征维度转换为一个三维矩阵 Y ∈ R 7 × 7 × 30 Y \in \mathbb{R}^{7 \times 7 \times 30} Y∈R7×7×30,其中,7×7是三维矩阵的空间尺寸,30 是该三维矩阵的通道数。我们经常听到 张量 (tensor) 这一词,三维及三维以上数据结构通常被称为张量。
模型参数量也是需要知道的,计算参数量时,需要考虑两个部分:
- 权重参数:每个神经元连接到展平后的每个输入单元,因此权重的数量是展平后向量长度乘以神经元数量。
- 偏置参数:每个神经元都有一个对应的偏置值。
如果特征图尺寸为 7×7×1024,展平后的向量长度为 7×7×1024=50176,全连接层中的每个神经元都与展平后的输入向量的每一个单元相连。因此,权重的参数量等于展平后的输入向量长度乘以神经元的数量。如果全连接层有 4096 个神经元,则权重参数的数量为 50176×4096=205,520,896。每个神经元都有一个对应的偏置,因此偏置参数的数量等于全连接层中的神经元数量。对于 4096 个神经元,全连接层的偏置参数量为 4096。所以全连接层的总参数量为权重参数加上偏置参数,即 :
可以看出仅这一层的参数量就已经非常庞大,也不一定代表 YOLOv1 推理速度会很慢,但是如此多的参数肯定占用大量存储空间,这也是 YOLOv1 的缺点。
YOLOv1 在 PASCAL VOC 数据集上的性能,与其他检测模型的对比情况,包括训练数据、mAP(mean Average Precision,平均精度)以及帧率(FPS,Frames Per Second),如下表格:
- mAP(mean Average Precision)的计算思路:首先计算每个类别的 AP(Average Precision,平均精度),然后将所有类别的 AP 取平均,得到最终的 mAP 值。AP的计算通常是根据模型在不同置信度阈值下的精度-召回率曲线来进行积分。
- FPS(Frames Per Second,帧率)表示模型每秒可以处理的多少张图像,如果模型处理一张图像的时间为 t 秒,那么 FPS 就是 1 t \frac{1}{t} t1 。例如,如果模型处理一张图像需要 0.01 秒,那么它的 FPS 就是 100。
2.YOLOv1检测原理
从 YOLOv1 网络结构看,网络接收一张尺寸为 448×448×3 的图像作为输入,经过网络的下采样操作,输出的特征图尺寸被降采样了 64 倍,即从 448×448 降为 7×7,我们知道特征图计算公式为 F ∈ R H o × W o × C o F \in \mathbb{R}^{H_o \times W_o \times C_o} F∈RHo×Wo×Co,Co为特征图的通道数即 1024(YOLOv1 设置的),那么特征图的高度 Ho 和宽度 Wo 与原始图片的高度 H 和宽度 W 之间的关系可以表示为:
H o = H s t r i d e , W o = W s t r i d e {\ H}_{o}=\frac{{\ H}}{s t r i d e},\quad W_{o}=\frac{\mathcal{W}}{s t r i d e} Ho=stride H,Wo=strideW
其中,stride 是网络的输出步长,其值通常等于网络的降采样倍数。
之后,特征图 F 经过若干全连接层处理以及一些必要的维度转换的操作后,最终输出 7×7×30 的立方体,这里 7×7 可以想象成一个网格,每个网格都是一个特征维度为30 的向量。
YOLOv1的输入和输出如下图所示:
上图将输入图像划分为一个 S×S 的网格,在每一个网格这个长度为 30 的向量都包含了两个边界框的参数以及总数为20的类别数量。每个网格单元预测边界框和这些边界框的置信度分数。置信度分数反映了模型对边界框包含物体的信心,以及模型认为边界框预测准确的程度。每个边界框由 5 个预测值组成:x, y, w, h和置信度。其中,(x, y)表示边界框中心相对于网格单元的坐标。宽度和高度相对于整个图像进行预测。最后,置信度表示预测框与真实框的IOU。
简单来说,YOLOv1的核心检测思想:逐个网格找物体。YOLOv1 的“网格划分”思想如下图所示
具体来说,YOLOv1 的主干网络将原始图像转化为特征图,特征图的每个网格单元都包含长度为 1024 的特征向量,该特征向量包含了该网格处的某种高级特征信息。YOLOv1 遍历所有网格,处理每个网格的特征信息,预测该网格内是否有物体的中心点坐标及对应的类别信息。每个网格单元还输出多个边界框及其置信度,每个边界框由 5 个参数(置信度和边界框位置参数)表示,因此每个网格总共会输出5B+Nc 个预测参数。B 表示每个网格单元所预测的 边界框。YOLOv1 中每个网格预测有 2 个边界框,每个边界框有 5 个参数,分别是:
- x:边界框中心的横坐标(相对于网格单元的偏移)
- y:边界框中心的纵坐标
- w:边界框的宽度
- h:边界框的高度
- 置信度:预测该框内有物体的置信度。
Nc表示类别的数量,在 PASCAL VOC 数据集上使用 20 个类别,所以 5B+Nc=30,这个 30 就是这样计算的。随着人工智能的发展,YOLOv1 的这种检测思路逐渐演变为后来的 “anchor-based” 方法,其中每个网格单元相当于一个 “anchor”。
3.YOLOv1的训练流程
(1)边界框的位置参数
在 YOLOv1 中,由于目标检测的原理是通过网格单元检测图像中的目标中心点,因此,只有目标中心点位于某个网格的情况下,才会认为该网格单元包含物体。为此,YOLOv1 引入了 “objectness” 概念,用来表示该网格是否包含物体。若该网格包含目标物体,objectness 的值为 1;若没有物体,objectness 的值为 0。这个标志帮助模型区分哪些网格单元需要进一步处理,以预测物体的类别和边界框。
如下图为 YOLOv1 中正样本候选区域的示意图。带颜色的网格单元表明该网格有物体,也就是图中的每个物体的边界框中心点(图中的黄、蓝、粉点)落在了这个网格内。在训练过程中,该网格内所要预测的边界框,其置信度会尽可能接近1。而对于其他没有物体的网格,其边界框的置信度就会尽可能接近0。黄色框、蓝色框、粉色框表示模型为不同物体(自行车、狗、汽车)生成的边界框。只有物体的中心点所在的网格单元才被认为是“正样本”,也就是说,在训练过程中,训练的正样本只会从此网格处的预测中得到,而其他区域的预测都是该目标的负样本。
从上面图中,目标的中心点通常并不会完全位于网格单元的正中央,而是相对于该网格的四边存在一定的偏移量。这是因为物体在图像中的位置是连续的,而网格是离散的划分,因此物体的中心点在其所属网格内可以有不同的偏移位置,这是网格划分必然的结果。在YOLOv1中,虽然每个网格负责预测其范围内物体的中心点,但仅靠网格的位置信息无法准确描述物体在图像中的精确位置。为了解决这个问题,YOLOv1通过网络训练,学习每个网格单元内物体中心点的偏移量。这个偏移量帮助模型对物体进行更加精确的定位。那怎么计算偏移量呢?
首先,对于给定的边界框,其左上角点的坐标可以记作 (xmin,ymin),表示边界框在图像中的左上角位置。与此同时,边界框的右下角点坐标可以记作 (xmax,ymax),表示该框的另一端的坐标,那么可以计算边界框的中心点,公式如下:
x c e n t e r = x m i n + x m a x 2 y c e n t e r = y m i n + y m a x 2 \begin{array}{c}{{x_{\mathrm{center}}=\frac{x_{\mathrm{min}}+x_{\mathrm{max}}}{2}}}\\ {{y_{\mathrm{center}}=\frac{y_{\mathrm{min}}+y_{\mathrm{max}}}{2}}}\end{array} xcenter=2xmin+xmaxycenter=2ymin+ymax
假设网格的步长为 stride,则中心点所在的网格坐标(grid 坐标)可以通过以下公式计算得到:
g r i d x = ∣ x c e n t e r s t r i d e ∣ g r i d y = ∣ y c e n t e r s t r i d e ∣ \begin{array}{r}{{\mathrm{grid}_{x}=\left|{\frac{x_{\mathrm{center}}}{\mathrm{stride}}}\right|}}\\ {{\mathrm{grid}_{y}=\left|{\frac{y_{\mathrm{center}}}{\mathrm{stride}}}\right|}}\end{array} gridx= stridexcenter gridy= strideycenter
那么这个中心点偏移量就可以被计算出来,YOLOv1 的 stride 为 64:
t x = x c e n t e r s t r i d e − g r i d x t y = y c e n t e r s t a t − g r i d y \begin{array}{c}{{t_{x}=\frac{x_{\mathrm{center}}}{\mathrm{stride}}-\mathrm{grid}_{x}}}\\ {{t_{y}=\frac{y_{\mathrm{center}}}{\mathrm{stat}}-\mathrm{grid}_{y}}}\end{array} tx=stridexcenter−gridxty=statycenter−gridy
YOLOv1 的核心思想之一,即在逐网格进行目标检测的基础上,使用偏移量提高目标定位的精度,为此网格处的正样本的学习标签。如下图更好解释中心点的偏移量。
在推理阶段,YOLOv1 是通过对偏移量公式进行逆运算来计算物体的最终中心点坐标,计算公式如下:
x c e n t e r = ( g r i d x + t x ) × s t r i d e y c e n t e r = ( g r i d y + t y ) × s t r i d e \begin{array}{c}{{x_{\mathrm{center}}=\left({\mathrm{grid}_{x}+t_{x}}\right)\times{\mathrm{stride}}}}\\ {{y_{\mathrm{center}}=\left({\mathrm{grid}}_{y}+t_{y}\right)\times{\mathrm{stride}}}}\end{array} xcenter=(gridx+tx)×strideycenter=(gridy+ty)×stride
归根到底就是,在训练阶段,YOLOv1 学习到的是物体中心点相对于网格左上角的偏移量 tx 和 ty,并且这些值是归一化到 0 和 1 之间的相对值。在推理阶段,模型通过这些预测的偏移量,结合网格的绝对位置和步长 stride,逆向推导出物体的 绝对中心点坐标。
为了应对边界框宽度和高度较大的问题,YOLOv1 采用了归一化处理。边界框的宽和高通常是相对于整个图像来说的,因此其数值相对较大。如果直接将这些值作为模型的回归目标,可能会导致训练过程中的数值不稳定,尤其是在损失函数中,过大的损失值可能导致发散问题。
w ˉ = w W h ˉ = h H \bar{w}=\frac{w}{W}\\ \bar{h}=\frac{h}{H} wˉ=Wwhˉ=Hh
其中
- w 和 h 分别表示物体的真实边界框的宽度和高度。
- W 和 H 分别表示输入图像的宽度和高度。
归一化的值都在 0 到 1 之间,这有助于模型在训练时保持数值稳定,避免因边界框尺寸过大导致损失函数不平衡或训练发散。
(2)边界框的置信度
那么如何让网络确定中心点的位置?为了让网络确定中心点的位置以及学习边界框的置信度,YOLOv1 通过在训练过程中定义一个 置信度损失 来优化这个部分。置信度是一个关键的预测值,它直接决定了一个网格是否包含目标的中心点。下图展示 IOU 计算原理
- 交集(Intersection):预测的边界框和真实的边界框之间的重叠区域
- 并集(Union):预测的边界框和真实边界框的联合区域(即二者的面积之和减去重叠区域的面积)
计算公式如下:
IoU = Area of Intersection Area of Union \text{IoU} = \frac{\text{Area of Intersection}}{\text{Area of Union}} IoU=Area of UnionArea of Intersection
IoU 的值范围在 0 到 1 之间,越接近 1,表示预测的边界框与真实边界框越接近,定位精度越高。于是,YOLOv1 就把预测的边界框(预测框)和目标的边界框(目标框)的 IoU 作为置信度的学习标签。
我们知道,YOLOv1 的输出包含 S×S×B 个预测边界框,但不是所有的边界框都需要关注。我们只关心那些包含目标中心点的网格。如下图,假设蓝框和绿框代表两个预测边界框,红框表示真实边界框。蓝框和绿框它们都属于正样本候选区域(即该网格包含目标的中心点),这里我们假设蓝框的 IoU 为 0.75,绿框的 IoU 为 0.6,由于蓝框预测框和真实边界框的 IoU 最大,即该预测框更加精确,因此我们就理所当然地希望这个预测框能作为正样本去学习目标的信息,即 只保留 IoU 最大的蓝框作为训练的正样本,去参与计算边界框的置信度损失、边界框的位置参数损失以及类别损失,并做反向传播。则绿框将其标记为负样本,它不参与类别损失和边界框的位置参数损失的计算,只计算边界框的置信度损失,且置信度的学习标签为 0。
可以看到:
- 无锚框技术:YOLOv1 直接预测每个网格的边界框,而不是使用基于先验框(anchor)的策略。
- IoU-aware 技术:YOLOv1 将 IoU(交并比)作为置信度评估的一部分,直接影响类别预测,提升了边界框预测的精度,既考虑是否有物体,也关注预测边界框与真实边界框的重合程度。
- 动态标签分配技术:在 YOLOv1 中,正样本的分配不是预定义的,而是根据预测框与目标框的 IoU 动态选择。这一思想后来被称为动态标签分配技术,即在训练过程中根据实际的预测结果决定哪些边界框作为正样本,从而提高模型的学习效果和适应性。
(3)类别置信度
YOLOv1 在处理类别置信度时采用了一种相对简单的方法:每个网格只预测一个目标,且只对包含目标中心点的正样本网格进行类别学习,不考虑其他网格。类别标签采用了 one-hot 编码格式,这是图像分类中常见的格式。通常,one-hot 编码格式的类别学习会使用 Softmax 函数来处理类别预测,之后通过 交叉熵损失函数计算损失。这是常见的做法,能够保证类别置信度在 0 到 1 之间。然而,YOLOv1 通过线性函数输出类别置信度,使用 L2 损失来计算每个类别的损失。
大家可以通过标注工具来制作数据集正样本,并且把数据集进行归一化操作,训练流程了解后,下面将介绍 YOLOv1 的损失函数计算了。
4.YOLOv1的损失函数
损失函数的设计对于目标检测性能起着决定性作用。好的损失函数设计能在边界框定位、置信度预测、类别分类之间找到平衡,使模型在速度和精度上都表现出色。如果损失函数设计不合理,可能会导致边界框不准确、置信度预测错误或类别混淆,从而影响模型的整体表现。因此,损失函数的设计直接关系到模型在实际应用中的效果。
在 YOLOv1 中,损失函数是用来优化模型的核心组件,它考虑了 定位损失、置信度损失 和 分类损失。YOLOv1 的损失函数由三部分组成,分别对应边界框位置的误差、物体置信度的误差以及物体类别的误差。YOLOv1 总的损失函数计算公式如下:
其中:
- S×S 表示将图像划分的网格数(例如 7×7)
- B 是每个网格单元预测的边界框数量(在 YOLOv1 中 B=2)。
- x^i ,y^i 和 xi,yi 表示预测和真实的边界框中心位置。
- w^i, h^i 和 wi,hi 是预测和真实的边界框宽度和高度。
- C^i 和 Ci 是预测和真实的置信度。
- p^i(c) 和 pi(c)是预测和真实的类别概率。
- 1 i j o b j \mathbf{1}_{i j}^{\mathrm{{obj}}} 1ijobj 是指示函数,表示网格单元 ii 的第 jj 个边界框是否包含物体(如果有物体为1,否则为0)。
- 1 i j n o o b j \mathsf{1}_{i j}^{\mathrm{noobj}} 1ijnoobj 是指示函数,表示网格单元中没有物体。
- λcoord 用于增加定位误差的权重,防止分类误差主导损失(论文中使用 λcoord=5)。
- λnoobj 用于降低无物体的置信度误差的权重,避免大量负样本的影响(论文中使用 λnoobj=0.5)。
5.YOLOv1的推理
YOLOv1训练完成之后,当输入一张图像之后,模型会为每个网格单元输出边界框和类别概率,输出太多框显然不是我们想要的结果。为此,模型预测之后需要进一步筛选和过滤。通常可以通过以下 4 个步骤来筛选最终的检测结果:
-
计算所有预测边界框的得分:
使用边界框的置信度分数和类别概率计算每个边界框的最终得分(score)。得分是边界框置信度和类别概率的乘积,反映了该边界框包含特定物体的可能性。
-
得分阈值筛选:
计算了所有边界框的得分后,设置一个得分阈值,过滤掉得分低于该阈值的边界框。通常,这个阈值可以设置为 0.3,确保只保留置信度较高的预测结果。如下图所示
-
计算边界框的中心点坐标及宽高:
筛选完后,计算每个边界框的中心点位置 (x,y) 和边界框的宽 w和高 h。这些参数用于进一步确定物体的准确位置。
-
使用非极大值抑制(NMS)进行第二次筛选:
由于 YOLOv1 可能对同一个目标给出多个得分较高的边界框。因此通过非极大值抑制(NMS)过滤重叠的边界框,保留得分最高的边界框。NMS 会根据边界框之间的 IOU(交并比)来去除重叠较大的框,确保每个物体只保留一个边界框。NMS具体步骤如下:
-
选择得分最高的边界框:对于某个类别的所有边界框,首先选取置信度得分最高的边界框作为最有可能正确的检测结果。
-
计算IOU:然后,计算其他边界框与这个得分最高的边界框的交并比(IOU)。
-
剔除重复检测:如果其他边界框的 IOU 值超过设定的阈值,则认为该边界框是重复检测,予以剔除。
-
循环处理:对所有类别的边界框都依次进行这一过程,直到所有的边界框都被筛选完毕。最终只保留置信度最高且非重复的检测结果。
非极大值抑制处理结果如下图所示:
-
总结
创作不易,对你有帮助的话,请帮忙点一个爱心,谢谢!关注我,带你不挂科!
相关文章:

YOLO目标检测理论详解,YOLOv1理论知识讲解,超w字精读(学习YOLO框架必备),全网最详细教程
文章目录 前言一、目标检测理论1.目标检测发展史2.目标检测框架理论基础3.本章小结 二、YOLOv1理论知识1.YOLOv1网络结构2.YOLOv1检测原理3.YOLOv1的训练流程(1)边界框的位置参数(2)边界框的置信度(3)类别置…...

SpringBoot3.x和OCR构建车牌识别系统
本专题旨在展示 OCR 技术与 SpringBoot3.x 框架结合的广泛应用。我们会深入探讨它在医疗、金融、教育、交通、零售、公安等多个领域的现实应用。每个应用场景都会提供详细的实例、面临问题的分析与解决策略,以帮助您深入理解 OCR 技术在实践中的关键作用。让我们一同…...
conda 容器学习笔记之一 -- 基础环境配置
1、容器瘦身导致部分应用缺少,需要在非容器环境下部署环境。但为避免破坏现有环境,现有使用conda环境进行隔离管理 创建:conda create -n tts python3.10.0 2、conda 是python环境管理,和python无关的东西比如cann还是会影响 下载…...
Oracle分区表改造(三):通过分区交换和分裂改造为分区表
Oracle分区表改造(三):通过分区交换和分裂改造为分区表 源表数据准备范围分区表改造:非间隔分区创建普通分区表分区交换分区分裂范围分区表改造:间隔分区创建间隔分区表分区交换分区分裂表重命名🐬 创建只有一个分区的分区表, 通过分区交换将原表变成分区表,然后分裂分…...

LeetCode 0908.最小差值 I:思维(遍历)
【LetMeFly】908.最小差值 I:思维(遍历) 力扣题目链接:https://leetcode.cn/problems/smallest-range-i/ 给你一个整数数组 nums,和一个整数 k 。 在一个操作中,您可以选择 0 < i < nums.length 的…...
Python基础之循环语句
在Python的编程世界里,循环结构犹如一把神奇的钥匙,开启高效处理数据和重复执行任务的大门。它赋予程序员强大的力量,让代码充满活力。Python主要有两种类型的循环语句:for循环和while循环。 一、for循环 for循环通常用于遍历一个…...

项目管理软件真的能让敏捷开发变得更简单吗?
敏捷开发是一种以快速交付和适应变化为核心特点的软件开发方法。其特点包括尽早并持续交付、能够驾驭需求变化、版本周期内尽量不加任务、业务与开发协同工作、以人为核心、团队配置敏捷等。 例如,尽早并持续交付可使用的软件,使客户能够更早地体验产品…...
互联网名称之时间戳
什么是时间戳 时间戳(Timestamp)是一种用于表示特定时刻的数值或字符串,通常以日期和时间的形式出现。它用于记录某一事件发生的准确时间,在计算机系统中常被用于日志记录、数据处理和同步等场景。 常见的时间戳 在互联网中常见…...

Leetcode—1242. 多线程网页爬虫【中等】Plus(多线程)
2024每日刷题(187) Leetcode—1242. 多线程网页爬虫 实现代码 /*** // This is the HtmlParsers API interface.* // You should not implement it, or speculate about its implementation* class HtmlParser {* public:* vector<string>…...

RISC-V笔记——内存模型总结
1 前言 Memory consistency model定义了使用Shared memory(共享内存)执行多线程(Multithread)程序所允许的行为规范。RISC-V使用的内存模型是RVWMO(RISC-V Weak Memory Ordering),RVWMO内存模型是根据全局内存顺序(global memory order)定义的,全局内存…...

后端常用安全措施
一、限流 1.简介 限流就是限制流量,但这里的流量是一个比较笼统的概念。如果考虑各种不同的场景,限流是非常复杂的,而且和具体的业务规则密切相关 通过限流,可以控制服务请求的速率,从而提高系统应对突发大流量的能…...

虚拟机数据恢复—通过拼接数据库页碎片的方式恢复数据库的数据恢复案例
虚拟机数据恢复环境: 某品牌服务器通过同品牌某型号的RAID卡,将4块STAT硬盘为一组RAID10阵列。上层部署XenServer虚拟化平台,虚拟机安装Windows Server系统,每台虚拟机有两个虚拟机磁盘(系统盘 数据盘)&am…...

【vue】自封组件,基于vue2封装一个弹框组件
源码:https://download.csdn.net/download/galaxyJING/89913551...
ES6基础知识
一、定义变量的关键字let和const 1. let 定义变量的语法: let 变量名 值; 2. 和var定义变量的区别 1. 是否支持同一个作用域变量同名 var支持,let不支持 2. 是否支持预解析 var支持,let不支持 3. 是否会挂载在window对象…...

基于Multisim的模拟拔河游戏比赛设计与仿真
1.设计一个模拟拔河游戏比赛的逻辑电路 2.使用15个发光二极管表示绳子,开机后只有最中间的发光二极管亮。 3.比赛双方各持一个按钮,快速不断地按动按钮,产生脉冲,谁按的快,发光的二极管就向谁的方向移动,每…...
MyBatis 配置详解
在项目中经常会用到 mybatis 相关的一些配置,而在启动类项目工程中,一般会把 mybatis 配置文件单独写到 mybatis,yml 中,如下简单介绍下常用的 mybatis 配置 mybatis:configuration:call-setters-on-nulls: truemap-underscore-to-camel-case…...

研发运营一体化(DevOps)能力成熟度模型
目录 应用设计 安全风险管理 技术运 持续交付 敏捷开发管理 基于微服务的端到端持续交付流水线案例 应用设计 安全风险管理 技术运 持续交付...
躺平成长-利用kimi编辑助手帮助自己编程第二天
天有道,无常道,兵无常势。 {今天开始听歌(歌曲:青丝!)进行编程!} 尝试用ai帮助自己进行小程序的开发,同时最为关键,是无法能够完成相关的代码的记忆,所以我开…...
OpenSuse-搭建NFS-Server
在OpenSUSE上搭建NFS服务可以通过以下步骤完成: ### 1. 安装NFS服务器软件 首先,确保你已经安装了NFS服务器软件包。你可以使用zypper命令来安装: sudo zypper install nfs-kernel-server### 2. 配置NFS导出目录 编辑/etc/exports文件&#x…...

【数据结构与算法】之二分查找
二分查找(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它通过比较数组中间元素与目标值来工作,从而将搜索范围缩小到一半,也称折半查找,是一种非常高效的工作于有序数组的查找算法。本文主要介绍二分查找…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...