YOLOv5-理论部分

YOLOv5

作者: Ultralytics

论文源码: https://github.com/ultralytics/yolov5

Ultralytics:“超视觉技术” / “超视觉系统”

0. 引言

“YOLOv5 🚀 是世界上备受喜爱的视觉人工智能,代表了 Ultralytics 对未来视觉人工智能方法的开源研究,融合了数千小时的研究和开发经验中所学到的教训和最佳实践。”


YOLOv5 仓库是在 2020-05-18 创建的,到今天已经迭代了很多个大版本了,现在已经迭代到 v7.0 了。下表是当前 (v7.0 / v6.1) 官网贴出的关于不同大小模型以及输入尺度对应的 mAP、推理速度(Speed)、参数数量(params)以及理论计算量(FLOPs)。

Modelsize(pixels)mAPval0.5:0.95mAPval0.5SpeedCPU b1(ms)SpeedV100 b1(ms)SpeedV100 b32(ms)params(M)FLOPs@640 (B)
YOLOv5n64028.045.7456.30.61.94.5
YOLOv5s64037.456.8986.40.97.216.5
YOLOv5m64045.464.12248.21.721.249.0
YOLOv5l64049.067.343010.12.746.5109.1
YOLOv5x64050.768.976612.14.886.7205.7
YOLOv5n6128036.054.41538.12.13.24.6
YOLOv5s6128044.863.73858.23.612.616.8
YOLOv5m6128051.369.388711.16.835.750.0
YOLOv5l6128053.771.3178415.810.576.8111.4
YOLOv5x6+ TTA1280153655.055.872.772.73136-26.2-19.4-140.7-209.8-

1. 网络结构

YOLOv5 的网络结构主要由以下几部分组成:

  1. Backbone: New CSP-Darknet53
    这是网络的主体部分。对于 YOLOv5,主干网络采用了 New CSP-Darknet53 结构,这是对先前版本中使用的 Darknet 架构的修改。
  2. Neck: SPPF, New CSP-PAN
    这部分连接了主干网络和头部。在 YOLOv5 中,使用了 SPPF 和 New CSP-PAN 结构。
  3. Head: YOLOv3 Head
    这部分负责生成最终的输出。YOLOv5 使用 YOLOv3 头部来实现这一目标。

关模型结构的详细信息可以在 yolov5l.yaml 中找到

下面是官方根据 yolov5l.yaml 绘制的网络整体结构,YOLOv5 不同大小(n, s, m, l, x)的网络整体架构都是一样的,只不过会在每个子模块中采用不同的深度和宽度,分别应对 .yaml 文件中的 depth_multiplewidth_multiple 参数。还需要注意一点,官方除了 n, s, m, l, x 版本外还有 n6, s6, m6, l6, x6,区别在于后者是针对更大分辨率的图片比如 1280 × 1280 1280\times 1280 1280×1280,当然结构上也有些差异,后者会 64 倍下采样,4 个预测特征层,而前者只会下采样到 32 倍且采用 3 个预测特征层。本文只讨论前者。

在这里插入图片描述

高清大图:yolov5-arch.png

注意:YOLOv5 相对于其前身引入了一些小的改变:

  • 早期版本中的 Focus 结构被替换为 6x6 Conv2d 结构。这个变化提高了效率 #4825。
  • SPP 结构被替换为 SPPF。这个改变使处理速度增加了一倍多。
  • 要测试 SPP 和 SPPF 的速度,可以使用以下代码:
展开/折叠
import time
import torch
import torch.nn as nnclass SPP(nn.Module):def __init__(self):super().__init__()self.maxpool1 = nn.MaxPool2d(5, 1, padding=2)self.maxpool2 = nn.MaxPool2d(9, 1, padding=4)self.maxpool3 = nn.MaxPool2d(13, 1, padding=6)def forward(self, x):o1 = self.maxpool1(x)o2 = self.maxpool2(x)o3 = self.maxpool3(x)return torch.cat([x, o1, o2, o3], dim=1)class SPPF(nn.Module):def __init__(self):super().__init__()self.maxpool = nn.MaxPool2d(5, 1, padding=2)def forward(self, x):o1 = self.maxpool(x)o2 = self.maxpool(o1)o3 = self.maxpool(o2)return torch.cat([x, o1, o2, o3], dim=1)def main():input_tensor = torch.rand(8, 32, 16, 16)spp = SPP()sppf = SPPF()output1 = spp(input_tensor)output2 = sppf(input_tensor)print(torch.equal(output1, output2))t_start = time.time()for _ in range(100):spp(input_tensor)print(f"SPP time: {time.time() - t_start}")t_start = time.time()for _ in range(100):sppf(input_tensor)print(f"SPPF time: {time.time() - t_start}")if __name__ == '__main__':main()
True
SPP time: 0.5373051166534424
SPPF time: 0.20780706405639648

