Reading

Yolo系列

  • YOLO的核心思想就是利用整张图作为网络的输入,直接在输出层回归bounding box的位置和bounding box所属的类别。
Our system divides the input image into a S × S grid. If the center of an object falls into a grid cell, that grid cell is responsible for detecting that object.
  • faster RCNN中也直接用整张图作为输入,但是faster-RCNN整体还是采用了RCNN那种 proposal+classifier的思想,只不过是将提取proposal的步骤放在CNN中实现了,而YOLO则采用直接回归的思路。

YOLO v1

将一幅图像分成SxS个网格(grid cell),如果某个object的中心 落在这个网格中,则这个网格就负责预测这个object。

image

每个网格要预测B个bounding box,每个bounding box除了要回归自身的位置之外,还要附带预测一个confidence值。 这个confidence代表了所预测的box中含有object的置信度和这个box预测的有多准两重信息,其值是这样计算的: \(Pr(Object)*IOU_{pred}^{trith}\) ,其中,如果有object落在一个grid cell里,第一项取1,否则取0。 第二项是预测的bounding box和实际的groundtruth之间的IoU值。

每个bounding box要预测(x, y, w, h)和confidence共5个值,每个网格还要预测一个类别信息,记为C类。则SxS个网格,每个网格要预测B个bounding box还要预测C个categories。输出就是\(S \times S \times (5B+C)\)的一个tensor。 注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。

举例说明: 在PASCAL VOC中,图像输入为\(448\times 448\),取\(S=7\)\(B=2\),一共有20个类别(\(C=20\))。则输出就是\(7\times 7\times 30\)的一个tensor。 整个网络结
构如下图所示:

image

在test的时候,每个网格预测的class信息和bounding box预测的confidence信息相乘,就得到每个bounding box的class-specific confidence score:

\[Pr(Class_i|Object)*Pr(Object)*IOU_{pred}^{truth}=Pr(Class_i)*IOU_{pred}^{truth}\]

等式左边第一项就是每个网格预测的类别信息,第二三项就是每个bounding box预测confidence。这个乘积即encode了预测的box属于某一类的概率,也有该box准确度的信息。

得到每个box的class-specific confidence score以后,设置阈值,滤掉得分低的boxes,对保留的boxes进行NMS处理,就得到最终的检测结果。

注:由于输出层为全连接层,因此在检测时,YOLO训练模型只支持与训练图像相同的输入分辨率。

虽然每个格子可以预测B个bounding box,但是最终只选择只选择IOU最高的bounding box作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或⻦群时,每个格子包含多个物体,但却只能检测出其中一个。这是YOLO方法的一个缺陷。

损失函数

损失函数有四部分组成,

image

上文中的红圈符号表示是否开关,比如第一个符号表示i号格子j号坐标框中如果含有obj则为1,否则为0。

损失函数第一部分的宽高计算加根号,这是因为:一个同样将一个100x100的目标与一个10x10的目标都预测大了10个像素,预测框为110 x 110与20 x 20。显然第一种情况我们还可以稍微接受,但第二种情况相当于把边界框预测大了一倍,但如果不使用根号函数,那么损失相
同,都为200,如果使用根号则可以表示出两者的差异。

\(C_i\)表示第i个框含有物体的置信度,类似于RCNN中的二分类部分思想,由于大部分框中没有物体,为平衡损失函数,本部分的权取小为0.5, \(\hat{p}_i(c)\)中c为正确类别则值为1,否则为0

正负样例

正样本:

  1. 对象中心落在网格内:对于每个真实对象(ground truth object),其边界框(bounding box)的中心落在哪个网格单元内,那个网格单元就负责预测这个对象。因此,该网格单元和与之对应的预测边界框成为“正样本”
  2. 存在性置信度:与该网格相关联的“对象存在的置信度”应该接近1
  3. 类别标签:该网格单元还需要预测该对象的类别
    负样本:
  4. 对象中心不落在网格内:如果一个网格单元内没有任何真实对象(ground truth object)的中心,那么该网格单元就是一个“负样本”
  5. 存在性置信度:与这些负样本网格相关联的“对象存在的置信度”接近0

优缺点

优点:

  1. 速度:最显著的优点是速度
  2. 全局信息:由于YOLO在整个图像上进行推断,而不是在局部区域进行,因此它能更好地利用全局上下文信息
  3. 多尺度检测:虽然初版的YOLO主要用于固定尺度的检测,但其架构灵活地支持多尺度检测
  4. 迁移泛化能力强
  5. 实时应用:由于其高速和简洁性,YOLO 特别适用于实时或近实时的应用,比如自动驾驶、监控等
  6. 易于实现和部署:相对较少的组件和端到端的设计使得 YOLO 更容易实现和部署

缺点:

  1. 准确性:初版的YOLO在小目标或密集排列目标的检测方面存在一定的局限性
  2. 定位误差:由于使用了较大的网格来预测边界框,YOLOv1对目标的定位不如基于候选区域的方法准确
  3. 每个网格只检测一个类别:在 YOLOv1 的设计中,每个网格只预测一个类别和一个边界框,这限制了它在一个小区域内检测多个目标的能力
  4. 高召回率但低准确率:通常有更高的召回率(检测到更多的真实目标)但更低的准确率(更多的误检)
  5. 在YOLOv1中,其backbone先在ImageNet上进行预训练,预训练时所输入的图像尺寸是224×224,而做检测任务时,YOLOv1所接收的输入图像尺寸是448×448
  6. 分类转换成了回归
  7. 训练阶段-中心点落到那个框中就由那个框产生的预测框负责预测-逐渐拟合
  8. 因为YOLO中每个cell只预测两个bbox和一个类别,这就限制了能预测重叠或邻近物体的数量,比如说两个物体的中心点都落在这个cell中,但是这个cell只能预测一个类别
  9. 此外,不像Faster R-CNN一样预测offset,YOLO是直接预测bbox的位置的,这就增加了训练的难度
  10. YOLO是根据训练数据来预测bbox的,但是当测试数据中的物体出现了训练数据中的物体没有的长宽比时,YOLO的泛化能力低
  11. 同时经过多次下采样,使得最终得到的feature的分辨率比较低,就是得到coarse feature,这可能会影响到物体的定位
  12. 损失函数的设计存在缺陷,使得物体的定位误差有点儿大,尤其在不同尺寸大小的物体的处理上还有待加强

YOLO v2

创新点简述

  1. YOLOv2在加入BN层之后mAP上升2%
  2. Yolov1也在Image-Net预训练模型上进行fine-tune,但是预训练时网络入口为224 x 224,而fine-tune时为448 x 448,这会带来预训练网络与实际训练网络识别图像尺寸的不兼容。yolov2直接使用448 x 448的网络入口进行预训练,然后在检测任务上进行训练,效果得到3.7%的提升。
  3. YOLO一代包含有全连接层,从而能直接预测Bounding Boxes的坐标值。 Faster R-CNN的方法只用卷积层与Region ProposalNetwork来预测Anchor Box的偏移值与置信度,而不是直接预测坐标值。作者发现通过预测偏移量而不是坐标值能够简化问题,让神经网络学习起来更容易。 所以最终YOLO去掉了全连接层,使用Anchor Boxes来预测 Bounding Boxes。作者去掉了网络中一个Pooling层,这让卷积层的输出能有更高的分辨率。收缩网络让其运行在416416而不是448448。由于图片中的物体都倾向于出现在图片的中心位置,特别是那种比较大的物体,所以有一个单独位于物体中心的位置用于预测这些物体。YOLO的卷积层采用32这个值来下采样图片,所以通过选择416416用作输入尺寸最终能输出一个1313的Feature Map。 使用Anchor Box会让精确度稍微下降,但用了它能让YOLO能预测出大于一千个框,同时recall达到88%,mAP达到69.2%。
  4. 输出从v1的S × S × (B × (coordinates + width + height+ confidence )+ C),变为v2的S × S × B × (coordinates + width + height+ confidence + C)。此时S=13,B=5,且从v1的一个cell预测一个类变为了一个anchor box预测一类。这是为了解决临近物体检测效果不好问题。
  5. 通过预测偏移量而不是坐标值能够简化问题,让神经网络学习起来更容易,及anchor的设置是有其优越性的,至于每个格子中设置多少个anchor(即k等于几),作者使用了k-means算法离线对voc及coco数据集中目标的形状及尺度进行了计算。发现当k = 5时并且选取固定5比例值的时,平衡了复杂度和IOU。(引入anchors和采用k_means确定anchors的个数、形状是两个创新)
image.png
  1. 新的主干网络:模型的mAP值没有显著提升,但计算量减少了:
image.png
  1. 对细粒度特征做了加强,个人理解就是resnet的跳层
  2. YOLOv2中使用的Darknet-19网络结构中只有卷积层和池化层,所以其对输入图片的大小没有限制。YOLOv2采用多尺度输入的方式训练,在训练过程中每隔10个batches,重新随机选择输入图片的尺寸,由于Darknet-19下采样总步⻓为32,输入图片的尺寸一般选择32的倍数{320,352,...,608}。采用Multi-Scale Training, 可以适应不同大小的图片输入,当采用低分辨率的图片输入时,mAP值略有下降,但速度更快,当采用高分辨率的图片输入时,能得到较高mAP值,但速度有所下降。
  3. 本文对anchors的回归提出了更好的算法,这部分比较麻烦,贴出一篇讲解很透彻的文章。anchor的预测公式来自于Faster-RCNN,我们来看看人家是怎么写的:
\[\begin{aligned} t_{\text{x}} &= (x - x_{\text{a}}) / w_{\text{a}}, & t_{\text{y}} &= (y - y_{\text{a}}) / h_{\text{a}}, \\ t_{\text{w}} &= \log(w / w_{\text{a}}), & t_{\text{h}} &= \log(h / h_{\text{a}}), \\ t_{\text{x}}^* &= (x^* - x_{\text{a}}) / w_{\text{a}}, & t_{\text{y}}^* &= (y^* - y_{\text{a}}) / h_{\text{a}}, \\ t_{\text{w}}^* &= \log(w^* / w_{\text{a}}), & t_{\text{h}}^* &= \log(h^* / h_{\text{a}}), \end{aligned} \]

公式中,符号的含义解释一下:x 是坐标预测值,xa 是anchor坐标(预设固定值),\(x^∗\) 是坐标真实值(标注信息),其他变量 y,w,h 以此类推,t 变量是偏移量。然后把前两个公式变形,就可以得到正确的公式:

\[\begin{aligned} x=(t_x * w_a)+x_a \\ y=(t_y * w_a)+y_a \end{aligned}\]

这个公式没有任何限制,使得无论在什么位置进行预测,任何anchor boxes可以在图像中任意一点结束(我的理解是,\(t_x\)没有数值限定,可能会出现anchor检测很远的目标box的情况,效率比较低。正确做法应该是每一个anchor只负责检测周围正负一个单位以内的目标box)。模型随机初始化后,需要花很长一段时间才能稳定预测敏感的物体位置。

在此,作者就没有采用预测直接的offset的方法,而使用了预测相对于grid cell的坐标位置的办法,作者又把ground truth限制在了0到1之间,利用logistic回归函数来进行这一限制。

现在,神经网络在特征图(13 *13 )的每个cell上预测5个bounding boxes(聚类得出的值),同时每一个bounding box预测5个坐值,分别为 \(t_x,t_y,t_w,t_h,t_o\) ,其中前四个是坐标,\(t_o\)是置信度。如果这个cell距离图像左上角的边距为 \((c_x,c_y)\) 以及该cell对应box(bounding box prior)的长和宽分别为 \((p_w,p_h)\),那么预测值可以表示为

\[\begin{aligned} b_x &= \sigma(t_x) + c_x \\ b_y &= \sigma(t_y) + c_y \\ b_w &= p_w e^{t_w} \\ b_h &= p_h e^{t_h} \\ Pr(\text{object}) * IOU(b, \text{object}) &= \sigma(t_o) \end{aligned} \]

\(t_x,t_y\) 经sigmod函数处理过,取值限定在了0~1,实际意义就是使anchor只负责周围的box,有利于提升效率和网络收敛。因此,\(σ(t_x)\)是bounding box的中心相对栅格左上角的横坐标,\(σ(t_y)\)是纵坐标,\(σ(t_o)\)是bounding box的confidence score。

定位预测值被归一化后,参数就更容易得到学习,模型就更稳定。作者使用Dimension Clusters和Direct location prediction这两项anchor boxes改进方法,mAP获得了5%的提升。

image.png

除此之外,YOLO_v2的实例YOLO9000在超多类分类(9000类)也做出了实践性质的创新,感兴趣的可以看一看。

优缺点

  1. Darknet-19:YOLOv2提出了一个全新的19层网络架构(Darknet-19),用于特征提取。该网络既轻量级也高效
  2. 锚框(Anchor Boxes):使用锚框可以更准确地检测不同形状和大小的物体,改进了对高度重叠物体的检测能力
  3. 多尺度检测:通过引入多尺度检测,YOLOv2能更好地检测不同大小的物体。这极大地提高了对小目标的检测能力
  4. 速度快:YOLOv2是为实时性能优化的。只需要一次前向传播,就能完成目标的检测
  5. 联合训练(Joint Training):YOLOv2可以同时在检测和分类任务上进行训练,这提高了其泛化性能
  6. 位置敏感性和类别预测:YOLOv2对于物体位置的敏感性减小,而对于类别预测的准确性提高
  7. 对小目标的检测不佳:尽管进行了多尺度检测,YOLOv2对小目标的检测性能仍然不如一些其他算法
  8. 处理高度重叠目标的挑战:尽管引入了锚框,但在高度重叠或密集的物体情况下,检测性能仍然有待提高
  9. 位置精度较低:虽然YOLOv2在类别识别方面表现出色,但在定位物体方面的精度相对较低

YOLO v3

image

改进之处

  1. 多尺度预测 (类FPN)
  2. 更好的基础分类网络(类ResNet)和分类器 darknet-53。
  3. 分类器-类别预测 YOLOv3不使用Softmax对每个框进行分类,主要考虑因素有两个:

结构

image-20200915175032596

网络结构解析:

  1. Yolov3 中,只有卷积层,通过调节卷积步长控制输出特征图的尺寸。所以对于输入图片尺寸没有特别限制。流程图中,输入图片以 \(256 \times 256\) 作为样例。
  2. Yolov3 借鉴了金字塔特征图思想,小尺寸特征图用于检测大尺寸物体,而大尺寸特征图检测小尺寸物体。特征图的输出维度为 \(N \times N \times [3 \times (4 + 1 + 80)]\)\(N \times N\) 为输出特征图格点数,一共 3 个 Anchor 框,每个框有 4 维预测框数值 \(t_x, t_y, t_w, t_h\),1 维预测框置信度,80 维物体类别数。所以第一层特征图的输出维度为 \(8 \times 8 \times 255\)
  3. Yolov3 总共输出 3 个特征图,第一个特征图下采样 32 倍,第二个特征图下采样 16 倍,第三个下采样 8 倍。输入图像经过 Darknet-53 (无全连接层),再经过 Yoloblock 生成的特征图被当作两用,第一用为经过 \(3 \times 3\) 卷积层、\(1 \times 1\) 卷积之后生成特征图一,第二用为经过 \(1 \times 1\) 卷积层加上上采样层,与 Darknet-53 网络的中间层输出结果进行拼接,产生特征图二。同样的循环之后产生特征图三。
  4. concat 操作与加和操作的区别:加和操作来源于 ResNet 思想,将输入的特征图,与输出特征图对应维度进行相加,即 \(y = f(x) + x\);而 concat 操作源于 DenseNet 网络的设计思路,将特征图按照通道维度直接进行拼接,例如 \(8 \times 8 \times 16\) 的特征图与 \(8 \times 8 \times 16\) 的特征图拼接后生成 \(8 \times 8 \times 32\) 的特征图。
  5. 上采样层 (upsample):作用是将小尺寸特征图通过插值等方法,生成大尺寸图像。例如使用最近邻插值算法,将 \(8 \times 8\) 的图像变换为 \(16 \times 16\)。上采样层不改变特征图的通道数。

Yolo 的整个网络,吸取了 Resnet、Densenet、FPN 的精髓,可以说是融合了目标检测当前业界最有效的全部技巧。

正负样本

  1. 预测框一共分为三种情况:正例 (positive)、负例 (negative)、忽略样例 (ignore)。
  2. 正例:任取一个 ground truth,与 4032 个框全部计算 IOU,IOU 最大的预测框,即为正例。并且一个预测框,只能分配给一个 ground truth。例如第一个 ground truth 已经匹配了一个正例检测框,那么下一个 ground truth,就在余下的 4031 个检测框中,寻找 IOU 最大的检测框作为正例。ground truth 的先后顺序可忽略。正例产生置信度 loss、检测框 loss、类别 loss。预测框为对应的 ground truth box 标签(需要反向编码,使用真实的 \(x, y, w, h\) 计算出 \(t_x, t_y, t_w, t_h\));类别标签对应类别为 1,其余为 0;置信度标签为 1。
  3. 忽略样例:正例除外,与任意一个 ground truth 的 IOU 大于阈值(论文中使用 0.5),则为忽略样例。忽略样例不产生任何 loss。
  4. 负例:正例除外(与 ground truth 计算后 IOU 最大的检测框,但是 IOU 小于阈值,仍为正例),与全部 ground truth 的 IOU 都小于阈值(0.5),则为负例。负例只有置信度产生 loss,置信度标签为 0。
image

\( Loss=loss_{N_1}+loss_{N_2}+loss_{N_3} \)

\(x、y、w、h\)使用MSE作为损失函数,也可以使用smooth L1 loss(出自Faster R-CNN)作为损失函数。smooth L1可以使训练更加平滑。置信度、类别标签由于是0,1二分类,所以使用交叉熵作为损失函数

