YOLOv5-v6.0学习笔记


参考链接:
1. 深入浅出Yolo系列之Yolov5核心基础知识完整讲解
2. yolov5 结构知识点解析
3. yolov5目标检测神经网络——损失函数计算原理

1. 网络结构

1.1 Backbone

YOLOv5-6.0版本的Backbone主要分为Conv模块CSPDarkNet53SPPF模块
YOLOv5-v6.0学习笔记

1.1.1 Conv模块

YOLOv5-v6.0学习笔记
YOLOv5在Conv模块中封装了三个功能:包括卷积(Conv2d)Batch Normalization激活函数,同时使用autopad(k, p)实现了padding的效果。其中YOLOv5-6.0版本使用Swish(或者叫SiLU)作为激活函数,代替了旧版本中的Leaky ReLU

1.1.2 Focus模块

Focus模块是YOLOv5旧版本中的一个模块,它的结构如下图所示。
YOLOv5-v6.0学习笔记

其中核心部分是对图片进行切片(slice)操作,并且在通道维度上进行拼接。如下图所示,对于一张3通道的输入图片,分别在YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记两个维度上,每隔一个像素取一个值,从而构建得到12张特征图。这12张特征图在宽度和高度上变为原来的YOLOv5-v6.0学习笔记,但是通道维度扩充了4倍。同时,这12张特征图包含了输入图片的所有信息,因此Focus模块不仅在减少信息丢失的情况下实现了2倍下采样,而且减少了参数量(params)和计算量(FLOPs),降低了CUDA显存的消耗,从而提升了前向和后向传递的速度。
YOLOv5-v6.0学习笔记

1.1.3 CSPDarkNet53

1.1.3.1 CSPNet

论文链接:https://arxiv.org/abs/1911.11929
CSPNet被提出的主要目的是为了保证在模型检测和识别精度没有下降的情况下,减少计算量,提高推理速度。它的主要思想是通过分割梯度流,使梯度流通过不同的网络路径传播。通过拼接和过渡等操作,从而实现更丰富的梯度组合信息。
YOLOv5-v6.0学习笔记

DenseNet

YOLOv5-v6.0学习笔记

Cross Stage Partial DenseNet

DenseNet为例,在将特征图输入到Dense_Block之前,将特征图从通道维度上分为两个部分,其中一部分进入Dense_Block中进行计算,另一部分则通过一个shortcutDense_Block的输出特征图进行拼接,最后将拼接后的特征图输入到Transition Layer进行卷积操作。

1.1.3.2 Bottleneck模块

YOLOv5-v6.0学习笔记

1.1.3.3 C3模块

YOLOv4和YOLOv5均借鉴了CSPNet的思想,将其运用于DarkNet53骨干网络。YOLOv5-6.0版本中使用了C3模块,替代了早期的BottleneckCSP模块
YOLOv5-v6.0学习笔记

C3模块

YOLOv5-v6.0学习笔记

BottleneckCSP模块

这两者结构作用基本相同,均为CSP架构,只是在修正单元的选择上有所不同,C3模块包含了3个标准卷积层以及多个Bottleneck模块C3模块相对于BottleneckCSP模块所不同的是,经过Bottleneck模块输出后的Conv模块被去掉了。
但是YOLOv4和YOLOv5的Backbone虽然借鉴了CSPNet,但实际上并没有按照CSPNet原论文中那样将输入的特征图在通道维度上划分成两个部分,而是直接用两路的YOLOv5-v6.0学习笔记×YOLOv5-v6.0学习笔记卷积对输入特征图进行变换。
YOLOv5-v6.0学习笔记

1.1.4 SPPF模块

参考链接:https://github.com/ultralytics/yolov5/pull/4420
YOLOv5-6.0版本使用了SPPF模块来代替SPP模块,其中SPPSpatial Pyramid Pooling的简称,即空间金字塔池化,YOLOv5借鉴了SPPNet的思想。
SPPF模块采用多个小尺寸池化核级联代替SPP模块中单个大尺寸池化核,从而在保留原有功能,即融合不同感受野的特征图,丰富特征图的表达能力的情况下,进一步提高了运行速度。
YOLOv5-v6.0学习笔记

SPPF模块

YOLOv5-v6.0学习笔记

SPP模块

1.2 Neck

YOLOv5的Neck与YOLOV4相似,均借鉴了FPNPANet的思想。
YOLOv5-v6.0学习笔记

1.2.1 FPN