通过对比可以发现,两者的计算结果是一模一样的,但 SPPF 比 SPP 计算速度快了不止两倍,快乐翻倍 😂。

1.1 Backbone

通过与上篇博文讲的 YOLOv4 对比,其实YOLOv5 在 Backbone 部分没太大变化。但是 YOLOv5 在 v6.0 版本后相比之前版本有一个很小的改动,把网络的第一层(原来是 Focus 模块)换成了一个 6 × 6 6×6 6×6 大小的卷积层(nn.Conv2d)。两者在理论上其实等价的,但是对于现有的一些 GPU 设备(以及相应的优化算法)使用 6 × 6 6×6 6×6 大小的卷积层比使用 Focus 模块更加高效。详情可以参考这个issue #4825 -> Is the Focus layer equivalent to a simple Conv layer?。

下图是原来的 Focus 模块(和之前 Swin Transformer 中的 Patch Merging 类似),将每个 2 × 2 2×2 2×2 的相邻像素划分为一个 patch,然后将每个 patch 中相同位置(同一颜色)像素给拼在一起就得到了 4 个 feature map,然后在接上一个 3 × 3 3×3 3×3 大小的卷积层。这和直接使用一个 6 × 6 6×6 6×6 大小的卷积层等效。

在这里插入图片描述

1.2 Neck

YOLOv5 在 Neck 部分的变化还是相对较大的,首先是将 SPP 换成成了 SPPF(Spatial Pyramid Pooling - Fast, 是 Glenn Jocher 自己设计的),两者的作用是一样的,但后者效率更高

1.2.1 SPP (Spatial Pyramid Pooling,空间金字塔池化)

SPP 结构如下图所示,是将输入并行通过多个不同大小的 MaxPool,然后做进一步融合,能在一定程度上解决目标多尺度问题。

在这里插入图片描述

每一个分支得到 feature map 的 shape 都一样 , 最后会实现通道数 × 4 ×4 ×4

关于 SPP 的介绍可以看文章:[语义分割] ASPP不同版本对比(DeepLab、DeepLab v1、DeepLab v2、DeepLab v3、DeepLab v3+、LR-ASPP)

1.2.2 SPPF (Spatial Pyramid Pooling Fast,快速空间金字塔池化)

而 SPPF 结构是将输入串行通过多个 5 × 5 5×5 5×5 大小的 MaxPool 层,这里需要注意的是串行两个 5 × 5 5×5 5×5 大小的 MaxPool 层是和一个 9 × 9 9×9 9×9 大小的 MaxPool 层计算结果是一样的,串行三个 5 × 5 5×5 5×5 大小的 MaxPool 层是和一个 13 × 13 13×13 13×13 大小的 MaxPool 层计算结果是一样的。

在这里插入图片描述

SPPF 最后同样会实现通道数 × 4 ×4 ×4

SPPF的代码如下:

class SPPF(nn.Module):# Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocherdef __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))super().__init__()c_ = c1 // 2  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c_ * 4, c2, 1, 1)self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)def forward(self, x):x = self.cv1(x)  # 先通过CBL进行通道数的减半with warnings.catch_warnings():warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warningy1 = self.m(x)y2 = self.m(y1)# 上述两次最大池化# 将原来的x,一次池化后的y1,两次池化后的y2,3次池化的self.m(y2)先进行拼接,然后再CBLreturn self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1))

1.2.4 CSP-PAN(跨阶段部分网络-路径聚合网络)

前置小知识
  • CSP: Cross-Stage Partial Network,跨阶段部分网络
  • PAN: Path Aggregation Network,路径聚合网络
   Input                      Input|                          |Backbone                   Backbone|                          |Neck                      Neck/    \                  /     \