训练策略解释

  1. ground truth为什么不按照中心点分配对应的预测box?
    1. 在Yolov3的训练策略中,不再像Yolov1那样,每个cell负责中心落在该cell中的ground truth。原因是Yolov3一共产生3个特征图,3个特征图上的cell,中心是有重合的。训练时,可能最契合的是特征图1的第3个box,但是推理的时候特征图2的第1个box置信度最高。所以Yolov3的训练,不再按照ground truth中心点,严格分配指定cell,而是根据预测值寻找IOU最大的预测框作为正例
    2. 笔者实验结果:第一种,ground truth先从9个先验框中确定最接近的先验框,这样可以确定ground truth所属第几个特征图以及第几个box位置,之后根据中心点进一步分配。第二种,全部4032个输出框直接和ground truth计算IOU,取IOU最高的cell分配ground truth。第二种计算方式的IOU数值,往往都比第一种要高,这样wh与xy的loss较小,网络可以更加关注类别和置信度的学习;其次,在推理时,是按照置信度排序,再进行nms筛选,第二种训练方式,每次给ground truth分配的box都是最契合的box,给这样的box置信度打1的标签,更加合理,最接近的box,在推理时更容易被发现
  2. Yolov1中的置信度标签,就是预测框与真实框的IOU,Yolov3为什么是1?
    1. 置信度意味着该预测框是或者不是一个真实物体,是一个二分类,所以标签是1、0更加合理
    2. 笔者实验结果:第一种:置信度标签取预测框与真实框的IOU;第二种:置信度标签取1。第一种的结果是,在训练时,有些预测框与真实框的IOU极限值就是0.7左右,置信度以0.7作为标签,置信度学习有一些偏差,最后学到的数值是0.5,0.6,那么假设推理时的激活阈值为0.7,这个检测框就被过滤掉了。但是IOU为0.7的预测框,其实已经是比较好的学习样例了。尤其是coco中的小像素物体,几个像素就可能很大程度影响IOU,所以第一种训练方法中,置信度的标签始终很小,无法有效学习,导致检测召回率不高。而检测框趋于收敛,IOU收敛至1,置信度就可以学习到1,这样的设想太过理想化。而使用第二种方法,召回率明显提升了很高
  3. 为什么有忽略样例?
    1. 忽略样例是Yolov3中的点睛之笔。由于Yolov3使用了多尺度特征图,不同尺度的特征图之间会有重合检测部分。比如有一个真实物体,在训练时被分配到的检测框是特征图1的第三个box,IOU达0.98,此时恰好特征图2的第一个box与该ground truth的IOU达0.95,也检测到了该ground truth,如果此时给其置信度强行打0的标签,网络学习效果会不理想
    2. 笔者实验结果:如果给全部的忽略样例置信度标签打0,那么最终的loss函数会变成\(Loss_{obj}\)\(Loss_{noobj}\)的拉扯,不管两个loss数值的权重怎么调整,或者网络预测趋向于大多数预测为负例,或者趋向于大多数预测为正例。而加入了忽略样例之后,网络才可以学习区分正负

优缺点

优点:

  1. 多尺度检测:YOLOv3在三个不同的尺度上进行检测,提高了模型对于不同大小物体的识别能力
  2. 浅层,细粒度,圆角,结构,颜色,板块
  3. 深层,纹理 ,眼镜,腿,汽车等语义信息
  4. 类别不确定性(Class Prediction):在类别预测方面,YOLOv3采用了逻辑回归而非softmax,从而可以更好地处理多标签场景
  5. 更多的Anchor Boxes:YOLOv3使用了多达9个锚框(分布在三个不同的尺度上),相比YOLOv2更能准确地适应不同形状和大小的目标
  6. 更大的模型和更深的架构:YOLOv3使用了Darknet-53,一个比YOLOv2的Darknet-19更大、更深的网络架构,以获得更高的准确性
  7. 新的损失函数:YOLOv3采用了一个新的损失函数,更加注重目标的定位和分类,使模型在多方面都得到了改进

缺点:

  1. 小目标检测仍有局限性:尽管YOLOv3通过多尺度检测做了一定程度的改进,但对于小目标的检测准确性相对仍然较低
  2. 高置信度的错误检测:YOLOv3可能会生成一些高置信度的错误检测,尤其是在目标密集或重叠的场景中
  3. 对标注质量的依赖:与其他目标检测算法一样,YOLOv3对于高质量的标注数据非常依赖。任何标注错误或不一致都可能对模型性能产生负面影响

YOLO v4

YOLOV4论文其实是一个结合了大量前人研究技术,加以组合并进行适当创新的高水平论文,实现了速度和精度的完美平衡

文中将前人的工作主要分为Bag of freebies和Bag of specials,前者是指不会显著影响模型测试速度和模型复杂度的技巧,主要就是数据增强操作,对应的Bag of specials就是会稍微增加模型复杂度和速度的技巧,但是如果不大幅增加复杂度且精度有明显提升,那也是不错的技巧。

image.png
YOLOv4 介绍及其模型优化方法

输入端创新

Mosaic

Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接

为什么要进行Mosaic数据增强呢?

在平时项目训练时,小目标的AP一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。Coco数据集中小目标占比达到41.4%,数量比中目标和大目标都要多。但在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。针对这种状况,Yolov4的作者采用了Mosaic数据增强的方式

主要有2个优点:

丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好 batch不需要很大:Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果

cmBN

CmBN的做法和前面两个都不一样,其把大batch内部的4个mini batch当做一个整体,对外隔离,主要改变在于BN层的统计量计算方面,具体流程是:假设当前是第t次迭代时刻,也是mini-batch的起点,

  1. 在第t时刻开始进行梯度累加操作
  2. 在第t时刻开始进行BN统计量汇合操作,这个就是和CBN的区别,CBN在第t时刻,也会考虑前3个时刻的统计量进行汇合,而CmBN操作不会,其仅仅在mini batch内部进行汇合操作
  3. 就是正常的应用BN,对输入进行变换输出即可
  4. 在mini batch的最后一个时刻,进行参数更新和可学习参数更新

可以明显发现CmBN是CBN的简化版本,其唯一差别就是在计算第t时刻的BN统计量时候,CBN会考虑前一个mini batch内部的统计量,而CmBN版本,所有计算都是在mini batch内部。有人认为这种做法是为了减少内存消耗,提高训练速度,既然大家都是近似,差距应该不大,而且本身yolo训练时候,batch也不会特别小,不至于是1-2,所以CmBN的做法应该是为了yolov4专门设计的,属于实践性改进

SAT自对抗训练

自对抗训练(Self-Adversarial Training,简称SAT)在YOLOv4中作为一种数据增强的方式出现。自对抗训练是一种基于生成对抗网络(GAN)中对抗训练概念的扩展。其主要目标是通过改变输入图像,使得网络难以识别,从而迫使网络提高泛化性能

在YOLOv4中,自对抗训练的主要步骤如下:

  1. 前向传播:首先,一个输入图像通过网络进行前向传播
  2. 计算损失:然后,计算预测与实际标签之间的损失
  3. 梯度回传:损失向后传播通过网络,以更新其参数
  4. 对抗性扰动:使用这些梯度来计算一个微小的对抗性扰动,该扰动能够使得损失最大化
  5. 应用扰动:将计算出的对抗性扰动应用于原始输入图像
  6. 再次训练:使用添加了对抗性扰动的图像再次进行前向和后向传播,并更新网络参数

这个过程旨在提高模型对输入变化的鲁棒性,从而在实际应用中达到更好的性能

需要指出的是,生成自对抗样本的具体方法可以有很多种方式,如添加噪声、旋转、缩放、颜色扰动等

Backbone主干结构

骨干部分图如下:


因为Backbone有5个CSP模块,输入图像是608*608,所以特征图变化的规律是:608->304->152->76->38->19 经过5次CSP模块后得到19-19大小的特征图。而且作者只在Backbone中采用了Mish激活函数,网络后面仍然采用Leaky_relu激活函数

YOLOv3的主干网络采用的是darknet53,yolov4的Backbone:采用的主干网络为 CSPDarknet53

CBM

Yolov4网络结构中的最小组件CBM,由Conv+Bn+Mish激活函数三者组成

首先,给定一张大小为 608-608-3 的输入图像,经过3-3的Conv1 之后得到低层全局特征图,经过BN层的归一化处理后,再经过mish激活函数R,\(H=W=608\)\(C=32\); 然后将该特征图。处理得到一个 608-608-32的特征图

Mish: ReLU 和 Mish 的对比,Mish 的梯度更平滑,Mish 检查了理想的激活函数应该是什么(平滑、处理负号等)的所有内容

PixPin_2026-02-26_15-19-35.png
\[𝑓(𝑥)=𝑥∗𝑡𝑎𝑛ℎ(𝑙𝑛(1+𝑒𝑥)) \]

以上无边界(即正值可以达到任何高度)避免了由于封顶而导致的饱和。理论上对负值的轻微允许,允许更好的梯度流,而不是像 ReLU 中那样的硬零边界。最后,可能也是最重要的,目前的想法是,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化。

这里的主要区别可能是 Mish 函数在曲线上几乎所有点上的平滑度。这种通过 Mish 激活曲线平滑性来推送信息的能力如下图所示,在本文的一个简单测试中,越来越多的层被添加到一个测试神经网络中,而没有一个统一的函数。随着层深的增加ReLU 精度迅速下降,其次是 Swish。相比之下,Mish 能更好地保持准确性,这可能是因为它能更好地传播信息:

image.png

CSP模块

CSPNet全称是Cross Stage Paritial Network,主要从网络结构设计的角度解决推理中从计算量很大的问题。CSPNet的作者认为推理计算过高的问题是由于网络优化中的梯度信息重复导致的。因此采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率

CSPNet将输入特征在channel纬度分为两部分。第一部分x₀’绕过DenseBlock成为下一个转换层的输入的一部分。第二部分\(x_0\)经过DenseBlock,结构如下

image.png

这种新设计通过将输入分成两部分——只有一部分经过密集的块,从而降低了计算复杂度。