论文链接:https://arxiv.org/abs/1612.03144
FPN,即Feature Pyramid Network(特征金字塔)。原来多数的目标检测算法只是采用顶层特征做预测,但我们知道浅层的特征所携带的语义信息较少,而位置信息更强;深层的特征所携带的语义信息较丰富,而位置信息更弱。FPN的思想就是把深层的语义信息传递到浅层,从而增强多个尺度上的语义表达。
YOLOv5-v6.0学习笔记

1.2.2 PANet

论文链接:https://arxiv.org/abs/1803.01534
FPN通过自顶向下(Top-down)的结构,将深层的语义信息传递到浅层,但是浅层的位置信息却无法影响到深层特征。同时,FPN中顶部信息流需要通过骨干网络(Backbone)逐层地往下传递,由于层数相对较多,因此计算量比较大,而PANet有效地解决了上述这些问题。
YOLOv5-v6.0学习笔记

1.3 Head

YOLOv5-v6.0学习笔记

2. 目标框回归

YOLOv5-v6.0学习笔记

3. 正负样本匹配

如上面所述,YOLOv5的每个检测层上的每个网格都预设了多个anchor先验框,但并不是每个网格中都存在目标,也并不是每个anchor都适合用来回归当前目标,因此需要对这些anchor先验框进行筛选,将其划分为正样本和负样本。本文的正负样本指的是预测框而不是Ground Truth(人工标注的真实框)。
与YOLOv3/4不同的是,YOLOv5采用的是基于宽高比例的匹配策略,它的大致流程如下:

  1. 对于每一个Ground Truth(人工标注的真实框),分别计算它与9种不同anchor的宽与宽的比值(w1/w2, w2/w1)和高与高的比值(h1/h2, h2/h1)。
  2. 找到Ground Truthanchor的宽比(w1/w2, w2/w1)和高比(h1/h2, h2/h1)中的最大值,作为该Ground Truthanchor的比值。
  3. Ground Truthanchor的比值小于设定的比值阈值(超参数中默认为anchor_t = 4.0),那么这个anchor就负责预测这个Ground Truth,即这个anchor所回归得到的预测框就被称为正样本,剩余所有的预测框都是负样本。

通过上述方法,YOLOv5不仅筛选了正负样本,同时对于部分Ground Truth在单个尺度上匹配了多个anchor来进行预测,总体上增加了一定的正样本数量。除此以外,YOLOv5还通过以下几种方法增加正样本的个数,从而加快收敛速度。

  1. 跨网格扩充: 假设某个Ground Truth的中心点落在某个检测层上的某个网格中,除了中心点所在的网格之外,其左、上、右、下4个邻域的网格中,靠近Ground Truth中心点的两个网格中的anchor也会参与预测和回归,即一个目标会由3个网格的anchor进行预测,如下图所示。YOLOv5-v6.0学习笔记
  2. 跨分支扩充:YOLOv5的检测头包含了3个不同尺度的检测层,每个检测层上预设了3种不同长宽比的anchor,假设一个Ground Truth可以和不同尺度的检测层上的anchor匹配,则这3个检测层上所有符合条件的anchor都可以用来预测该Ground Truth,即一个目标可以由多个检测层的多个anchor进行预测。

4. 损失计算

4.1 总损失

YOLOv5对特征图上的每个网格进行预测,得到的预测信息与真实信息进行对比,从而指导模型下一步的收敛方向。损失函数的作用就是衡量预测信息和真实信息之间的差距,若预测信息越接近真实信息,则损失函数值越小。YOLOv5的损失主要包含三个方面:矩形框损失(bbox_loss)分类损失(cls_loss)置信度损失(obj_loss)。总损失的表达式为YOLOv5-v6.0学习笔记其中YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记分别对应不同的损失权重,默认值分别为0.05,0.5,1.0。

4.2 边界框损失

论文链接:https://arxiv.org/abs/1911.08287
IoU,即交并比,它的作用是衡量目标检测中预测框与真实框的重叠程度。假设预测框为A,真实框为B,则IoU的表达式为YOLOv5-v6.0学习笔记
YOLOv5-v6.0学习笔记

4.3 分类损失

YOLOv5默认使用二元交叉熵函数来计算分类损失。二元交叉熵函数的定义为YOLOv5-v6.0学习笔记其中YOLOv5-v6.0学习笔记为输入样本对应的标签(正样本为1,负样本为0),YOLOv5-v6.0学习笔记为模型预测该输入样本为正样本的概率。
假设YOLOv5-v6.0学习笔记交叉熵函数的定义可简化为YOLOv5-v6.0学习笔记