Part A   Part B         Part A   Part B\     /                  \     /Concatenation              Concatenation|                          |Head                       Head|                          |Output                     OutputFig.1 CSP                 Fig.2 PAN

在这个示意图中:

  • CSP 结构将输入通过主干网络(Backbone)分成两部分,分别经过两个部分(Part A 和 Part B)的处理,然后再将它们连接在一起(Concatenation)。接下来,特征图进入颈部(Neck),最后到达头部(Head),产生最终的输出。这种结构有助于提高模型的性能和准确性。
  • PAN 结构将输入通过主干网络(Backbone),然后进入颈部(Neck),颈部后分成两部分,分别通过两个部分(Part A 和 Part B)的处理,最后再次合并(Concatenation)后经过头部(Head)生成输出。

在 Neck 部分另外一个不同点就是 New CSP-PAN 了,在 YOLOv4 中,Neck 的 PAN 结构是没有引入 CSP 结构的,但在 YOLOv5 中作者在 PAN 结构中加入了 CSP。详情见上面的网络结构图,每个 C3 模块里都含有 CSP 结构。

CSP 结构是在 CSPNet(Cross Stage Partial Network)论文中提出的,CSPNet 作者说在目标检测任务中使用 CSP 结构有如下好处:

  • Strengthening learning ability of a CNN:增强 CNN 的学习能力
  • Removing computational bottlenecks:移除计算瓶颈
  • Reducing memory costs:减少 MACs

CSP 的加入可以: 减少网络的计算量以及对显存的占用,同时保证网络的能力不变或者略微提升。CSP 结构的思想参考原论文中绘制的 CSPDenseNet,进入每个 stage(一般在下采样后)先将数据划分成俩部分,如下图左图所示的 Part1 和 Part2。

在这里插入图片描述

左边的图是 CSPDenseNet(来源于 CSPNet 论文)。CSP 结构会将网络分为两个部分。Part2 分支首先会经过一系列的 Block(这里是 DenseBlock),最后经过 Transition,得到输出后再与 Part1 上的输出进行 Transition 融合。

1.3 Head

在 Head 部分,YOLOv3, v4, v5 都是一样的。

2. 数据增强策略

在 YOLOv5 代码里,关于数据增强策略还是挺多的,这里简单罗列部分方法:

2.1 Mosaic,马赛克增强

核心思想:将 4 张图片拼成一张图片。

在这里插入图片描述

2.2 Copy Paste,复制粘贴增强

将部分目标随机的粘贴到图片中,前提是数据要有分割数据才行,即每个目标的实例分割信息。下面是 Copy paste 原论文中的示意图。

在这里插入图片描述

可以理解为是升级版的 Mosaic

2.3 Random affine,随机放射变换 (Rotation, Scale, Translation and Shear)

随机进行仿射变换,但根据配置文件里的超参数发现只使用了 Scale (缩放)和 Translation (平移)。

在这里插入图片描述

参考资料:数据增强中的仿射变换:旋转,缩放,平移以及错切(shear)

2.4 MixUp,混合数据增强

Mixup 就是将两张图片按照一定的透明度融合在一起,具体有没有用不太清楚,毕竟没有论文,也没有消融实验。代码中只有较大的模型才使用到了 MixUp,而且每次只有 10 % 10\% 10% 的概率会使用到。

在这里插入图片描述

2.5 Albumentations

主要是做些滤波、直方图均衡化以及改变图片质量等等,代码里写的只有安装了 albumentations 包才会启用,但在项目的 requirements.txt 文件中 albumentations 包被注释掉了的,所以 默认不启用

# Extras ----------------------------------------------------------------------
# ipython  # interactive notebook
# mss  # screenshots
# albumentations>=1.0.3
# pycocotools>=2.0.6  # COCO mAP

“Albumentations” 这个名称通常不会被翻译,因为它是一个特定的计算机视觉数据增强库的名称。如果需要提到这个库,通常会直接保留原名 “Albumentations”。

Albumentations官方文档: https://albumentations.readthedocs.io/en/latest/

Albumentations 基本介绍

albumentations 是一个给予 OpenCV 的快速训练数据增强库,拥有非常简单且强大的可以用于多种任务(分割、检测)的接口,易于定制且添加其他框架非常方便。