由CBM组件和X个Res unint模块Concate组成

第一个CSP模块:由CBM组件和1个Res unint模块Concate组成

将CBM组件处理后的特征图608-608-32的F_conv2传入第一个CSP1模块进行处理(其中只有1个残差单元)

第二个CSP模块:由CBM组件和2个Res unint模块Concate组成

将第一个csp模块处理后的304-304-64特征图,传入到第二个CSP模块处理

同理经过下采样后变成了152152128的特征图,然后分别经过两个1164的s=1的卷积后得到两个分支,其中一个分支的特征块进入残差模块进行处理后,再与另一个分支进行拼接,最后第二个csp模块的最后输出是152-152-128 (残差模块中的卷积层:1-1-64和3-3-64)

第三个CSP模块:由8个Res unint模块和CBM组件Concate组成

将第二个csp模块处理后的52-152-128 的特征图,传入到第三个个CSP模块处理

同理也是经过同样的操作,最后第三个csp模块的最后输出是76-76-256 (残差模块中的卷积层:1-1-128和3-3-128),这个模块后又分为两个分支,一个分支继续进行csp模块处理,另一个分支直接进入到neck处理

第四个CSP模块:由8个Res unint模块和CBM组件Concate组成

将第三个csp模块的一个分支76-76-256的特征图,传入到第四个CSP模块处理

同理也是经过同样的操作,最后第四个csp模块的最后输出是38-38-512 (残差模块中的卷积层:1-1-256和3-3-256),这个模块后又分为两个分支,一个分支继续进行csp模块处理,另一个分支直接进入到neck处理

第五个CSP模块:由4个Res unint模块和CBM组件Concate组成

将第四个csp模块的一个分支38-38-512的特征图,传入到第五个CSP模块处理

同理也是经过同样的操作,最后第五个csp模块的最后输出是19-19-1024 (残差模块中的卷积层:1-1-512和3-3-512),这个模块输出结果直接进入到neck处理

Dropblock

Yolov4中使用的Dropblock,其实和常见网络中的Dropout功能类似,也是缓解过拟合的一种正则化方式

传统的Dropout很简单,一句话就可以说的清:随机删除减少神经元的数量,使网络变得更简单

dropout主要作用在全连接层,而dropblock可以作用在任何卷积层之上

文章分析了传统 dropout 在 conv 上效果不好的原因: conv 具有空间相关性,所以即使对一些单元随机进行 dropout,仍然可以有信息流向后面的网络,导致 dropout 不彻底

中间Dropout的方式会随机的删减丢弃一些信息,但Dropblock的研究者认为,卷积层对于这种随机丢弃并不敏感,因为卷积层通常是三层连用:卷积+激活+池化层,池化层本身就是对相邻单元起作用。而且即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息

而且并不是用固定的归零比率,而是在训练时以一个小的比率开始,随着训练过程线性的增加这个比率。在特征图上一块一块的进行归0操作,去促使网络去学习更加鲁棒的特征

为了保证Dropblock后的特征图与原先特征图大小一致,需要和dropout一样,进行rescale操作

neck

PixPin_2026-02-26_15-25-48.png

特征增强模块,主要由CBL组件,SPP模块和FPN+PAN的方式组成

CBL组件:

由Conv+Bn+Leaky_relu激活函数三者组成

将第五个csp4模块的输出结果19-19-1024的特征图,传入到CBL组件中处理

spp前后三个CBL组件是对称的,它们的卷积分别是1-1-512,3-3-1024和1-1-512,步长都是1

SPP模块:

采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合


spp模块采用的1×1 ,5×5 padding=5 // 2,9×9 padding=9 // 2,13×13 padding=13 // 2的最大池化的方式,进行多尺度融合,从前面三个CBL组件输出的结果:1919512的特征图,将之送入spp模块中,最后的结果为19192048,再经过三个CBL组件的卷积后得到1919512的特征图

FPN+PAN的结构:

PAN是借鉴图像分割领域PANet的创新点

这样结合操作,FPN层自顶向下传达强语义特征,而PAN则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行参数聚合,加速了不同尺度特征的融合,进一步提高特征提取的能力

FPN+PAN借鉴的是18年CVPR的PANet,当时主要应用于图像分割领域,但Alexey将其拆分应用到Yolov4中,进一步提高特征提取的能力

原本的PANet网络的PAN结构中,两个特征图结合是采用shortcut操作,而Yolov4中则采用**concat(route)**操作,特征图融合后的尺寸发生了变化

Head

YoloHead利用获得到的特征进行预测,是一个解码的过程

先验框(anchor box)

YOLO3采用了K-means聚类得到先验框的尺寸,YOLO4延续了这种方法,为每种下采样尺度设定3种先验框,总共聚类出9种尺寸的先验框

解码检测框

有了先验框与输出特征图后,就可以解码检测框 x,y,w,h。 例如:(19,19,3,85),分别对应着19*19个网格,每个网格3种anchors,85=(x,y,w,h,confident),此时box的x,y是相对于网格的偏移量,所以还需要经过一些列的处理,处理方式见下图:

在这里插入图片描述

置信度解码

物体的检测置信度,置信度在输出85维中占固定一位,由sigmoid函数解码即可,解码之后数值区间在[0,1]中

类别解码

COCO数据集有80个类别,所以类别数在85维输出中占了80维,每一维独立代表一个类别的置信度。使用sigmoid激活函数替代了Yolov2中的softmax,取消了类别之间的互斥,可以使网络更加灵活

筛选预测框

三个特征图一共可以解码出 19 × 19 × 3 + 38 × 38× 3 + 76 × 76 × 3 = 22743个box以及相应的类别、置信度。 首先,设置一个置信度阈值,筛选掉低于阈值的box,再经过DIOU_NMS(非极大值抑制)后,就可以输出整个网络的预测结果了

回归框损失函数:Smooth L1 loss;IoU;G;D;C

计算损失

位置损失

\[CIoU=1-IoU+\frac{\rho^2(A,B)}{c^2}+\alpha v 𝐶𝐼𝑜𝑈=1−𝐼𝑜𝑈+𝜌2(𝐴,𝐵)𝑐2+𝛼𝑣\]

置信度损失

\[\sum_{i=0}^{K\times K}\sum_{j=0}^MI_{ij}^{obj}[C_ilog(\hat{C}_i)+(1-C_i)log(1-\hat{C}_i)].\]
\[\sum_{i=0}^{K\times K}\sum_{j=0}^MI_{ij}^{noobj}[C_ilog(\hat{C}_i)+(1-C_i)log(1-\hat{C}_i)]\]

分类损失:

\[\text{Classification Loss} = - \sum_{c \in C} p(c) \log(q(c))\]
\[\begin{gathered} \mathrm{LOSS1=CIOU-}\lambda_{obj}\sum_{i=0}^{KK}\sum_{j=0}^{M}I_{ij}^{obj}[C_{i}\log{(\widehat{C_{i}})}+(1-{\cal L_{i}})log{(\widehat{C_{i}})}] \\ -\lambda_{noobj}\sum_{i=0}^{KK}\sum_{j=0}^{M}I_{ij}^{NOobj}[C_{i}\log{(\widehat{C_{i}})}+(1-C_{i})log{(1-\widehat{C_{i}})}] \\ -\quad\sum_{i=0}^{K\times K}\sum_{j=0}^MI_{ij}^{obj}\sum_{c\in classes}[p_i(c)log(\hat{p}_i(c))+(1-p_i(c))log(1-\hat{p}_i(c))] \end{gathered}\]
  1. $\lambda$ 为权重常数,控制检测框 Loss、有物体置信度 Loss、没有物体的置信度 Loss 之间的比例,通常负例的个数是正例的几十倍以上,可以通过权重超参控制检测效果。
  2. \(\mathbb{I}_{i,j}^{\text{obj}}\) 若是正例则输出 1,否则为 0;\(\mathbb{I}_{i,j}^{\text{noobj}}\)若是负例则输出 1,否则为 0;忽略样例都输出 0。
  3. 置信度、类别标签由于是 0, 1 二分类,所以使用交叉熵作为损失函数。

优缺点

优点:

  1. CIOU Loss(Complete Intersection over Union):这是一种改进的损失函数,用于解决传统IoU损失的一些问题,从而提高模型对目标定位的准确性
  2. PANet(Path Aggregation Network)和 SAM block:这些结构改进了特征传播和模型的注意力机制
  3. Mish 激活函数:这是一种替代 ReLU 的新型激活函数,旨在改进模型的训练稳定性和性能
  4. CSPDarknet53:这是一种更有效的特征提取网络,比起其他如 VGG 和 ResNet 等网络结构,它具有更高的运算效率
  5. 使用多尺度和多宽高比的锚点:这改进了对不同形状和大小的目标的检测能力

缺点:

  1. 计算复杂性:尽管 YOLOv4 针对速度进行了优化,但其模型结构仍然相当复杂,可能不适用于资源受限的硬件
  2. 可解释性与透明度:YOLOv4 的模型结构和算法相对复杂,这可能影响模型的可解释性和透明度
  3. 易用性和训练稳定性:由于模型结构和损失函数更为复杂,对于一般用户来说,训练一个稳定和高性能的 YOLOv4 模型可能需要更多的专业知识和经验

YOLO v5