4.4 置信度损失

每个预测框的置信度表示这个预测框的可靠程度,值越大表示该预测框越可靠,也表示越接近真实框。如下图所示,红点YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记表示真实框的中心点,那么每个红点所在网格对应的anchor所预测和回归得到的预测框置信度应该比较大甚至接近1,而其它网格对应的预测框置信度则会比较小甚至接近0。
YOLOv5-v6.0学习笔记

tobj[b, a, gj, gi] = (1.0 - self.gr) + self.gr * score_iou

其中self.gr为标签平滑系数,当参数self.gr为1时,置信度标签就等于CIoU
与计算分类损失一样,YOLOv5默认使用二元交叉熵函数来计算置信度损失。除此以外,对于不同尺度的检测层上得到的置信度损失,YOLOv5分配了不同的权重系数,按照检测层尺度从大到小的顺序,对应的默认的权重系数分别为4.0、1.0、0.4,即用于检测小目标的大尺度特征图上的损失权重系数更大,从而使得网络在训练时更加侧重于小目标。

5. 数据增强

5.1 Mosaic

YOLOv5借鉴了YOLOv4中的Mosaic数据增强方法,它是CutMix数据增强方法的进化版,主要思想是任意抽取四张图片进行随机裁剪,然后拼接到一张图片上作为训练数据,同时每张图片上的标注框也会进行相应的裁剪。
YOLOv5-v6.0学习笔记

  1. 假设抽取的每张图片尺寸为YOLOv5-v6.0学习笔记,重新拼接后的图片尺寸为YOLOv5-v6.0学习笔记。在下图的灰色区域中随机生成一个中心点YOLOv5-v6.0学习笔记,从而将平面分割成四块不同大小的区域。
labels4, segments4 = [], []
s = self.img_size
yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border)

YOLOv5-v6.0学习笔记

  1. 在加载第一张图片后,从数据集中再随机抽取三张图片,并打乱这四张图片的顺序。
indices = [index] + random.choices(self.indices, k=3)
random.shuffle(indices)
  1. 将第一张图像放置在左上角的区域,其右下角坐标与随机生成的中心点对齐;将第二张图像放置在右上角的区域,其左下角坐标与随机生成的中心点对齐;将第三张图像放置在左下角的区域,其右上角坐标与随机生成的中心点对齐;将第四张图像放置在右下角的区域,其左上角坐标与随机生成的中心点对齐。
if i == 0:  # top left
	img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8)
	x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc
	x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h
elif i == 1:  # top right
	x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc
	x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h
elif i == 2:  # bottom left
	x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)
	x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h)
elif i == 3:  # bottom right
	x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)
	x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)

img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]  # img4[ymin:ymax, xmin:xmax]
padw = x1a - x1b
padh = y1a - y1b
  1. 假设抽取的图片尺寸超过了填充区域给定的大小,则需要对抽取的图片中超过填充区域的部分进行裁剪,如下图所示。
    YOLOv5-v6.0学习笔记
  2. 将归一化后的标注框坐标还原到原图尺寸,然后转换到拼接后的坐标系中,得到新的标注框坐标。
labels, segments = self.labels[index].copy(), self.segments[index].copy()
if labels.size:
	labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padw, padh)
	segments = [xyn2xy(x, w, h, padw, padh) for x in segments]
labels4.append(labels)
segments4.extend(segments)
  1. 由于重新拼接后的图片尺寸为YOLOv5-v6.0学习笔记,因此还需要将其尺寸缩放到YOLOv5-v6.0学习笔记,保证与用于训练的输入图片尺寸一致。

5.2 MixUp

MixUp是一种简单的数据增强方法,它的主要思想是将两个随机样本的特征和标签进行加权求和,从而得到一个新的训练样本。公式如下:YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记其中YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记表示两个不同的输入样本,YOLOv5-v6.0学习笔记YOLOv5-v6.0学习笔记表示两个不同的输入样本对应的标签,YOLOv5-v6.0学习笔记表示两个样本融合的比例系数,且满足Beta分布。
YOLOv5-v6.0学习笔记

但是在YOLOv5中只对图像特征做了融合,而对标签做了拼接,具体的代码实现如下:

r = np.random.beta(32.0, 32.0)
im = (im * r + im2 * (1 - r)).astype(np.uint8)
labels = np.concatenate((labels, labels2), 0)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年6月9日
下一篇 2022年6月9日

相关推荐