它可以对数据集进行逐像素的转换,如:

  1. 模糊
  2. 下采样
  3. 高斯造点
  4. 高斯模糊
  5. 动态模糊
  6. RGB转换
  7. 随机雾化

也可以进行空间转换(同时也会对目标进行转换),如:

  • 裁剪
  • 翻转
  • 随机裁剪等。

github 及其示例地址如下:

GitHub: https://github.com/albumentations-team/albumentations
示例:https://github.com/albumentations-team/albumentations_examples

参考: https://zhuanlan.zhihu.com/p/107399127/

2.6 Augment HSV(Hue, Saturation, Value)

随机调整色度,饱和度以及明度。

在这里插入图片描述

2.7 Random horizontal flip,随机水平翻转

在这里插入图片描述

3. 训练策略

在 YOLOv5 源码中使用到了很多训练的策略,这里简单总结几个:

  1. Multi-scale training(0.5~1.5x)(多尺度训练):假设设置输入图片的大小为 640 × 640 640 \times 640 640×640,训练时采用尺寸是在 0.5 × 640 ∼ 1.5 × 640 0.5 \times 640 \sim 1.5 \times 640 0.5×6401.5×640 之间随机取值,注意取值时取得都是 32 的整数倍(因为网络会最大下采样 32 倍)。
  2. AutoAnchor(For training custom data)(自动聚类生产 Anchor 模板):训练自己数据集时可以根据自己数据集里的目标进行重新聚类生成 Anchors 模板。
  3. Warmup and Cosine LR scheduler(带有 Warmup 的余弦调度器):训练前先进行 Warmup 热身,然后在采用 Cosine 学习率下降策略。
  4. EMA(Exponential Moving Average)(指数移动平均):可以理解为给训练的参数(模型参数)加了一个动量,让它更新过程更加平滑。
  5. Mixed precision(混合精度训练):能够减少显存的占用并且加快训练速度,前提是GPU硬件支持。
  6. Evolve hyper-parameters(超参数优化):没有炼丹经验的人勿碰,保持默认就好。
Evolve Hyper-parameters 简介

“Evolve hyper-parameters” 指的是在机器学习和深度学习中,通过优化算法或搜索策略来动态地调整模型的超参数(Hyperparameters),以提高模型的性能和泛化能力。超参数是指那些不是由模型自动学习而是需要手动设置的参数,它们通常用于控制模型的结构、学习率、正则化等方面。

“Evolve” 表示超参数可以通过不断地尝试不同的值来进行迭代调整,以找到最优的超参数组合。这种过程通常涉及超参数搜索和优化技术,如网格搜索、随机搜索、贝叶斯优化等。

通过进化超参数,可以实现以下目标:

  1. 提高模型性能:通过找到最佳的超参数组合,模型的性能通常会得到显著的提升。这包括准确性、泛化能力和训练效率。

  2. 防止过拟合:适当的超参数选择可以帮助防止模型过拟合训练数据,从而提高模型的泛化能力。

  3. 节省时间和资源:有效的超参数优化可以节省训练时间和计算资源,因为它可以避免不必要的试验和训练周期。

  4. 适应不同任务:通过调整超参数,可以使同一模型适应不同类型的任务,而无需重新设计整个模型。

总之,“evolve hyper-parameters” 意味着通过智能的搜索和优化技术来改进模型的性能和适应性,而不是仅仅手动选择固定的超参数值。这是机器学习和深度学习中重要的实践,以实现更好的结果。

4. 其他

4.1 损失计算

YOLOv5 的损失主要由三个部分组成:

  1. Classes loss(分类损失): 采用的是 BCE loss,注意只计算正样本的分类损失。
  2. Objectness loss(obj 损失(置信度损失)): 采用的依然是 BCE loss,注意这里的 obj 指的是网络预测的目标边界框与 Ground True 的 CIoU。这里计算的是所有样本的 obj 损失。
  3. Location loss(定位损失): 采用的是 CIoU loss,注意只计算正样本的定位损失。

L a l l = λ 1 L c l s + λ 2 L o b j + λ 3 L l o c {\mathcal L}_{all} = \lambda_1 {\mathcal L}_{\rm cls} + \lambda_2 {\mathcal L}_{\rm obj} + \lambda_3 {\mathcal L}_{\rm loc} Lall=λ1Lcls+λ2Lobj+λ3Lloc