YOLO v5中的改进点:

  • 输入端: 数据增强(Mosaic Augmentation、MixUp、CutMix、Bluring、Label Smoothing等)、自适应锚框计算、自适应的图像缩放
  • BackBone骨干网络: Focus结构、CSP+DarkNet等
  • Neck:FPN+PAN、SPP等
  • Prediction:更换边框回归损失函数(GIoU_LOSS)

简介

image.png
YOLOv5-l-P5 模型结构
image.png

YOLOv5 是一个面向实时工业应用而开源的目标检测算法,受到了广泛关注。我们认为让 YOLOv5 爆火的原因不单纯在于 YOLOv5 算法本身的优异性,更多的在于开源库的实用和鲁棒性。简单来说 YOLOv5 开源库的主要特点为:

  1. 友好和完善的部署支持
  2. 算法训练速度极快,在 300 epoch 情况下训练时长和大部分 one-stage 算法如 RetinaNet、ATSS 和 two-stage 算法如 Faster R-CNN 在 12 epoch 的训练时间接近
  3. 框架进行了非常多的 corner case 优化,功能和文档也比较丰富

如图 1 和 2 所示,YOLOv5 的 P5 和 P6 版本主要差异在于网络结构和图片输入分辨率。其他区别,如 anchors 个数和 loss 权重可详见配置文件

数据增强模块

YOLOv5 目标检测算法中使用的数据增强比较多,包括:

  • Mosaic 马赛克
  • RandomAffine 随机仿射变换
  • MixUp
  • 图像模糊等采用 Albu 库实现的变换
  • HSV 颜色空间增强
  • 随机水平翻转

其中 Mosaic 数据增强概率为 1,表示一定会触发,而对于 small 和 nano 两个版本的模型不使用 MixUp,其他的 l/m/x 系列模型则采用了 0.1 的概率触发 MixUp。小模型能力有限,一般不会采用 MixUp 等强数据增强策略。

其核心的 Mosaic + RandomAffine + MixUp 过程简要绘制如下:

image.png

下面对其进行简要分析。

image.png

Mosaic 属于混合类数据增强,因为它在运行时候需要 4 张图片拼接,变相的相当于增加了训练的 batch size。其运行过程简要概况为:

  1. 随机生成拼接后 4 张图的交接中心点坐标,此时就相当于确定了 4 张拼接图片的交接点
  2. 随机选出另外 3 张图片的索引以及读取对应的标注
  3. 对每张图片采用保持宽高比的 resize 操作将其缩放到指定大小
  4. 按照上下左右规则,计算每张图片在待输出图片中应该放置的位置,因为图片可能出界故还需要计算裁剪坐标
  5. 利用裁剪坐标将缩放后的图片裁剪,然后贴到前面计算出的位置,其余位置全部补 114 像素值
  6. 对每张图片的标注也进行相应处理

注意:由于拼接了 4 张图,所以输出图片面积会扩大 4 倍,从 640x640 变成 1280x1280,因此要想恢复为 640x640, 必须要再接一个 RandomAffine 随机仿射变换,否则图片面积就一直是扩大 4 倍的。

image.png

随机仿射变换有两个目的:

  1. 对图片进行随机几何仿射变换
  2. 将 Mosaic 输出的扩大 4 倍的图片还原为 640x640 尺寸

随机仿射变换包括平移、旋转、缩放、错切等几何增强操作,同时由于 Mosaic 和 RandomAffine 属于比较强的增强操作,会引入较大噪声,因此需要对增强后的标注进行处理,过滤规则为:

  1. 增强后的 gt bbox 宽高要大于 wh_thr
  2. 增强后的 gt bbox 面积和增强前的 gt bbox 面积比要大于 ar_thr,防止增强太严重
  3. 最大宽高比要小于 area_thr,防止宽高比改变太多

由于旋转后标注框会变大导致不准确,因此目标检测里面很少会使用旋转数据增强。

MixUp

image.png

MixUp 和 Mosaic 类似也属于混合图片类增强方法。随机选出另外一张图后将两图再随机混合。具体实现方法有多种,常见的做法是要么将 label 直接拼接起来,要么将 label 也采用 alpha 方法混合。原作者的做法非常简单,对 label 即直接拼接,而图片通过分布采样混合。

需要特别注意的是: YOLOv5 实现的 MixUp 中,随机出来的另一张图也需要经过 Mosaic 马赛克 + RandomAffine 随机仿射变换 的增强后才能混合。这个和其他开源库实现可能不太一样。

图像模糊和其他数据增强策略

image.png

剩下的数据增强包括

  • 图像模糊等采用 Albu 库实现的变换
  • HSV 颜色空间增强
  • 随机水平翻转

MMDetection 开源库中已经对 Albu 第三方数据增强库进行了封装,使用户可以简单的通过配置即可使用 Albu 库中提供的任何数据增强功能。而 HSV 颜色空间增强和随机水平翻转都是属于比较常规的数据增强,不需要特殊介绍。

网络结构

YOLOv5 网络结构是标准的 CSPDarknet + PAFPN + 非解耦 Head

Backbone

在 MMYOLO 中 CSPDarknet 继承自 BaseBackbone,整体结构和 ResNet 类似。P5 模型共 5 层结构,包含 1 个 Stem Layer 和 4 个 Stage Layer

  • Stem Layer 是 1 个 6x6 kernel 的 ConvModule,相较于 v6.1 版本之前的 Focus 模块更加高效。
  • 除了最后一个 Stage Layer,其他均由 1 个 ConvModule 和 1 个 CSPLayer 组成。如上图 Details 部分所示。 其中 ConvModule 为 3x3的 Conv2d + BatchNorm + SiLU 激活函数CSPLayer 即 YOLOv5 官方仓库中的 C3 模块,由 3 个 ConvModule + n 个 DarknetBottleneck(带残差连接) 组成。
  • 最后一个 Stage Layer 在最后增加了 SPPF 模块。SPPF 模块是将输入串行通过多个 5x5 大小的 MaxPool2d 层,与 SPP 模块效果相同,但速度更快。
  • P5 模型会在 Stage Layer 2-4 之后分别输出一个特征图进入 Neck 结构。以 640x640 输入图片为例,其输出特征为 (B,256,80,80)、(B,512,40,40) 和 (B,1024,20,20),对应的 stride 分别为 8/16/32。
  • P6 模型会在 Stage Layer 2-5 之后分别输出一个特征图进入 Neck 结构。以 1280x1280 输入图片为例,其输出特征为 (B,256,160,160)、(B,512,80,80)、(B,768,40,40) 和 (B,1024,20,20),对应的 stride 分别为 8/16/32/64。

Neck

YOLOv5 官方仓库的配置文件中并没有 Neck 部分,为方便用户与其他目标检测网络结构相对应,我们将官方仓库的 Head 拆分成 PAFPN 和 Head 两部分。

基于 BaseYOLONeck 结构,YOLOv5 Neck 也是遵循同一套构建流程,对于不存在的模块,我们采用 nn.Identity 代替。

Neck 模块输出的特征图和 Backbone 完全一致。即 P5 模型为 (B,256,80,80)、 (B,512,40,40) 和 (B,1024,20,20);P6 模型为 (B,256,160,160)、(B,512,80,80)、(B,768,40,40) 和 (B,1024,20,20)。

Head

YOLOv5 Head 结构和 YOLOv3 完全一样,为 非解耦 Head。Head 模块只包括 3 个不共享权重的卷积,用于将输入特征图进行变换而已。

前面的 PAFPN 依然是输出 3 个不同尺度的特征图,shape 为 (B,256,80,80)、 (B,512,40,40) 和 (B,1024,20,20)。 由于 YOLOv5 是非解耦输出,即分类和 bbox 检测等都是在同一个卷积的不同通道中完成。以 COCO 80 类为例:

  • P5 模型在输入为 640x640 分辨率情况下,其 Head 模块输出的 shape 分别为 (B, 3x(4+1+80),80,80)(B, 3x(4+1+80),40,40) 和 (B, 3x(4+1+80),20,20)
  • P6 模型在输入为 1280x1280 分辨率情况下,其 Head 模块输出的 shape 分别为 (B, 3x(4+1+80),160,160)(B, 3x(4+1+80),80,80)(B, 3x(4+1+80),40,40) 和 (B, 3x(4+1+80),20,20)。 其中 3 表示 3 个 anchor,4 表示 bbox 预测分支,1 表示 obj 预测分支,80 表示 COCO 数据集类别预测分支。

正负样本匹配策略

正负样本匹配策略的核心是确定预测特征图的所有位置中哪些位置应该是正样本,哪些是负样本,甚至有些是忽略样本。 匹配策略是目标检测算法的核心,一个好的匹配策略可以显著提升算法性能。

YOLOV5 的匹配策略简单总结为:采用了 anchor 和 gt_bbox 的 shape 匹配度作为划分规则,同时引入跨邻域网格策略来增加正样本。 其主要包括如下两个核心步骤:

  1. 对于任何一个输出层,抛弃了常用的基于 Max IoU 匹配的规则,而是直接采用 shape 规则匹配,也就是该 GT Bbox 和当前层的 Anchor 计算宽高比,如果宽高比例大于设定阈值,则说明该 GT Bbox 和 Anchor 匹配度不够,将该 GT Bbox 暂时丢掉,在该层预测中该 GT Bbox 对应的网格内的预测位置认为是负样本
  2. 对于剩下的 GT Bbox(也就是匹配上的 GT Bbox),计算其落在哪个网格内,同时利用四舍五入规则,找出最近的两个网格,将这三个网格都认为是负责预测该 GT Bbox 的,可以粗略估计正样本数相比之前的 YOLO 系列,至少增加了三倍

