最近频繁的使用了YOLOv6网络模型,发现性能是真的强,那就来写一篇博客记录一下吧。。。
首先来比较一下YOLOv6与其它YOLO性能,如下图,图来自美团YOLOv6。
通过上面2张图比较发现,无论是速度还是精度均超越其他同体量算法。
如上图是YOLOv6的整体网络结构,主要由三个部分组成Backbone、Neck还有Head部分组成。
其流程为:先对输入的图片预处理,处理成640*640大小的RGB图片,再送入Backbone网络结构,由Backbone网络经过特征提取,输出三层特征层,再将这三层的特征层传入Neck部分,进行特征融合,输出三层特征图,输入到Head部分,对图像检测的三类任务(分类、前后背景分类、边框)预测,输出最后的结果。
接下里就来看看YOLOv6的细节部分。
如上图,其中Input代表输入
,一般是图片预处理之后分辨率为640*640大小的图片。stem代表的是RepConv,也就是RepVGG网络中的卷积模块,是一种在训练时具有多分支拓扑,而在实际部署时可以等效融合为单个 3x3 卷积的一种可重参数化的结构,融合过程如下图,该卷积模块的作用:可以有效利用计算密集型硬件计算能力,同时提高算法的精度,让检测网络更快更强。
其Tensorflow2代码现实方式如下:
def ConvBn(inputs, filters, kernel_size, stride, padding, groups=1, weight_decay=5e-4):
x = Conv2D(filters=filters, kernel_size=kernel_size, strides=stride, padding=padding,
groups=groups, use_bias=False, kernel_initializer=RandomNormal(stddev=0.02),
kernel_regularizer=l2(weight_decay))(inputs)
x = BatchNormalization()(x)
return x
# RepVGG网络中的卷积模块
def RepVGGBlock(inputs, filters, kernel_size=3, stride=1, padding='same', dilation=1, groups=1,
deploy=False, weight_decay=5e-4):
if deploy:
x = Conv2D(filters=filters, kernel_size=kernel_size, strides=stride, padding=padding,
dilation_rate=dilation, use_bias=True, kernel_initializer=RandomNormal(stddev=0.02),
kernel_regularizer=l2(weight_decay))(inputs)
x = ReLU()(x)
return x
else:
if inputs.shape[-1] == filters and stride == 1:
x0 = ConvBn(inputs, filters, kernel_size, stride, padding=padding, groups=groups)
x1 = ConvBn(inputs, filters, 1, stride, padding=padding, groups=groups)
x = Add()([x0, x1, BatchNormalization()(inputs)])
return ReLU()(x)
else:
x0 = ConvBn(inputs, filters, kernel_size, stride, padding=padding, groups=groups)
x1 = ConvBn(inputs, filters, 1, stride, padding=padding, groups=groups)
x = Add()([x0, x1])
return ReLU()(x)
RepBlock代表的是n个RepConv叠加
。SimSPPF代表的是原来YOLOv5、YOLOX的优化设计,如下图,其中cat代表特征层的融合
。
其中SimConv代表卷积+标准化+激活函数
,Tensorflow2实现代码如下:
def SimConv(inputs, filters, kernel_size, stride, groups=1, bias=False, padding='same', weight_decay=5e-4):
x = Conv2D(filters=filters, kernel_size=kernel_size, strides=stride, padding=padding,
groups=groups, use_bias=bias, kernel_initializer=RandomNormal(stddev=0.02),
kernel_regularizer=l2(weight_decay))(inputs)
x = BatchNormalization()(x)
x = ReLU()(x)
return x
# 原始的 SPPF 优化设计
def SimSPPF(inputs, filters, kernel_size=5, weight_decay=5e-4):
c_ = filters // 2
x = SimConv(inputs, c_, 1, 1, padding='valid', weight_decay=weight_decay)
with warnings.catch_warnings():
warnings.simplefilter('ignore')
y1 = MaxPool2D(pool_size=kernel_size, strides=1, padding='same')(x)
y2 = MaxPool2D(pool_size=kernel_size, strides=1, padding='same')(y1)
y3 = MaxPool2D(pool_size=kernel_size, strides=1, padding='same')(y2)
out = Concatenate(axis=-1)([x, y1, y2, y3])
return SimConv(out, filters, 1, 1, padding='valid', weight_decay=weight_decay)
其Backbone的主要流程为:输入640x640x3的图片,通过stem层(s=2,步长为2)输出为32032032,后面接几个block(如上图的1、2、3、4),每个block均做特征层的下采样和channel的增大,每个block由一个RepConv和一个RepBlock组成(4多加SPPF层),在RepConv中做特征层的下采样,同时channel增大,在RepBlock中对特征层充分融合后输出,最后Backbone输出三个特征层分别为(20x20x512(第4个block), 40x40x128(第3个block), 80x80x64(第2个block))。
如上图,其中Upsimple代表上采样
。
Neck流程为:左侧,从Backbone第4个block输出20x20x512的特征层,通过SimConv 变成20x20x128大小,上采样后宽和高较之前增大一倍后与Backbone第3个block的输出在通道数上融合后特征层变成40x40x384,通过一个RepBlock后,输出 40x40x128,重复上述步骤后,输出80x80x64的特征层。右侧,将80x80x64的特征层先SimConv下采样,得到40x40x64的特征层,与左侧宽和高一致的特征层在通道数上融合后,通过一个RepBlock,输出第二个特征层,重复右侧以上步骤,输出第三个特征层。至此,Neck层输出三个特征层分别为(20x20x256, 40x40x128, 80x80x64)。
如上图,其中YOLO-Head结构如下图。
其中,Conv代表普通卷积+标准化+SiLU激活函数
,Conv2D代表普通卷积
。
Head流程:从Neck层输出三个分支,对于每个分支,先对输出特征图通过Conv层,做特征图的特征融合后,分成两个分支一个分支通过Conv+Conv2D完成分类任务的预测,另外一个分支先通过Conv融合特征后再分成两个分支,一个分支通过卷积完成边框的回归,一个分支通过Conv2D完成前后背景的分类,至此三个分支再通过合并在通道数上融合,输出未经后处理的预测结果。
采用了更简洁的 Anchor-free 检测方法。由于 Anchor-based检测器需要在训练之前进行聚类分析以确定最佳 Anchor 集合,这会一定程度提高检测器的复杂度;同时,在一些边缘端的应用中,需要在硬件之间搬运大量检测结果的步骤,也会带来额外的延时。而 Anchor-free 无锚范式因其泛化能力强,解码逻辑更简单。与YOLOX类似。
为了获得更多高质量的正样本,YOLOv6 引入了 SimOTA算法动态分配正样本,进一步提高检测精度。此类方法会根据训练过程中的网络输出来分配正样本,从而可以产生更多高质量的正样本,继而又促进网络的正向优化。与YOLOX的训练策略类似,可以先学习一下YOLOX。
论文地址:https://arxiv.org/ftp/arxiv/papers/2205/2205.12740.pdf
SIOU考虑框中心之间的距离、重叠区域和纵横比,这使得帮助了训练收敛过程和效果,因为它可以让预测框很快地移动到最近的轴,并且随后的方法只需要一个坐标 X 或 Y 的回归。简而言之,添加Angle惩罚成本有效地减少了损失的总自由度。
具体原理很简单,可以看该博客讲解SIOU
数据集网址:
https://aistudio.baidu.com/aistudio/datasetdetail/49531
下载之后需要将文件夹格式处理成如下命名格式:
VOCdevkit
- VOC2007
- Annotations
- ImageSets
- JPEGImages
gitee地址:https://gitee.com/Hao_gg/yolov6_-traffic_signs/tree/master
github地址:https://github.com/hao-ux/YOLOv6_Traffic_signs