其中, λ 1 , λ 2 , λ 3 \lambda_1, \lambda_2, \lambda_3 λ1,λ2,λ3 为平衡系数。

4.2 平衡不同尺度的损失

这里是指针对三个预测特征层(P3, P4, P5)上的 obj损失 采用不同的权重。在源码中,针对预测小目标的预测特征层(P3)采用的权重是 4.0,针对预测中等目标的预测特征层(P4)采用的权重是 1.0,针对预测大目标的预测特征层(P5)采用的权重是 0.4,作者说这是针对 COCO 数据集设置的超参数。

L o b j = 4.0 × L o b j s m a l l + 1.0 × L o b j m e d i u m + 0.4 × L l a r g e s m a l l {\mathcal L}_{\rm obj} = 4.0 \times {\mathcal L}^{\rm small}_{\rm obj} + 1.0 \times {\mathcal L}^{\rm medium}_{\rm obj} + 0.4 \times {\mathcal L}^{\rm small}_{\rm large} Lobj=4.0×Lobjsmall+1.0×Lobjmedium+0.4×Llargesmall

4.3 消除 Grid 敏感度 (Eliminating grid sensitivity)

在 YOLOv4 中有提到过,主要是调整预测目标中心点相对 Grid 网格的左上角偏移量。下图是 YOLOv2 和 YOLOv3 的计算公式。

其中:

  • t x t_x tx 是网络预测的目标中心 x x x 坐标偏移量(相对于网格的左上角)
  • t y t_y ty 是网络预测的目标中心 y y y 坐标偏移量(相对于网格的左上角)
  • c x c_x cx 是对应网格左上角的 x x x 坐标
  • c y c_y cy 是对应网格左上角的 y y y 坐标
  • σ \sigma σ 是 sigmoid 激活函数,将预测的偏移量限制在0到1之间,即预测的中心点不会超出对应的 Grid Cell 区域

关于预测目标中心点相对 Grid 网格左上角 ( c x , c y ) (c_x, c_y) (cx,cy) 偏移量为 σ ( t x ) , σ ( t y ) \sigma(t_x), \sigma(t_y) σ(tx),σ(ty)。YOLOv4 的作者认为这样做不太合理,比如当真实目标中心点非常靠近网格的左上角点 σ ( t x ) \sigma(t_x) σ(tx) σ ( t y ) \sigma(t_y) σ(ty) 应该趋近与 0 或者右下角点( σ ( t x ) \sigma(t_x) σ(tx) σ ( t y ) \sigma(t_y) σ(ty) 应该趋近与 1)时,网络的预测值需要负无穷或者正无穷时才能取到,而这种很极端的值网络一般无法达到。

为了解决这个问题,作者对偏移量进行了缩放从原来的 ( 0 , 1 ) (0, 1) (0,1) 缩放到 ( − 0.5 , 1.5 ) (-0.5, 1.5) (0.5,1.5) 这样网络预测的偏移量就能很方便达到 0 或 1,故最终预测的目标中心点 b x , b y b_x, b_y bx,by 的计算公式为:

b x = ( 2 ⋅ σ ( t x ) − 0.5 ) + c x b y = ( 2 ⋅ σ ( t y ) − 0.5 ) + c y b_x = \left( 2 \cdot \sigma(t_x) - 0.5 \right) + c_x \\ b_y = \left( 2 \cdot \sigma(t_y) - 0.5 \right) + c_y bx=(2σ(tx)0.5)+cxby=(2σ(ty)0.5)+cy

下面是霹雳吧啦Wz绘制的 y = σ ( x ) y = \sigma(x) y=σ(x) 对应sigma曲线和 y = 2 ⋅ σ ( x ) − 0.5 y = 2 \cdot \sigma(x) - 0.5 y=2σ(x)0.5 对应scale曲线。

很明显通过引入缩放系数 scale 以后, x x x 在同样的区间内, y y y 的取值范围更大,或者说, y y y x x x 更敏感了。并且偏移的范围由原来 ( 0 , 1 ) (0, 1) (0,1) 调整到了 ( − 0.5 , 1.5 ) (-0.5, 1.5) (0.5,1.5)

b w , b h b_w, b_h bw,bh 保持 YOLOv3 的策略不变。