下面会对每个部分进行详细说明,部分描述和图示直接或间接参考自官方 Repo

Anchor 设置

YOLOv5 是 Anchor-based 的目标检测算法,其 Anchor size 的获取方式与 YOLOv3 类似,也是使用聚类获得,其不同之处在于聚类使用的标准不再是基于 IoU 的,而是使用形状上的宽高比作为聚类准则(即 shape-match )。

Bbox 编解码过程

在 Anchor-based 算法中,预测框通常会基于 Anchor 进行变换,然后预测变换量,这对应 GT Bbox 编码过程,而在预测后需要进行 Pred Bbox 解码,还原为真实尺度的 Bbox,这对应 Pred Bbox 解码过程。

在 YOLOv3 中,回归公式为:

\[\begin{split}b_x=\sigma(t_x)+c_x \\ b_y=\sigma(t_y)+c_y \\ b_w=a_w\cdot e^{t_w} \\ b_h=a_h\cdot e^{t_h} \\\end{split}\]

公式中,\(𝑎_𝑤\)代表𝐴𝑛𝑐ℎ𝑜𝑟的宽度\(𝑐_𝑥\)代表𝐺𝑟𝑖𝑑所处的坐标\(𝜎\)代表𝑆𝑖𝑔𝑚𝑜𝑖𝑑公式。

而在 YOLOv5 中,回归公式为:

\[\begin{split}b_x=(2\cdot\sigma(t_x)-0.5)+c_x \\ b_y=(2\cdot\sigma(t_y)-0.5)+c_y \\ b_w=a_w\cdot(2\cdot\sigma(t_w))^2 \\ b_h=a_h\cdot(2\cdot\sigma(t_h))^2\end{split}\]

改进之处主要有以下两点:

  • 中心点坐标范围从 (0, 1) 调整至 (-0.5, 1.5)
  • 宽高范围从,(0,+∞)调整至,(0,4𝑎𝑤ℎ)

这个改进具有以下好处:

  • 新的中心点设置能更好的预测到 0 和 1。这有助于更精准回归出 box 坐标。
  • 宽高回归公式中 exp(x) 是无界的,这会导致梯度失去控制,造成训练不稳定。YOLOv5 中改进后的宽高回归公式优化了此问题。

匹配策略

在 MMYOLO 设计中,无论网络是 Anchor-based 还是 Anchor-free,我们统一使用 prior 称呼 Anchor。

正样本匹配包含以下两步:

  1. “比例”比较

将 GT Bbox 的 WH 与 Prior 的 WH 进行“比例”比较。

比较流程:

\[\begin{split}r_w = w\_{gt} / w\_{pt} \\ r_h = h\_{gt} / h\_{pt} \\ r_w^{max}=max(r_w, 1/r_w) \\ r_h^{max}=max(r_h, 1/r_h) \\ r^{max}=max(r_w^{max}, r_h^{max}) \\ if\ \ r_{max} < prior\_match\_thr: match!\end{split}\]

此处我们用一个 GT Bbox 与 P3 特征图的 Prior 进行匹配的案例进行讲解和图示:

image.png

prior1 匹配失败的原因是 ℎ_𝑔𝑡 / ℎ_𝑝𝑟𝑖𝑜𝑟 = 4.8 > 𝑝𝑟𝑖𝑜𝑟_𝑚𝑎𝑡𝑐ℎ_𝑡ℎ𝑟

  1. 为步骤 1 中 match 的 GT 分配对应的正样本

依然沿用上面的例子:

GT Bbox (cx, cy, w, h) 值为 (26, 37, 36, 24),

Prior WH 值为 [(15, 5), (24, 16), (16, 24)],在 P3 特征图上,stride 为 8。通过计算,prior2 和 prior3 能够 match。

计算过程如下:

将 GT Bbox 的中心点坐标对应到 P3 的 grid 上

\[\begin{split}GT_x^{center_grid}=26/8=3.25 \\ GT_y^{center_grid}=37/8=4.625\end{split}\]
image.png

将 GT Bbox 中心点所在的 grid 分成四个象限,由于中心点落在了左下角的象限当中,那么会将物体的左、下两个 grid 也认为是正样本

image.png

下图展示中心点落到不同位置时的正样本分配情况:

image.png

那么 YOLOv5 的 Assign 方式具体带来了哪些改进?

  • 一个 GT Bbox 能够匹配多个 Prior
  • 一个 GT Bbox 和一个Prior 匹配时,能分配 1-3 个正样本
  • 以上策略能适度缓解目标检测中常见的正负样本不均衡问题。

而 YOLOv5 中的回归方式,和 Assign 方式是相互呼应的:

  1. 中心点回归方式:
image.png
  1. WH 回归方式:
image.png

Loss 设计

YOLOv5 中总共包含 3 个 Loss,分别为:

  • Classes loss:使用的是 BCE loss
  • Objectness loss:使用的是 BCE loss
  • Location loss:使用的是 CIoU loss

三个 loss 按照一定比例汇总:

\[Loss=\lambda_1L_{cls}+\lambda_2L_{obj}+\lambda_3L_{loc}\]

P3、P4、P5 层对应的 Objectness loss 按照不同权重进行相加,默认的设置是 obj_level_weights=[4. ,1. , 0.4 ]

\[L_{obj}=4.0\cdot L_{obj}^{small}+1.0\cdot L_{obj}^{medium}+0.4\cdot L_{obj}^{large}\]

YOLO v6

简介

image.png
image.png

YOLOv6 提出了一系列适用于各种工业场景的模型,包括 N/T/S/M/L,考虑到模型的大小,其架构有所不同,以获得更好的精度-速度权衡。本算法专注于检测的精度和推理效率,并在网络结构、训练策略等算法层面进行了多项改进和优化。

简单来说 YOLOv6 开源库的主要特点为:

  1. 统一设计了更高效的 Backbone 和 Neck:受到硬件感知神经网络设计思想的启发,基于 RepVGG style 设计了可重参数化、更高效的骨干网络 EfficientRep Backbone 和 Rep-PAN Neck。
  2. 相比于 YOLOX 的 Decoupled Head,进一步优化设计了简洁有效的 Efficient Decoupled Head,在维持精度的同时,降低了一般解耦头带来的额外延时开销。
  3. 在训练策略上,采用 Anchor-free 的策略,同时辅以 SimOTA 标签分配策略以及 SIoU 边界框回归损失来进一步提高检测精度。

数据增强模块

YOLOv6 目标检测算法中使用的数据增强与 YOLOv5 基本一致,唯独不一样的是没有使用 Albu 的数据增强方式:

  • Mosaic 马赛克
  • RandomAffine 随机仿射变换
  • MixUp
  • 图像模糊等采用 Albu 库实现的变换
  • HSV 颜色空间增强
  • 随机水平翻转

关于每一个增强的详细解释,详情请看 YOLOv5 数据增强模块

另外,YOLOv6 参考了 YOLOX 的数据增强方式,分为 2 种增强方法组,一开始和 YOLOv5 一致,但是在最后 15 个 epoch 的时候将 Mosaic 使用 YOLOv5KeepRatioResize + LetterResize 替代了,个人感觉是为了拟合真实情况。

网络结构

YOLOv6 N/T/S 模型的网络结构由 EfficientRep + Rep-PAN + Efficient decoupled Head 构成,M/L 模型的网络结构则由 CSPBep + CSPRepPAFPN + Efficient decoupled Head 构成。其中,Backbone 和 Neck 部分的结构与 YOLOv5 较为相似,但不同的是其采用了重参数化结构 RepVGG Block 替换掉了原本的 ConvModule,在此基础上,将 CSPLayer 改进为了多个 RepVGG 堆叠的 RepStageBlock(N/T/S 模型)或 BepC3StageBlock(M/L 模型);Head 部分则参考了 FCOS 和 YOLOX 的检测头,将回归与分类分支解耦成两个分支进行预测。YOLOv6-S 和 YOLOv6-L 整体结构分别如图 1 和图 2 所示。

Backbone

已有研究表明,多分支的网络结构通常比单分支网络性能更加优异,例如 YOLOv5 的 CSPDarknet,但是这种结构会导致并行度降低进而增加推理延时;相反,类似于 VGG 的单分支网络则具有并行度高、内存占用小的优点,因此推理效率更高。而 RepVGG 则同时具备上述两种结构的优点,在训练时可解耦成多分支拓扑结构提升模型精度,实际部署时可等效融合为单个 3×3 卷积提升推理速度,RepVGG 示意图如下。因此,YOLOv6 基于 RepVGG 重参数化结构设计了高效的骨干网络 EfficientRep 和 CSPBep,其可以充分利用硬件算力,提升模型表征能力的同时降低推理延时。

image.png

在 N/T/S 模型中,YOLOv6 使用了 EfficientRep 作为骨干网络,其包含 1 个 Stem Layer 和 4 个 Stage Layer,具体细节如下:

  • Stem Layer 中采用 stride=2 的 RepVGGBlock 替换了 stride=2 的 6×6 ConvModule
  • Stage Layer 结构与 YOLOv5 基本相似,将每个 Stage layer 的 1 个 ConvModule 和 1 个 CSPLayer 分别替换为 1 个 RepVGGBlock 和 1 个 RepStageBlock,如上图 Details 部分所示。其中,第一个 RepVGGBlock 会做下采样和 Channel 维度变换,而每个 RepStageBlock 则由 n 个 RepVGGBlock 组成。此外,仍然在第 4 个 Stage Layer 最后增加 SPPF 模块后输出。