在 YOLOv5 中除了调整预测 Anchor 相对 Grid 网格左上角 ( c x , c y ) (c_x, c_y) (cx,cy) 偏移量以外,还调整了预测目标高宽的计算公式,之前是:

b w = p w ⋅ e t w b h = p h ⋅ e t h b_w = p_w \cdot e^{t_w} \\ b_h = p_h \cdot e^{t_h} bw=pwetwbh=pheth

在 YOLOv5 中被作者调整为:

b w = p w ⋅ ( 2 ⋅ σ ( t w ) ) 2 b h = p h ⋅ ( 2 ⋅ σ ( t h ) ) 2 b_w = p_w \cdot (2 \cdot \sigma(t_w))^2 \\ b_h = p_h \cdot (2 \cdot \sigma(t_h))^2 bw=pw(2σ(tw))2bh=ph(2σ(th))2

作者 Glenn Jocher 对此修改的原话如下,也可以参考issue #471:

The original yolo/darknet box equations have a serious flaw. Width and Height are completely unbounded as they are simply out=exp(in), which is dangerous, as it can lead to runaway gradients, instabilities, NaN losses and ultimately a complete loss of training.

原始的 YOLO/Darknet box 公式存在严重缺陷。宽度和高度完全无限制,因为它们仅为 out = exp(in),这是危险的,因为它可能导致梯度失控、不稳定、NaN 损失,最终完全失去训练的能力。

作者的大致意思是,原来的计算公式并没有对预测目标宽高做限制,这样可能出现梯度爆炸,训练不稳定等问题。下图是修改前 y = e x y = e^x y=ex 和修改后 y = ( 2 ⋅ σ ( x ) ) 2 y = (2 \cdot \sigma(x))^2 y=(2σ(x))2 (相对Anchor宽高的倍率因子)的变化曲线, 很明显调整后倍率因子被限制在 ( 0 , 4 ) (0, 4) (0,4) 之间。

4.4 匹配样本 (Build Targets)

之前在 YOLOv4 介绍中有讲过该部分内容,其实 YOLOv5 也差不多。主要的区别在于 GT Box 与 Anchor Templates 模板的匹配方式。在 YOLOv4 中是直接将每个 GT Box 与对应的 Anchor Templates 模板计算 IoU,只要 IoU 大于设定的阈值就算匹配成功。但在 YOLOv5 中,作者先去计算每个 GT Box 与对应的 Anchor Templates 模板的高宽比例,即:

r w = w g t w a t r h = h g t h w a t r_w = \frac{w_{gt}}{w_{at}} \\ r_h = \frac{h_{gt}}{hw_{at}} rw=watwgtrh=hwathgt

然后统计这些比例和它们倒数之间的最大值,这里可以理解成计算 GT Box 和 Anchor Templates 分别在宽度以及高度方向的最大差异(当相等的时候比例为 1,差异最小):

r w max ⁡ = max ⁡ ( r w , 1 r w ) r h max ⁡ = max ⁡ ( r h , 1 r h ) r^{\max}_w = \max(r_w, \frac{1}{r_w}) \\ r^{\max}_h = \max(r_h, \frac{1}{r_h}) rwmax=max(rw,rw1)rhmax=max(rh,rh1)

接着统计 r w max ⁡ r_w^{\max} rwmax r h max ⁡ r_h^{\max} rhmax 之间的最大值,即宽度和高度方向差异最大的值:

r max ⁡ = max ⁡ ( r w max ⁡ , r h max ⁡ ) r^{\max} = \max(r_w^{\max}, r_h^{\max}) rmax=max(rwmax,rhmax)

如果 GT Box 和对应的 Anchor Template 的 r m a x r^{max} rmax 小于阈值 anchor_t(在源码中默认设置为 4.0),即 GT Box 和对应的 Anchor Template 的高、宽比例相差不算太大,则将 GT Box 分配给该 Anchor Template 模板。为了方便大家理解,可以看下图。

假设对某个 GT Box 而言,其实只要 GT Box 满足在某个 Anchor Template 宽和高的 × 0.25 \times 0.25 ×0.25 倍和 × 4.0 \times 4.0 ×4.0 倍之间就算匹配成功。

剩下的步骤和 YOLOv4 中一致:

将 GT 投影到对应预测特征层上,根据 GT 的中心点定位到对应 Cell,注意图中有三个对应的 Cell。因为网络预测中心点的偏移范围已经调整到了 ( − 0.5 , 1.5 ) (-0.5, 1.5) (0.5,1.5),所以按理说只要 Grid Cell 左上角点距离 GT 中心点在 ( − 0.5 , 1.5 ) (−0.5, 1.5) (0.5,1.5) 范围内它们对应的 Anchor 都能回归到 GT 的位置处。这样会让正样本的数量得到大量的扩充。

则这三个 Cell 对应的 AT2 和 AT3 都为正样本。

还需要注意的是,YOLOv5 源码中扩展 Cell 时只会往上、下、左、右 四个方向 扩展,不会往左上、右上、左下、右下方向扩展。

下面又给出了一些根据 G T x c e n t e r GT_x^{center} GTxcenter, G T y c e n t e r GT_y^{center} GTycenter 的位置扩展的一些 Cell 案例,其中 %1 表示取余并保留小数部分。

到此,YOLOv5 相关理论的内容基本上都分析完了。

知识来源

  1. YOLOv5网络详解
  2. YOLOv5网络详解

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

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

相关文章

Confluence 内容管理

1.创建页面 功能入口: Confluence →指定空间→创建 功能说明: (1)为保证页面风格统一,建议各类内容应统一选择对应模板创建 (2)页面应配置可查看用户,以及用户编辑、查看权限 …

《golang设计模式》第三部分·行为型模式-01-责任链模式(Chain of Responsibility)

文章目录 1 概念1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1 概念 责任链(Chain of Responsibility)是指将客户端请求处理的不同职责对象组成请求处理链。 客户端只需要将请求交付到该链上,而不需要关心链上含有哪些对象。请求…

Hadoop3教程(十五):MapReduce中的Combiner

文章目录 (103)Combiner概述什么是CombinerCombiner有什么用处Combiner有什么特点如何自定义Combiner (104)Combiner合并案例实操如何从日志里查看Combiner如果不存在Reduce阶段,会发生什么自定义Combiner的两种方式 参…

论文阅读:Point-to-Voxel Knowledge Distillation for LiDAR Semantic Segmentation

来源:CVPR 2022 链接:https://arxiv.org/pdf/2206.02099.pdf 0、Abstract 本文解决了将知识从大型教师模型提取到小型学生网络以进行 LiDAR 语义分割的问题。由于点云的固有挑战,即稀疏性、随机性和密度变化,直接采用以前的蒸馏…

正点原子嵌入式linux驱动开发——设备树下LED驱动

经过对设备树的学习以及驱动开发中常用的OF函数介绍,本篇笔记将之前的新字符设备驱动的LED,换成设备树形式。 设备树LED驱动原理 在之前的新字符设备驱动实验中,直接在驱动文件newchrled.c中定义有关寄存器物理地址,然后使用io_…

Groovy语法Gradle配置学习笔记

第一部分:Groovy语法 变量的类型和定义 Groovy所有类型都是对象类型: int x 10 println x.class double y 3.14 println y.classdef 定义变量: def str "dddd" println str.class字符串 字符串: // 单引号 双引号…

el-input: 把不符合正则校验的值动态清空,只保留符合的值

<el-input v-model"form.profit" placeholder"请输入授权专利新增利润" input"handleInput" clearable />/*** 不符合正则校验,清空*/const handleInput () > {if (form.value.profit) {if (!/^\d*\.?\d*$/.test(form.value.profit))…

基于STM32_DHT11单总线温湿度传感器驱动

基于STM32_DHT11单总线温湿度传感器驱动 文章目录 基于STM32_DHT11单总线温湿度传感器驱动前言一、DHT11&#xff1f;二、原理1.时序1.主机复位信号和 DHT11 响应信号2.信号‘0’的表示3.信号‘1’的表示4.整个数据信号收发流程 2.数据结构 三、驱动1 .h文件&#xff1a;2 .c文…

CSS 笔记/练习

CSS 概述 与 html 配合&#xff0c;实现内容与样式分离样式美化 标签中元素作用 class&#xff1a;class属性用于为元素指定一个或多个样式类。通过为元素添加class属性&#xff0c;可以将其与CSS样式表中的样式规则关联起来&#xff0c;从而改变元素的外观和行为。一个元素可…

网络工程师知识点7

111、IS-IS路由器的三种类型&#xff1f; Level-1路由器&#xff08;只能创建level-1的LSDB&#xff09; Level-2路由器&#xff08;只能创建level-2的LSDB&#xff09; Level-1-2路由器&#xff08;路由器默认的类型&#xff0c;能同时创建level-1和level-2的LSDB&#xff09;…

0基础学习VR全景平台篇第109篇:认识拼接软件PTGui Pro

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01;今天给大家讲解我们全景后期拼接软件PTgui pro&#xff0c;下面我们开始吧&#xff01; &#xff08;PTgui pro软件课程大纲&#xff09; 1.PTGui这个软件是什么 发明人 &#xf…

公司如何防止源代码外泄,保护开发部门代码安全呢?

在智能制造业中&#xff0c;研发人员的开发环境&#xff0c;大多数采用c#开发语言svn 或c#git进行软件系统的开发&#xff0c;但是c#语言如何来防泄密保护呢&#xff1f;德人合科技针对于制造类企业制定了安全稳定的源代码防泄密方案&#xff0c;不影响员工的正常工作&#xff…

【数字图像处理笔记】01-数字图像基础

01-数字图像基础 图像类型 黑白(二值)图像 只有黑白两种颜色的图像称为黑白图像或单色图像&#xff0c;图像的每个像素只能是黑或白&#xff0c;没有中间的过渡&#xff0c;故又称为二值图像。 二值图像的像素值只能为0或1&#xff0c;图像中的每个像素值用1位存储。图像矩阵中…

Eudic欧路词典 for Mac(可离线英语学习工具)

Eudic欧路词典是一款功能强大的英语学习工具&#xff0c;旨在为用户提供全面的词汇解释和例句。该软件整合了多个权威词典&#xff0c;包括牛津、柯林斯等&#xff0c;提供了全面准确的词汇解释和用法示例。同时&#xff0c;它还支持离线使用&#xff0c;用户可以在无网络连接的…

EasyExcel

EasyExcel 官方文档 EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel (alibaba.com) 优势 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存&#xff0c;poi有一套SAX模式的API可以一定程度的解决一些内存溢出…

电脑蓝牙与ESP32蓝牙连接,让电脑发现ESP32

win11蓝牙默认只查看常见蓝牙设备。ESP32创建的蓝牙很有可能是看不到的。 再蓝牙设备发现一栏选择高级&#xff0c;才能查看所有蓝牙设备。 只要下面几行代码&#xff0c;就能让PC发现ESP32 #include <BLEDevice.h> // 引入相关库void setup() {BLEDevice::init("…

学习pytorch13 神经网络-搭建小实战Sequential的使用

神经网络-搭建小实战&Sequential的使用 官网模型结构根据模型结构和数据的输入shape&#xff0c;计算用在模型中的超参数coderunning log网络结构可视化 B站小土堆pytorch视频学习 官网 https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html#torch.nn.Se…

图扑智慧仓储数据可视化监控平台

随着市场竞争加剧和市场需求的不断提高&#xff0c;企业亟需更加高效、智能且可靠的仓储物流管理方式&#xff0c;以提升企业的物流效率&#xff0c;减少其输出成本&#xff0c;有效应对市场上的变化和挑战。 图扑软件应用自研 HT for Web 产品搭建的 2D 智慧仓储可视化平台&a…

全流程TOUGH系列软件实践技术应用

查看原文>>>全流程TOUGH系列软件实践技术应用 TOUGH系列软件是由美国劳伦斯伯克利实验室开发的&#xff0c;旨在解决非饱和带中地下水、热运移的通用模拟软件。和传统地下水模拟软件Feflow和Modflow不同&#xff0c;TOUGH系列软件采用模块化设计和有限积分差网格剖分…

JavaScript系列从入门到精通系列第二十篇:使用工厂方法创建JavaScript对象,JavaScript构造函数详解,JavaScript类概念的介绍

文章目录 一&#xff1a;使用工厂方法创建对象 1&#xff1a;原始写法 2&#xff1a;工厂方式 3&#xff1a;结果验证 二&#xff1a;构造函数 1&#xff1a;什么是构造函数 2&#xff1a;构造函数和普通函数的区别 3&#xff1a;构造函数的执行流程 三&#xff1a;类…