在 M/L 模型中,由于模型容量进一步增大,直接使用多个 RepVGGBlock 堆叠的 RepStageBlock 结构计算量和参数量呈现指数增长。因此,为了权衡计算负担和模型精度,在 M/L 模型中使用了 CSPBep 骨干网络,其采用 BepC3StageBlock 替换了小模型中的 RepStageBlock 。如下图所示,BepC3StageBlock 由 3 个 1×1 的 ConvModule 和多个子块(每个子块由两个 RepVGGBlock 残差连接)组成。

image.png

Neck

Neck 部分结构仍然在 YOLOv5 基础上进行了模块的改动,同样采用 RepStageBlock 或 BepC3StageBlock 对原本的 CSPLayer 进行了替换,需要注意的是,Neck 中 Down Sample 部分仍然使用了 stride=2 的 3×3 ConvModule,而不是像 Backbone 一样替换为 RepVGGBlock

Head

不同于传统的 YOLO 系列检测头,YOLOv6 参考了 FCOS 和 YOLOX 中的做法,将分类和回归分支解耦成两个分支进行预测并且去掉了 obj 分支。同时,采用了 hybrid-channel 策略构建了更高效的解耦检测头,将中间 3×3 的 ConvModule 减少为 1 个,在维持精度的同时进一步减少了模型耗费,降低了推理延时。此外,需要说明的是,YOLOv6 在 Backobone 和 Neck 部分使用的激活函数是 ReLU,而在 Head 部分则使用的是 SiLU

由于 YOLOv6 是解耦输出,分类和 bbox 检测通过不同卷积完成。以 COCO 80 类为例:

  • P5 模型在输入为 640x640 分辨率情况下,其 Head 模块输出的 shape 分别为 (B,4,80,80)(B,80,80,80)(B,4,40,40)(B,80,40,40)(B,4,20,20)(B,80,20,20)

正负样本匹配策略

YOLOv6 采用的标签匹配策略与 TOOD 相同, 前 4 个 epoch 采用 ATSSAssigner 作为标签匹配策略的 warm-up , 后续使用 TaskAlignedAssigner 算法选择正负样本, 基于官方开源代码, MMYOLO 中也对两个 assigner 算法进行了优化, 改进为 Batch 维度进行计算, 能够一定程度的加快速度。 下面会对每个部分进行详细说明。

Anchor 设置

YOLOv6 采用与 YOLOX 一样的 Anchor-free 无锚范式,省略了聚类和繁琐的 Anchor 超参设定,泛化能力强,解码逻辑简单。在训练的过程中会根据 feature size 去自动生成先验框。

Bbox 编解码过程

YOLOv6 的 BBox Coder 采用的是 DistancePointBBoxCoder

网络 bbox 预测的值为 (top, bottom, left, right),解码器将 anchor point 通过四个距离解码到坐标 (x1,y1,x2,y2)。

匹配策略

  • 0 <= epoch < 4,使用 BatchATSSAssigner
  • epoch >= 4,使用 BatchTaskAlignedAssigner

ATSSAssigner

ATSSAssigner 是 ATSS 中提出的标签匹配策略。 ATSS 的匹配策略简单总结为:通过中心点距离先验对样本进行初筛,然后自适应生成 IoU 阈值筛选正样本。 YOLOv6 的实现种主要包括如下三个核心步骤:

  1. 因为 YOLOv6 是 Anchor-free,所以首先将 anchor point 转化为大小为 5*strdie 的 anchor
  2. 对于每一个 GT,在 FPN 的每一个特征层上, 计算与该层所有 anchor 中心点距离(位置先验), 然后优先选取距离 topK 近的样本,作为 初筛样本。
  3. 对于每一个 GT,计算其 初筛样本 的 IoU 的均值 mean与标准差 std,将 mean + std 作为该 GT 的正样本的 自适应 IoU 阈值 ,大于该 自适应阈值 且中心点在 GT 内部的 anchor 才作为正样本,使得样本能够被 assign 到合适的 FPN 特征层上。

下图中,(a) 所示中等大小物体被 assign 到 FPN 的中层,(b) 所示偏大的物体被 assign 到 FPN 中检测大物体和偏大物体的两个层。

image.png
# 1. 首先将anchor points 转化为 anchors
# priors为(point_x,point_y,stride_w,stride_h), shape 为(N,4)
cell_half_size = priors[:, 2:] * 2.5
priors_gen = torch.zeros_like(priors)
priors_gen[:, :2] = priors[:, :2] - cell_half_size
priors_gen[:, 2:] = priors[:, :2] + cell_half_size
priors = priors_gen
# 2. 计算 anchors 与 GT 的 IoU
overlaps = self.iou_calculator(gt_bboxes.reshape([-1, 4]), priors)
# 3. 计算 anchor 与 GT 的中心距离
distances, priors_points = bbox_center_distance(
        gt_bboxes.reshape([-1, 4]), priors)
# 4. 根据中心点距离,在 FPN 的每一层选取 TopK 临近的样本作为初筛样本
is_in_candidate, candidate_idxs = self.select_topk_candidates(
        distances, num_level_priors, pad_bbox_flag)
# 5. 对于每一个 GT 计算其对应初筛样本的均值与标准差的和, 作为该GT的样本阈值
overlaps_thr_per_gt, iou_candidates = self.threshold_calculator(
        is_in_candidate, candidate_idxs, overlaps, num_priors, batch_size,
        num_gt)
# 6. 筛选大于阈值的样本作为正样本
is_pos = torch.where(
        iou_candidates > overlaps_thr_per_gt.repeat([1, 1, num_priors]),
        is_in_candidate, torch.zeros_like(is_in_candidate))
# 6. 保证样本中心点在 GT 内部且不超图像边界
pos_mask = is_pos * is_in_gts * pad_bbox_flag

TaskAlignedAssigner

TaskAlignedAssigner 是 TOOD 中提出的一种动态样本匹配策略。 由于 ATSSAssigner 是属于静态标签匹配策略,其选取正样本的策略主要根据 anchor 的位置进行挑选, 并不会随着网络的优化而选取到更好的样本。在目标检测中,分类和回归的任务最终作用于同一个目标,所以 TaskAlignedAssigner 认为样本的选取应该更加关注到对分类以及回归都友好的样本点。

TaskAlignedAssigner 的匹配策略简单总结为: 根据分类与回归的分数加权的分数选择正样本。

  1. 对于每一个 GT,对所有的 预测框 基于 GT类别对应分类分数 与 预测框与 GT 的 IoU 的加权得到一个关联分类以及回归的对齐分数 alignment_metrics
  2. 对于每一个 GT,直接基于 alignment_metrics 对齐分数选取 topK 大的作为正样本。

因为在网络初期参数随机, 分类分数 和 预测框与 GT 的 IoU 都不准确,所以需要经过前 4 个 epoch 的 ATSSAssigner 的 warm-up。经过预热之后的 TaskAlignedAssigner 标签匹配策略就不使用中心距离的先验, 而是直接对每一个GT 选取 alignment_metrics 中 topK 大的样本作为正样本。

# 1. 基于分类分数与回归的 IoU 计算对齐分数 alignment_metrics
alignment_metrics = bbox_scores.pow(self.alpha) * overlaps.pow(
            self.beta)
# 2. 保证中心点在 GT 内部的 mask
is_in_gts = select_candidates_in_gts(priors, gt_bboxes)
# 3. 选取 TopK 大的对齐分数的样本
topk_metric = self.select_topk_candidates(
            alignment_metrics * is_in_gts,
            topk_mask=pad_bbox_flag.repeat([1, 1, self.topk]).bool())

Loss 设计

参与 Loss 计算的共有两个值:loss_cls 和 loss_bbox,其各自使用的 Loss 方法如下:

  • Classes loss:使用的是 mmdet.VarifocalLoss
  • BBox loss:l/m/s使用的是 GIoULoss, t/n 用的是 SIoULoss

权重比例是:loss_cls : loss_bbox = 1 : 2.5

分类损失函数 VarifocalLoss

Varifocal Loss (VFL) 是 VarifocalNet: An IoU-aware Dense Object Detector 中的损失函数。

image.png

VFL 是在 GFL 的基础上做的改进,GFL详情请看 GFL详解

在上述标签匹配策略中提到过选择样本应该优先考虑分类回归都友好的样本点, 这是由于目标检测包含的分类与回归两个子任务都是作用于同一个物体。 与 GFL 思想相同,都是将 预测框与 GT 的 IoU 软化作为分类的标签,使得分类分数关联回归质量, 使其在后处理 NMS 阶段有分类回归一致性很强的分值排序策略,以达到选取优秀预测框的目的。

Varifocal Loss 原本的公式:

\[\begin{split}{VFL}(p,q)= \begin{cases} -q(qlog(p) +(1-q)log(1-p)), & q > 0 \\ -\alpha p^\gamma log(1-p), & q = 0 \end{cases}\end{split}\]

其中 𝑞 是预测 bboxes 与 GT 的 IoU,使用软标签的形式作为分类的标签。 𝑝∈[0,1] 表示分类分数。

  1. 对于负样本,即当 𝑞=0 时,标准交叉熵部分为 −log⁡(𝑝),负样本权重使用 𝛼𝑝𝛾 作为 focal weight 使样本聚焦与困难样本上,这与 Focal Loss 基本一致。
  2. 对于正样本,即当 𝑞>0 时,首先计算标准二值交叉熵部分 −(𝑞𝑙𝑜𝑔(𝑝)+(1−𝑞)𝑙𝑜𝑔(1−𝑝)), 但是针对正样本的权重设置,Varifocal Loss 中并没有采用类似 𝛼𝑝𝛾的方式降权, 而是认为在网络的学习过程中正样本相对于负样本的学习信号来说更为重要,所以使用了分类的标签 𝑞, 即 IoU 作为 focal weight, 使得聚焦到具有高质量的样本上。

但是 YOLOv6 中的 Varifocal Loss 公式采用 TOOD 中的 Task ALignment Learning (TAL), 将预测的 IoU 根据之前标签匹配策略中的分类对齐度 alignment_metrics 进行了归一化, 得到归一化 𝑡^。 具体实现方式为:

对于每一个 Gt,找到所有样本中与 Gt 最大的 IoU,具有最大 alignment_metrics 的样本位置的 𝑡^=𝑚𝑎𝑥(𝐼𝑜𝑢)

\[\hat{t} = AlignmentMetrics / max(AlignmentMetrics) * max(IoU)\]

最终 YOLOv6 分类损失损失函数为:

\[\begin{split}{VFL}(p,\hat{t})= \begin{cases} -\hat{t}(\hat{t}log(p) +(1-\hat{t})log(1-p)), & \hat{t} > 0 \\ -\alpha p^\gamma log(1-p), & \hat{t} = 0 \end{cases}\end{split}\]

MMDetection 实现源码的核心部分:

def varifocal_loss(pred, target, alpha=0.75, gamma=2.0, iou_weighted=True):
    """
        pred (torch.Tensor): 预测的分类分数,形状为 (B,N,C) , N 表示 anchor 数量, C 表示类别数
        target (torch.Tensor): 经过对齐度归一化后的 IoU 分数,形状为 (B,N,C),数值范围为 0~1
        alpha (float, optional): 调节正负样本之间的平衡因子,默认 0.75.
        gamma (float, optional): 负样本 focal 权重因子, 默认 2.0.
        iou_weighted (bool, optional): 正样本是否用 IoU 加权
    """
    pred_sigmoid = pred.sigmoid()
    target = target.type_as(pred)
    if iou_weighted:
        # 计算权重,正样本(target > 0)中权重为 target,
        # 负样本权重为 alpha*pred_simogid^2
        focal_weight = target * (target > 0.0).float() + \
            alpha * (pred_sigmoid - target).abs().pow(gamma) * \
            (target <= 0.0).float()
    else:
        focal_weight = (target > 0.0).float() + \
            alpha * (pred_sigmoid - target).abs().pow(gamma) * \
            (target <= 0.0).float()
    # 计算二值交叉熵后乘以权重
    loss = F.binary_cross_entropy_with_logits(
        pred, target, reduction='none') * focal_weight
    loss = weight_reduce_loss(loss, weight, reduction, avg_factor)
    return loss

回归损失函数 GIoU Loss / SIoU Loss

在 YOLOv6 中,针对不同大小的模型采用了不同的回归损失函数,其中 l/m/s使用的是 GIoULoss, t/n 用的是 SIoULoss

其中 GIoULoss 详情请看 GIoU详解

SIou Loss

SIoU 损失函数是 SIoU Loss: More Powerful Learning for Bounding Box Regression 中提出的度量预测框与 GT 的匹配度的指标,由于之前的GIoUCIoUDIoU 都没有考虑预测框向 GT 框回归的角度,然而角度也确实是回归中一个重要的影响因素,因此提出了全新的SIoU

SIoU 损失主要由四个度量方面组成:

  • IoU成本
  • 角度成本
  • 距离成本
  • 形状成本

如下图所示,角度成本 就是指图中预测框 𝐵 向 𝐵𝐺𝑇 的回归过程中, 尽可能去使得优化过程中的不确定性因素减少,比如现将图中的角度 𝛼 或者 𝛽 变为 0 ,再去沿着 x 轴或者 y 轴去回归边界。

image.png

MMYOLO 实现源码的核心部分:


def bbox_overlaps(bboxes1, bboxes2, mode='siou', is_aligned=False, eps=1e-6):
    # 两个box的顶点x1,y1,x2,y2
    bbox1_x1, bbox1_y1 = pred[:, 0], pred[:, 1]
    bbox1_x2, bbox1_y2 = pred[:, 2], pred[:, 3]
    bbox2_x1, bbox2_y1 = target[:, 0], target[:, 1]
    bbox2_x2, bbox2_y2 = target[:, 2], target[:, 3]
    # 交集
    overlap = (torch.min(bbox1_x2, bbox2_x2) -
               torch.max(bbox1_x1, bbox2_x1)).clamp(0) * \
              (torch.min(bbox1_y2, bbox2_y2) -
               torch.max(bbox1_y1, bbox2_y1)).clamp(0)
    # 并集
    w1, h1 = bbox1_x2 - bbox1_x1, bbox1_y2 - bbox1_y1
    w2, h2 = bbox2_x2 - bbox2_x1, bbox2_y2 - bbox2_y1
    union = (w1 * h1) + (w2 * h2) - overlap + eps
    # IoU = 交集/并集
    ious = overlap / union
    # 最小外界矩的宽高
    enclose_x1y1 = torch.min(pred[:, :2], target[:, :2])
    enclose_x2y2 = torch.max(pred[:, 2:], target[:, 2:])
    enclose_wh = (enclose_x2y2 - enclose_x1y1).clamp(min=0)
    enclose_w = enclose_wh[:, 0]  # enclose_w
    enclose_h = enclose_wh[:, 1]  # enclose_h
    elif iou_mode == 'siou':
        # 1.计算 σ (两个box中心点距离):
        # sigma_cw,sigma_ch:上图中cw,ch
        sigma_cw = (bbox2_x1 + bbox2_x2) / 2 - (bbox1_x1 + bbox1_x2) / 2 + eps
        sigma_ch = (bbox2_y1 + bbox2_y2) / 2 - (bbox1_y1 + bbox1_y2) / 2 + eps
        sigma = torch.pow(sigma_cw**2 + sigma_ch**2, 0.5)

        # 2. 在 α 和 β 中选择一个小的角度(小于π/4)去优化
        sin_alpha = torch.abs(sigma_ch) / sigma
        sin_beta = torch.abs(sigma_cw) / sigma
        sin_alpha = torch.where(sin_alpha <= math.sin(math.pi / 4), sin_alpha,
                                sin_beta)

        # 角度损失 = 1 - 2 * ( sin^2 ( arcsin(x) - (π / 4) ) ) = cos(2α-π/2) = sin(2α)
        # 这里就是角度损失,当 α=0 或者 α=90° 时损失为 0, 当 α=45° 损失为 1
        angle_cost = torch.cos(torch.arcsin(sin_alpha) * 2 - math.pi / 2)

        # 3.这里将角度损失与距离损失进行融合
        # Distance cost = Σ_(t=x,y) (1 - e ^ (- γ ρ_t))
        rho_x = (sigma_cw / enclose_w)**2  # ρ_x:x轴中心点距离距离损失
        rho_y = (sigma_ch / enclose_h)**2  # ρ_y:y轴中心点距离距离损失
        gamma = 2 - angle_cost  # γ
        # 当 α=0, angle_cost=0, gamma=2, dis_cost_x =  1 - e ^ (-2 p_x),因为 ρ_x>0, 主要优化距离
        # 当 α=45°,angle_cost=1, gamma=1, dis_cost_x =  1 - e ^ (-1* p_x),因为 ρ_x<1, 主要优化角度
        distance_cost = (1 - torch.exp(-1 * gamma * rho_x)) + (
            1 - torch.exp(-1 * gamma * rho_y))

        # 4.形状损失 就是两个box之间的宽高比
        # Shape cost = Ω = Σ_(t=w,h) ( ( 1 - ( e ^ (-ω_t) ) ) ^ θ )
        omiga_w = torch.abs(w1 - w2) / torch.max(w1, w2)  # ω_w
        omiga_h = torch.abs(h1 - h2) / torch.max(h1, h2)  # ω_h
        shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w),
                               siou_theta) + torch.pow(
                                   1 - torch.exp(-1 * omiga_h), siou_theta)

        # 5.综合 IoU、角度、距离以及形状信息
        # SIoU = IoU - ( (Distance Cost + Shape Cost) / 2 )
        ious = ious - ((distance_cost + shape_cost) * 0.5)

    return ious.clamp(min=-1.0, max=1.0)

@weighted_loss
def siou_loss(pred, target, eps=1e-7):
    sious = bbox_overlaps(pred, target, mode='siou', is_aligned=True, eps=eps)
    loss = 1 - sious
    return loss

Object Loss

在 YOLOv6 中,由于额外的置信度预测头可能与 Aligned Head 有所冲突,经实验验证在不同大小的模型上也都有掉点, 所以最后选择弃用 Objectness 分支。

Reference

想读懂YOLOV4,你需要先了解下列技术(一)

YOLOv4

MMYOLO