Rocky Ding

公众号:WeThinkIn

写在前面

【Make YOLO Great Again】栏目专注于从更实战,更深刻的角度解析YOLOv1-v7这个CV领域举足轻重的算法系列,并给出其在业务,竞赛以及研究维度的延伸思考。欢迎大家一起交流学习,分享宝贵的ideas与思考~

大家好,我是Rocky。

近年来YOLO系列层出不穷,更新不断,已经到v7版本。Rocky认为不能简单用版本高低来评判一个系列的效果好坏,YOLOv1-v7不同版本各有特色,在不同场景,不同上下游环境,不同资源支持的情况下,如何从容选择使用哪个版本,甚至使用哪个特定部分,都需要我们对YOLOv1-v7有一个全面的认识

故Rocky将YOLO系列每个版本都表示成下图中的五个部分,逐一进行解析,并将每个部分带入业务,竞赛,研究等维度进行延伸思考,探索更多可能性。

Rocky已经将这五个部分全部深入解析并撰写成文:You Only Look Once:Unified, Real-Time Object Detection

YOLOv1开源代码:YOLOv1-Darkent

YOLOv2论文名以及论文地址:YOLO9000:Better, Faster, Stronger

YOLOv2开源代码:YOLOv2-Darkent

YOLOv3论文名以及论文地址:YOLOv3: An Incremental Improvement

YOLOv3开源代码:YOLOv3-PyTorch

YOLOv4论文名以及论文地址:YOLOv4: Optimal Speed and Accuracy of Object Detection

YOLOv4开源代码:YOLOv4-Darkent

YOLOv5论文名以及论文地址:无

YOLOv5开源代码:YOLOv5-PyTorch

YOLOx论文名以及论文地址:YOLOX: Exceeding YOLO Series in 2021

YOLOx开源代码:YOLOx-PyTorch

YOLOv6论文名以及论文地址:YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications

YOLOv6开源代码:YOLOv6-PyTorch

YOLOv7论文名以及论文地址:YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors

YOLOv7开源代码:Official YOLOv7-PyTorch

【二】YOLO系列中输入侧,Backbone,Neck,Head,Tricks的特点

输入侧

YOLO系列中的输入侧主要包含了输入数据,数据增强算法以及一些特殊预处理操作

输入数据可以是图片,也可以是视频。

数据增强算法包含通用增强以及YOLO自带的一些高阶增强算法。

YOLO系列的输入侧可谓是通用性最强的一个部分,具备很强的向目标检测其他模型,图像分类,图像分割,目标跟踪等方向迁移应用的价值。

并且从业务,竞赛,研究等角度观察,输入侧结构也能在这些方面比较好的融入,从容。

Backbone

YOLO系列中的Backbone结构主要作为算法模型的一个核心特征提取器,随着时代的变迁不断发展。

某种程度上,YOLO系列的各个Backbone代表着当时的高价值模型与AI行业的发展记忆,计算机视觉江湖上,名噪一时的那些“算法兵器”,它们确实来过

YOLO系列的Backbone与输入侧一样,是通用性非常强的一个部分,在不同的计算机视觉细分方向,都有广泛的应用。

Neck

YOLO从v3版本开始设计Neck结构,其中的特征融合思想最初在FPN(feature pyramid networks)网络中提出,在YOLOv3中进行结构的微调,最终成为YOLO后续系列不可或缺的部分。

FPN的思路剑指小目标,原来很多目标检测算法都是只采用高层特征进行预测,高层的特征中语义信息比较丰富,但是分辨率较低,目标位置比较粗略。假设在深层网络中,最后的高层特征图中一个像素可能对应着输出图像 20 × 20 20 \times 20 20×20的像素区域,那么小于 20 × 20 20 \times 20 20×20像素的小物体的特征大概率已经丢失。与此同时,低层的特征语义信息比较少,但是目标位置准确,这是对小目标检测有帮助的。FPN将高层特征与底层特征进行融合,从而同时利用低层特征的高分辨率和高层特征的丰富语义信息,并进行了多尺度特征的独立预测,对小物体的检测效果有明显的提升。

FPN论文地址:Feature Pyramid Networks for Object Detection

【Rocky的延伸思考】

  1. 业务:FPN具备在业务场景中的应用价值,但还是要分场景来使用,主要在小目标场景可以尝试,并同时要兼顾上游数据侧与下游部署侧的适配。
  2. 竞赛:FPN的思想可谓是算法竞赛的一个利器,在分类,分割,检测等任务中都能大展拳脚,进行迁移应用。
  3. 研究:FPN具备作为baseline的价值,不管是进行拓展研究还是单纯的学习FPN思想,都是提升研究能力的不错选择。

Head

YOLO系列中的Head结构主要包含了Head检测头,损失函数部分以及Head结构的优化策略

Head检测头体现了YOLO系列“简洁美”的思想,与two-stage检测算法相比,YOLO取消了RPN模块,设计了特征提取网络Backbone+检测头Head的end-to-end整体逻辑,其对工程的友好特性让工业界顿时开满“YOLO花”

YOLO系列的损失函数部分可谓是目标检测领域中的“掌上明珠”,其在业务,竞赛和研究等维度都有很强的迁移价值。

【Rocky的延伸思考】

  1. 业务:YOLO系列的Head结构中,不管是Head检测头,损失函数部分以及Head结构的优化策略,其在业务中都可以作为baseline进行迁移使用。
  2. 竞赛:YOLO系列的Head结构在目标检测竞赛中可以说时入场必选结构,能极大程度上缩短竞赛初期的熟悉适应成本。
  3. 研究:YOLO系列的Head结构和Neck结构一样,具备作为baseline的价值。

Tricks

YOLO系列中使用的Tricks,从横向角度来看,基本算是当时的最优Trcks;从纵向角度来看,其大部分都具备了可迁移性,强适应性,能够跟随着我们一起进入2020年代,并且依旧发挥余热

YOLO系列中使用的Tricks和Backbone以及输入侧一样,是通用性非常强的一个部分,迁移应用在业务,竞赛,研究等维度,可能会带来出其不意的效果与惊喜。

【三】YOLOv1 输入侧,Backbone,Neck,Head,Tricks大解析

YOLOv1作为YOLO系列的开山鼻祖,让YOLO这个计算机视觉中的“璀璨明珠”在2015年的夏天,拉开了帷幕。

YOLOv1整体上有着朴素的逻辑,但是隐隐约约已经为后续的YOLO发展定下了简单实用的基调。

下面Rocky就将YOLOv1拆解,从输入侧,Backbone,Head,Tricks入手,带着大家一起学习研究。

(需要注意的是,YOLO系列中的Neck结构在YOLOv3才出现,故在后面的YOLOv3部分将加入Neck结构的讲解)

YOLOv1 输入侧大解析

YOLOv1在输入侧做的最多的工作是调整输入图像的尺寸以支持对图像细粒度特征的挖掘与检测。

同样的,YOLO系列的grid逻辑(“分而治之”)也从输入侧开始展开,直到Head结构输出相应结果。

YOLOv1 Backbone大解析

YOLOv1的Backbone结构主要受启发于GoogLeNet思想,从上面的整体结构可以看出,模型结构非常简洁,卷积一卷到底。

YOLOv1的backbone结构中使用了Leaky ReLu激活函数,但并没有引入BN层。

YOLOv1 Head大解析

YOLOv1作为YOLO系列的开山鼻祖,其Head结构整体逻辑比较直观,并且对后续的版本影响深远。

YOLOv1中,图片被划分为 7 × 7 7\times7 7×7 的网格(grid cell),每个网络在Head结构中进行独立检测。

YOLOv1在Inference过程中并不是把每个单独的网格作为输入,网格只是用于物体ground truth中心点位置的分配,如果一个物体的ground truth中心点坐标在一个grid cell中,那么就认为这个grid cell就是包含这个物体,这个物体的预测就由该grid cell负责。而不是对图片进行切片,并不会让网格的视野受限且只有局部特征。

YOLOv1的输出是一个 7 × 7 × 30 7\times7\times30 7×7×30 的张量, 7 × 7 7\times7 7×7 表示把输入图片划分成 7 × 7 7\times7 7×7 的网格,每一个网格的通道维度等于 30 = ( 2 × 5 + 20 ) 30=(2\times5+20) 30=(2×5+20),代表YOLOv1中每个网格能预测2个框,每个框能预测5个参数 ( x , y , w , h , C ) (x,y,w,h,C) (x,y,w,h,C) 再加上20个种类。

把上述内容转换成通用公式就是网格一共是 S × S S \times S S×S 个,每个网格产生 B B B 个检测框,每个检测框会经过网络最终得到相应的bounding box。最终会得到 S × S × B S\times S\times B S×S×B 个bounding box,每个bounding box都包含5个预测值,分别是bounding box的中心坐标 x , y x,y x,y,bounding box的宽高 w , h w,h w,h 和置信度 C C C。其中 C C C 代表网格中box能与物体的取得的最大IOU值。

铺垫了这么多变量表示,到这里终于可以引出对工业界产生深远影响的YOLOv1的损失函数,YOLO系列的后续版本的损失函数都是从这个最初的形式优化而来。

$$\begin{aligned}
Loss = \lambda_{coord} \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}\lbrack(x_i – \hat{x}_i)^2 + (y_i – \hat{y}_i)^2\rbrack \

  • \lambda_{coord}\sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}[(\sqrt{w_i} – \sqrt{\hat{w}_i})^2 + (\sqrt{h_i} – \sqrt{\hat{h}_i})^2]\
  • \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}(C_i – \hat{C}_i)^2\
  • \lambda_{noobj} \sum{S2}{i=0}\sum{B}_{j=0}I{noobj}{ij}(C_i – \hat{C}_i)^2\
  • \sum{S2}{i=0}I^{obj}{ij}\sum_{c\in classes}(P_{i}© – \hat{P}_{i}©)^2
    \end{aligned}$$

乍一看YOLOv1的损失函数十分复杂,don’t worry,接下来Rocky将进行详细分析。

整体上来看,YOLOv1的损失函数可以分为检测框的回归损失,置信度误差损失以及分类误差损失

公式中第一行和第二行代表了检测框的中心点和宽高的回归损失,其中 I i j o b j I^{obj}_{ij} Iijobj 表示第 i i i 个网格的第 j j j 个box是否去预测这个物体,即这个box与物体的ground truth box的IOU值和其他box相比是否是最大的。如果是,那么 I i j o b j = 1 I^{obj}_{ij} = 1 Iijobj=1,否则 I i j o b j = 0 I^{obj}_{ij} = 0 Iijobj=0,而YOLOv1中每个网格只有2个box,还是比较简单的。值得注意的是宽高回归损失中使用了开根号的操作,这是考虑到了小目标与大目标对应的检测框会存在差异,并消除这个差异。不开根号时,损失函数往往更倾向于调整尺寸比较大的检测框。例如,12个像素点的偏差,对于 888 × 888 888\times888 888×888 的检测框几乎没有影响,因为此时的IOU值还是很大,但是对于 28 × 48 28\times48 28×48 的小检测框影响就很大。

公式中第三行和第四行代表了置信度误差损失,分别是含物体的置信度误差损失和不含物体的置信度误差损失。当网格中含有物体时, I i j o b j = 1 , I i j n o o b j = 0 I^{obj}_{ij} = 1, I^{noobj}_{ij} = 0 Iijobj=1,Iijnoobj=0,并且置信度ground truth值 C ^ i = 1 \hat{C}_i = 1 C^i=1;当网格中不含物体时, I i j o b j = 0 , I i j n o o b j = 1 I^{obj}_{ij} = 0, I^{noobj}_{ij} = 1 Iijobj=0,Iijnoobj=1,并且置信度ground truth值 C ^ i = 0 \hat{C}_i = 0 C^i=0。包含物体的预测置信度 C i C_i Ci 为网格中box与物体ground truth box能取到的最大的IOU值,这很好理解,计算逻辑也直接明了。但是不包含物体的置信度误差损失究竟是怎么回事?don’t worry,不包含物体的置信度误差损失包含两部分,一部分是包含物体的网格中的两个box中不负责预测的那个box,另外一部分是不包含物体的网格中的box,让他们都往0回归吧!

目标检测中存在一个常见问题,那就是类别不均衡问题,YOLOv1中也不例外。在一张图像中物体往往只占一小部分,大部分还是背景为主。故在置信度误差损失中设置了 λ c o o r d = 5 \lambda_{coord} = 5 λcoord=5 λ n o o b j = 0.5 \lambda_{noobj} = 0.5 λnoobj=0.5 来平衡含物体的置信度误差损失和不含物体的置信度误差损失两者的权重,让模型更加重视含物体的置信度误差损失。

公式中第五行代表了分类误差损失,只有当 I i j o b j = 1 I^{obj}_{ij} = 1 Iijobj=1 时才会进行计算。

到这里,YOLOv1损失函数的解析就告一段落了。接下来我们看一下YOLOv1Head侧的优化策略:

  1. 使用NMS算法,过滤掉一些重叠的检测框。
  2. 同一网格中的不同检测框有不同作用,也就是置信度误差损失的设计逻辑,这样可以增加召回率
  3. Inference时使用 P × C P\times C P×C 作为输出置信度。使用物体的类别预测最大值 P P P 乘以最合适的预测框 C C C,这样也可以过滤掉一些大部分重叠的检测框,同时考虑了检测框与类别让输出更加可信。

YOLOv1 Tricks大解析

作为YOLO系列的开山之作,YOLOv1中并未用太多的Tricks,但是设计出YOLO的架构,已经足够伟大。

YOLOv1的缺陷:

  1. 由于YOLOv1每个网格的检测框只有2个,对于密集型目标检测和小物体检测都不能很好适用。
  2. Inference时,当同一类物体出现的不常见的长宽比时泛化能力偏弱。
  3. 由于损失函数的问题,定位误差是影响检测效果的主要原因,尤其是大小物体的处理上,还有待加强。

【Rocky的延伸思考】

  1. 业务:YOLOv1 输入侧逻辑非常适合作为新业务的实验性Baseline,快速搭建,快速试错。Head结构经过时间的考验与沉淀,非常适合作为简单业务的入场baseline部分模块进行搭建。
  2. 竞赛:YOLOv1 坦率来说在竞赛中已不具备竞争力,但作为baseline入场模型也未尝不可。
  3. 研究:YOLOv1 Head架构可谓是YOLO系列的开山鼻祖,给后续系列搭建了baseline,不管是入门学习还是进行扩展研究,都是非常有价值的。

【四】YOLOv2 输入侧,Backbone,Neck,Head,Tricks大解析

时隔一年,在2016年的冬天,YOLOv2来了,YOLOv2让工业界狂喜的同时,YOLO版本号迭代的周期也来开了帷幕。

YOLOv2 输入侧大解析

YOLOv2的输入侧在YOLOv1的基础上引入了多尺度训练(Multi-Scale Training),并且优化了预训练模型(High Resolution Classifier)

多尺度训练(Multi-Scale Training)的逻辑是模型每训练一定的Epoch,改变输入图片的尺寸,使得模型对不同的输入尺寸更鲁棒,能够从容地对不同尺寸的图像进行检测

论文中使用32的倍数作为输入的尺寸,具体使用了320、352、384、416、448、480、512、544、576、608这10种尺寸。

在预训练模型这块,YOLOv2使用了High Resolution Classifier思想。一般基于ImageNet预训练的模型的输入尺寸都是小于 256 × 256 256\times 256 256×256的。YOLOv2使用的输入尺寸是 448 × 448 448\times 448 448×448,比YOLOv1的要大,故预训练模型网络需要使用大分辨率输入在ImageNet上进行微调。经过这个操作,YOLOv2的mAP提升了4%。

YOLOv2 Backbone大解析

YOLOv2的Backbone结构在YOLOv1的基础上设计了Darknet-19网络,并引入了BN层优化模型整体性能

Darknet-19网络包含19个卷积层和5个max pooling层,整体计算量比YOLOv1中采用的GoogleNet更少,最后用average pooling层代替全连接层进行Inference。

在YOLOv2的Backbone中加入BN层之后,使得mAP提升了2%,而BN层也成为了YOLO后续系列的标配。

YOLOv2 Head大解析

YOLOv2的Head结构在YOLOv1的基础上进行了网络结构和损失函数的改进,并且大名鼎鼎的anchor box也在此引入

YOLOv2在YOLOv1的基础上去掉了最后的全连接层,采用了卷积和anchor boxes来预测检测框。由于使用卷积对特征图进行下采样会使很多细粒度特征(Fine-Grained Features)的损失,导致小物体的识别效果不佳。故在YOLOv2Head侧中引入了passthrough layer结构,将特征图一分为四,并进行concat操作,保存了珍贵的细粒度特征

刚才提到了YOLOv2使用卷积和anchor box来输出检测框,那么到底anchor box机制是怎么样的呢?

YOLOv1中每个网格预测两个检测框,并让最合适的检测框向ground truth框进行回归修正。在YOLOv2中,Head侧不对检测框的宽高进行直接硬回归,而是将检测框与Anchor框的偏差(offset)进行回归,并且每个网格指定 n n n 个anchor box。在训练时,只有最接近ground truth的检测框进行损失的计算。在引入anchor box后,mAP由69.5下降至69.2,原因在于每个网格预测的物体变多之后,召回率大幅上升,准确率有所下降,总体mAP略有下降。

在引入anchor box之后,又使用了Dimension Clusters操作,使得anchor box的宽高由聚类算法产生。没错,就是K-means算法~~(K-NN算法)~~。使用K-means算法获得anchor box的具体细节可以在我之前的文章13×13,每个grid cell设置了 5 5 5 个anchor box预测得到 5 5 5 个检测框,一共有 13 × 13 × 5 = 845 13\times13\times5=845 13×13×5=845 个检测框,与YOLOv1相比大大提高目标的定位准确率。

优化了anchor box预设置后,YOLOv2设计了Direct location prediction操作来支持检测框与Anchor框的偏差(offset)回归逻辑。与YOLOv1相比,YOLOv2中每个检测框输出5个偏差参数 ( t x , t y , t w , t h , t o ) (t_x,t_y,t_w,t_h,t_o) (tx,ty,tw,th,to),为了将预测框的中心点约束在当前grid cell中,使用sigmoid函数 σ ( ⋅ ) \sigma(·) σ() t x 和 t y t_x和t_y txty 归一化处理,将值约束在 [ 0 , 1 ] [0,1] [0,1] 之间,这使得模型训练更稳定。

其中 P w P_w Pw P h P_h Ph 代表anchor box的宽高, c x c_x cx c y c_y cy 代表grid cell左上角相对于feature map左上角的距离。

讲完了网络结构的改进和anchor box,接下来就是损失函数的改进了:

$$\begin{aligned}
Loss = \lambda_{coord} \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}(2 – \hat{w}\times \hat{h})[(x_i – \hat{x}_i)^2 + (y_i – \hat{y}_i)^2]\

  • \lambda_{coord}\sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}(2 – \hat{w}\times \hat{h})[(w_i – \hat{w}_i)^2 + (h_i – \hat{h}_i)^2]\
  • \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}(C_i – \hat{C}_i)^2\
  • \lambda_{noobj} \sum{S2}{i=0}\sum{B}_{j=0}I{noobj}{ij}(C_i – \hat{C}_i)^2\
  • \sum{S2}{i=0}I^{obj}{ij}\sum_{c\in classes}(P_{i}© – \hat{P}_{i}©)^2\
  • 0.01 \sum{S2}{i=0}\sum{B}_{j=0}I{noobj}{ij}[(p_x – x_i)^2 + (p_y – y_i)^2 + (p_w – w_i)^2 + (p_h – h_i)^2](when iter < 12800)
    \end{aligned}$$

可以看出,在计算检测框的回归损失时,YOLOv2去掉了开根号操作,进行直接计算。但是根据ground truth的大小对权重系数进行修正: ( 2 − w ^ × h ^ ) (2 – \hat{w}\times \hat{h}) (2w^×h^)(这里 w ^ \hat{w} w^ h ^ \hat{h} h^ 都归一化到 [ 0 , 1 ] [0,1] [0,1]),这样对于尺度较小的预测框其权重系数会更大一些,可以放大误差,起到和YOLOv1计算平方根相似的效果。

在训练前期(iter < 12800),YOLOv2还会进行 0.01 ∑ i = 0 S 2 ∑ j = 0 B I i j n o o b j [ ( p x − x i ) 2 + ( p y − y i ) 2 + ( p w − w i ) 2 + ( p h − h i ) 2 ] 0.01 \sum^{S^2}_{i=0}\sum^{B}_{j=0}I^{noobj}_{ij}[(p_x – x_i)^2 + (p_y – y_i)^2 + (p_w – w_i)^2 + (p_h – h_i)^2] 0.01i=0S2j=0BIijnoobj[(pxxi)2+(pyyi)2+(pwwi)2+(phhi)2] 的计算,表示对anchor boxes和检测框进行坐标回归,促进网络学习到anchor的形状。

YOLOv2 Tricks大解析

等到YOLOv2发布时,引入了当时来说比较有创造性的Tricks,即设计了分类与检测的联合训练方法,使得YOLO能够实时检测多达9000种目标,在这种方法下输出的模型称为YOLO9000

YOLO9000主要在COCO和ImageNet数据集上进行训练,首先在检测数据集上训练一定的epoch来让模型学习定位和检测目标的能力;再使用分类数据集进行训练,从而扩展模型对目标的识别能力

在训练的过程中,混合目标检测和分类的数据集。当输入是检测数据集时,对整个Loss函数计算Loss;当输入是分类数据集时,Loss函数只计算分类Loss,其余部分Loss设为零。

YOLO9000使用的联合训练不同于将Backbone在ImageNet上进行预训练,联合训练可以扩充检测识别的目标类别。例如,当模型检测出车的位置后,更进一步将其细分类别轿车、卡车、客车、自行车、三轮车等。

【Rocky的延伸思考】

  1. 业务侧:YOLOv2 输入侧的多尺度训练思想,Backbone以及Head结构完全可以作为baseline模型的一部分进行业务开展。
  2. 竞赛侧:YOLOv2 输入侧的多尺度训练思想在竞赛侧是一个提分利器。Head结构中的anchor box机制,Dimension Clusters以及Direct location prediction优化方法可以作为竞赛侧的提分策略。
  3. 研究侧:YOLOv2 输入侧的多尺度训练思想以及High Resolution Classifier和Head结构以及损失函数具备作为baseline的价值,不管是进行拓展研究还是单纯学习思想。

【五】YOLOv3 输入侧,Backbone,Neck,Head,Tricks大解析

时间来到2018年,这时候Rocky正要开始研究生的生涯,与此同时,YOLOv3来了!后续YOLO系列的整体结构,都在YOLOv3中已经定型。

下面Rocky在这里先分享一下YOLOv3的整体结构:

YOLOv3 输入侧大解析

在YOLOv3输入侧,Rocky想引入常用基础数据增强技术和高阶数据增强算法

因为不管是YOLO系列还是二阶段目标检测系列;不管是目标检测还是图像分类和分割,基础数据增强技术和高阶数据增强算法都有很强的实用价值。

高阶数据增强算法:

其中RandErasing将图像的部分区域替换为随机值,或者是训练集的平均像素值。

而GridMask则使用了一个网格掩码,并将掩码进行随机翻转,与原图相乘,从而得到增广后的图像,通过超参数控制生成的掩码网格的大小。

基于NAS搜索的AutoAugment在一系列图像增强子策略的搜索空间中通过搜索算法找到适合特定数据集的图像增强方案。针对不同类型的数据集,会包含不同数量的子策略。每个子策略中都包含两种变换,针对每张图像都随机的挑选一个子策略,然后以一定的概率来决定是否执行子策略中的每种变换方法。

其余方法的细节知识,Rocky将在后续的高阶数据增强专题文章中依次展开,大家敬请期待。

常用基础数据增强技术:

  1. 颜色变换:在色彩通道空间进行数据增强,比如将某种颜色通道关闭,或者改变亮度值。
  2. 旋转变换:选择一个角度,左右旋转图像,可以改变图像内容朝向。
  3. 添加噪声:从高斯等分布中采样出的随机值矩阵加入到图像中。
  4. 锐化和模糊:使用高斯算子,拉普拉斯算子等处理图像。
  5. 缩放变换:图像按照比例进行放大和缩小并不改变图像中的内容。
  6. 平移变换:向上下左右四个维度移动图像。
  7. 翻转变换:关于水平或者竖直的轴进行图像翻转操作。
  8. 裁剪变换:主要有中心裁剪与随机裁剪。
  9. 仿射变换:对图像进行一次线性变换并接上一个平移变换。

YOLOv3 Backbone大解析

YOLOv3的Backbone在YOLOv2的基础上设计了Darknet-53结构

YOLOv3将YOLOv2的Darknet-19加深了网络层数,并引入了ResNet的残差思想,也正是残差思想让YOLOv3将Backbone深度大幅扩展至Darknet-53。

YOLOv3优化了下采样方式(无池化层结构),采用卷积层来实现,而YOLOv2中采用池化层实现。

YOLOv3 Neck大解析

YOLOv3则是较好的引入了FPN的思想,以支持后面的Head侧采用多尺度来对不同size的目标进行检测,越精细的grid cell就可以检测出越精细的目标物体。YOLOv3设置了三个不同的尺寸,分别是 19 × 19 19 \times 19 19×19, 38 × 38 38 \times 38 38×38 76 × 76 76 \times 76 76×76,他们之间的比例为 1 : 2 : 4 1 : 2: 4 1:2:4

YOLOv3采用全卷积的思路,在Neck结构也不例外(YOLOv1-v2中采用池化层做特征图的下采样, v3中采用卷积层来实现)。

YOLOv3 Head大解析

YOLOv3Head结构在YOLOv2的基础上引入了多尺度检测逻辑和多标签分类思想,优化了损失函数

YOLOv3在Neck结构的基础上顺势而为融合了3个尺度,在多个尺度的融合特征图上分别独立做检测。再将Anchor Box由5个增加至9个,每个尺度下分配3个Anchor Box,最终对于小目标的检测效果提升明显。并且多尺度+9anchor box让YOLOv3的整体检测性能达到了一个比较从容的level。

再说多标签分类思想,我大受震撼。首先什么是多标签分类呢?我们先对几种常见的分类逻辑做一个对比:

  1. 二分类(Two-Class Classification)问题,是最简单的分类问题,比如一个任务中只有猫和狗,每个样本中也只有其中的一类。
  2. 单标签多分类(Multi-Class Classification)问题,指一个样本(一个图片或者一个检测框)有一个标签,但总共的类别数是大于两类的。目标检测中针对每个检测框的分类是多分类问题。在深度学习中,使用softmax是最常用的解决方案。
  3. 多标签多分类(Multi-Label Classification)问题,指一个样本(一个图片或者一个检测框)中含有多个物体或者多个label。在深度学习中,使用多个Logistic输出是一种性价比很高的做法。

YOLOv3将YOLOv2的单标签分类改进为多标签分类,Head结构将用于单标签分类的Softmax分类器改成多个独立的用于多标签分类的Logistic分类器,取消了类别之间的互斥,可以使网络更加灵活。YOLOv2使用Softmax分类器,认为一个检测框只属于一个类别,每个检测框分配到概率最大的类别。但实际场景中一个检测框可能含有多个物体或者有重叠的类别标签。Logistic分类器主要用到Sigmoid函数,可以将输入约束在0到1的范围内,当一张图像经过特征提取后的某一检测框类别置信度经过sigmoid函数约束后如果大于设定的阈值,就表示该检测框负责的物体属于该类别。

YOLOv3的损失函数在YOLOv2的基础上进行了改进:

$$\begin{aligned}
Loss = \lambda_{coord} \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}(2 – \hat{w}\times \hat{h})[(x_i – \hat{x}_i)^2 + (y_i – \hat{y}_i)^2]\

  • \lambda_{coord}\sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}(2 – \hat{w}\times \hat{h})[(w_i – \hat{w}_i)^2 + (h_i – \hat{h}_i)^2]\
  • \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}[C_i\log(C_i) + (1-\hat{C}_i)\log(1-\hat{C}_i)]\
  • \lambda_{noobj} \sum{S2}{i=0}\sum{B}_{j=0}I{noobj}{ij}[C_i\log(C_i) + (1-\hat{C}_i)\log(1-\hat{C}_i)]\
  • \sum{S2}{i=0}I^{obj}{ij}\sum_{c\in classes}[P_{i}©\log(P_{i}©) + (1 – \hat{P}{i}©)\log(1-\hat{P}{i}©)]
    \end{aligned}$$

YOLOv3中置信度误差损失和分类误差损失都使用交叉熵来表示。

YOLOv3 Tricks大解析

等到YOLOv3发布时,YOLO系列的整体架构算是基本确定,Adam优化器也开始逐渐流行起来

Adam优化器结合了AdaGrad和RMSProp两种优化算法的优点。对梯度的一阶矩估计(First Moment Estimation,即梯度的均值)和二阶矩估计(Second Moment Estimation,即梯度的未中心化的方差)进行综合考虑,计算出更新步长。

Adam的优势:

  1. 实现简单,计算高效,对内存需求少。
  2. 参数的更新不受梯度的伸缩变换影响。
  3. 超参数具有很好的解释性,且通常无需调整或仅需很少的微调。
  4. 更新的步长能够被限制在大致的范围内(初始学习率)。
  5. 能自然地实现步长退火过程(自动调整学习率)。
  6. 很适合应用于大规模的数据及参数的场景。
  7. 适用于不稳定目标函数。
  8. 适用于梯度稀疏或梯度存在很大噪声的问题。

Adam的实现原理:

【Rocky的延伸思考】

  1. 基础数据增强技术和高阶数据增强算法不管是在业务,竞赛还是研究维度都能非常稳定的带来性能的提升。
  2. 业务:YOLOv3 整体结构在工程中非常稳定,且久经时间的考验,可以作为业务baseline模型的首选。
  3. 竞赛:YOLOv3 整体结构在竞赛中的地位和业务侧同理。
  4. 研究:基于YOLOv3优化而来的论文日新月异,让人眼花缭乱,但正真价值几何,还需要我们去判断。

【六】YOLOv4 输入侧,Backbone,Neck,Head,Tricks大解析

首先,Rocky在这里先分享一下YOLOv4的整体结构:

YOLOv4 输入侧大解析

YOLOv4的输入侧在YOLOv3的基础上,使用了Mosaic和CutMix高阶数据增强来提升模型的整体性能

Mosaic数据增强技术从经典的CutMix优化而来。在CutMix的逻辑中,使用两张图片分别选取部分像素进行拼接,产生新的数据。而Mosaic则在此基础上图片数量增加到四张,并采用随机缩放,裁剪和排布的方式进行拼接

Mosaic数据增强的优点:

  1. 优化模型对小目标的检测效果。
  2. 减少训练算力,由于一次性可以计算4张图片,所以Batch Size可以不用很大,也为YOLOv4在一张GPU卡上完成训练奠定了数据基础。
  3. 依然是一种增强数据操作,让模型的鲁棒性与泛化性能更优。

而上面提到的CutMix则从Mixup和Cutout优化而来。

由上图可知,Mixup将两张图片按比例混合,其label也按同等比例分配;Cutout则是将图片中的部分像素区域置0,但是label不变;CutMix则是在Cutout的基础上对置0的像素区域随机填充其他图像的部分像素值,label则按同等比例进行分配。

其中, M M M是二进制 0 , 1 0,1 0,1矩阵,用来标记需要裁剪的区域和保留的区域,裁剪的区域值均为 0 0 0,其余位置为 1 1 1。图片 A A A B B B组合得到新样本,最后两个图的label也对应求加权和。

CutMix的优势:

  1. 由于采用填充的形式,合成的图片不会有不自然的混合情形。
  2. 高价值信息增多,提升训练效率,优化算法性能。
  3. 作为YOLOv4的Bag of freebies,其不增加模型的推理耗时。
  4. 增加算法的局部识别与局部定位能力。
  5. 在输入侧,起到了类似dropout的作用。

YOLOv4 Backbone大解析

YOLOv4的Backbone在YOLOv3的基础上,受CSPNet网络结构启发,将多个CSP子模块进行组合设计成为CSPDarknet53,并且使用了Mish激活函数

CSPDarknet53总共有72层卷积层,遵循YOLO系列一贯的风格,这些卷积层都是 3 × 3 3\times3 3×3大小,步长为2的设置,能起到特征提取与逐步下采样的作用。

CSP子模块主要解决了由于梯度信息重复导致的计算量庞大的问题。

CSP模块不仅仅是一个子结构,更是一个处理思想,可以和ResNet、ResNext、DenseNet、EfficientNet等网络结合使用。

上图左侧是DenseNet的结构,它进行反向传播时会有大量的重复计算,而右侧的图是CSP模块结构,它将基础层的特征图分成两部分,一部分直接与该阶段的末尾concat相连,另一部分经过局部Dense模块,从而既能保留Dense模块的特征复用,又能截断梯度流,避免大量的重复计算,同时可以保证准确率。

总的来说,CSP模块解决了三个方面的问题:

  1. 提升模型的学习能力,同时使模型轻量化。
  2. 降低计算瓶颈,提高硬件利用率。
  3. 降低模型的内存占用。

CSP模块逻辑也可以迁移到其他Backbone网络,例如优化ResNet以提升性能:

CSPNet论文地址:CSPNet

YOLOv4论文中通过消融实验发现使用Mish激活函数会提升性能,于是在Backbone中将其使用。(注:除Backbone以外的网络结构依旧使用LeakyReLU激活函数)

Mish激活函数的示意图如下,其有三个主要特征:

  1. 无上界有下界。Mish向上无边界避免了由于封顶而导致的梯度饱和,加快训练过程。向下有边界有助于实现强正则化效果。
  2. 非单调函数。允许其在负半轴有稳定的微小负值,从而使梯度流更稳定。与ReLU负半轴的硬零边界相比,其梯度更平滑。
  3. 无穷连续性与光滑性。具有较好的泛化能力,提高训练结果的质量。

Mish激活函数的表达式:

Mish激活函数论文地址:Mish激活函数

YOLOv4 Neck大解析

YOLOv4的Neck结构主要包含了SPP模块和PAN模块

SPP模块在YOLOv3_SPP.cfg中率先展现,但是在YOLOv4中则成为了一个标配。SPP模块包含3个最大池化层,其滑动核(sliding kernel)尺寸分别是 5 × 5 , 9 × 9 和 13 × 13 5 \times 5, 9 \times 9和 13 \times 13 5×5,9×913×13,并通过Padding操作,使每个最大池化层的输出特征图不变,用于Concat融合操作。

SPP模块代替了卷积层后的常规池化层,可以增加感受野,更能获取多尺度特征,训练速度也让人满意。Yolov4论文中使用 608 × 608 608\times608 608×608的图像在COCO目标检测任务进行实验,SPP模块能以0.5%的额外计算代价将AP50提升2.7%

SPP模块论文:Spatial Pyramid Pooling in Deep Convolutional
Networks for Visual Recognition

PAN模块不同层次的特征进行疯狂融合,其在FPN模块的基础上增加了自底向上的特征金字塔结构,保留了更多的浅层位置特征,将整体特征提取能力进一步提升

在引入YOLOv4时,特征图最后的融合操作相比于原论文发生了变化,从add操作改为concat操作,增加了特征图的通道数:

PAN模块论文:Path Aggregation Network for Instance Segmentation

YOLOv4 Head大解析

YOLOv4的Head结构沿用了YOLOv3的整体架构,并引入了CIOU Loss和DIOU NMS来提升Head结构的整体性能

在YOLOv3中,使用MSE(均方误差)损失函数对检测框的中心点以及宽高坐标进行优化。在MSE损失函数的逻辑中,将检测框的中心点和宽高坐标作为独立的变量对待,但是实际上他们之间是有关联的。所以一个直观的解决方案是使用IOU损失代替MSE损失。

YOLOv4论文中依次提到了IOU Loss,GIOU Loss,DIOU Loss以及CIOU Loss。其中IOU Loss是其他Loss的基石,也最为简单,公式如下:

L I O U = 1 − I O U ( A , B ) = 1 − A ∩ B A ∪ B L_{IOU} = 1 – IOU(A,B) = 1 – \frac{A \cap B}{A \cup B} LIOU=1IOU(A,B)=1ABAB

其中 A A A 代表检测框, B B B 代表ground truth, I O U IOU IOU 代表两者的交并比。

IOU Loss思想简洁明了,但存在两个问题:

  1. 当检测框和ground truth不相交时,会使IOU=0,从而无法反应两个框距离的远近,进而导致IOU Loss不可导。
  2. 当两个检测框大小相同,IOU也相同时,IOU Loss无法区分两者位置的差异。

而GIOU Loss能改进这些问题,其在检测框与ground truth之外映射一个最小外接矩形来缓解IOU Loss存在的问题,其公式和图解如下:

L G I O U = 1 − G I O U = 1 − I O U ( A , B ) + ∣ C − A ∪ B ∣ ∣ C ∣ L_{GIOU} = 1 – GIOU = 1 – IOU(A,B) + \frac{|C – A \cup B|}{|C|} LGIOU=1GIOU=1IOU(A,B)+CCAB

其中 C C C 代表最小外接矩形,最后一项代表使用差集来进行约束与惩罚。

但出现上图右侧的情况时,GIOU Loss被打回原形。

DIOU Loss在GIOU Loss基础上提出了中心点距离的概念,来改进GIOU Loss被打回原形的问题。

对ground truth和检测框的中心点进行度量,引入位置信息的同时加快了损失函数的收敛,其公式如下:

L D I O U = 1 − D I O U = 1 − I O U ( A , B ) + D 2 2 D 1 2 L_{DIOU} = 1 – DIOU = 1 – IOU(A,B) + \frac{D_2^2}{D_1^2} LDIOU=1DIOU=1IOU(A,B)+D12D22

但是DIOU Loss仍存在检测框长宽比带来的新问题:

最后,就是YOLOv4中使用的CIOU Loss登场了。CIOU Loss在DIOU Loss的基础上考虑了检测框长宽比的因素,将检测框回归损失的三大逻辑:重叠面积、中心点距离,长宽比进行了有效整合,其公式如下:

L C I O U = 1 − C I O U = 1 − I O U ( A , B ) + D 2 2 D 1 2 + v 2 ( 1 − I O U ( A , B ) ) + v L_{CIOU} = 1 – CIOU = 1 – IOU(A,B) + \frac{D_2^2}{D_1^2} + \frac{v^2}{(1 – IOU(A,B)) + v} LCIOU=1CIOU=1IOU(A,B)+D12D22+(1IOU(A,B))+vv2

其中 v v v 代表了长宽比一致性的参数:

v = 4 π 2 ( a r c t a n w g t h g t − a r c t a n w h ) 2 v = \frac{4}{\pi^2}(arctan\frac{w^{gt}}{h^{gt}} – arctan\frac{w}{h})^2 v=π24(arctanhgtwgtarctanhw)2

在使用了CIOU Loss之后,YOLOv4的整体损失函数如下所示:

$$\begin{aligned}
Loss = CIOULoss + \sum{S2}{i=0}\sum{B}_{j=0}I{obj}{ij}[C_i\log(C_i) + (1-\hat{C}_i)\log(1-\hat{C}_i)]\

  • \lambda_{noobj} \sum{S2}{i=0}\sum{B}_{j=0}I{noobj}{ij}[C_i\log(C_i) + (1-\hat{C}_i)\log(1-\hat{C}_i)]\
  • \sum{S2}{i=0}I^{obj}{ij}\sum_{c\in classes}[P_{i}©\log(P_{i}©) + (1 – \hat{P}{i}©)\log(1-\hat{P}{i}©)]
    \end{aligned}$$

介绍完YOLOv4的CIOU Loss以及整体损失函数,接下来我们来介绍YOLOv4对NMS操作的优化。

YOLOv4改进了YOLOv1-v3中使用的传统NMS操作,使用了DIOU思想计算“IOU”值,进一步优化了后处理效果。CIOU思想在训练中有很大作用,但是在Inference过程中,并没有ground truth的信息,所以使用DIOU足矣,且能减少计算量。

YOLOv4 Tricks大解析

YOLOv4在YOLOv3的基础上,设计使用了SAT,CmBN和Label Smoothing等Tricks

YOLOv4中的SAT(self adversarial training) 使用基于FGSM原理的梯度攻击技术,生成对抗样本进行对抗训练。

首先,什么是对抗样本呢?对抗样本是在原图像中增加扰动噪声生成,如上图所示。对抗样本容易使得模型输出错误判断,这给模型的鲁棒性造成了重大挑战。

打不过,就加入它。秉持着这个原则,我们在训练时将对抗样本加入训练集一起训练,即为对抗训练。进行对抗训练能扩充训练集的可能性,使得数据集逼近我们想要的数据分布,训练后的模型鲁棒性和泛化性能也大大增强。

生成对抗样本的方法主要分为三种,具体逻辑如下图所示。

**CmBN(Cross mini-Batch Normalization)**是CBN的修改版。

CBN主要用来解决在Batch-Size较小时,BN的效果不佳问题。CBN连续利用多个迭代的数据来变相扩大Batch-Size从而改进模型的效果。(每次迭代时计算包括本次迭代的前四个迭代后统一计算整体BN)

而CmBN是独立利用多个mini-batch内的数据进行BN操作。(每四个迭代后统一计算一次整体BN)

Label Smooth可以看作是一种防止过拟合的正则化方法。

其主要是在One-Hot标签中加入噪声,减少训练时GroundTruth在计算损失函数的权重,来达到防止过拟合的作用,增强模型的泛化能力。

通常参数设置如下图中的比例即可。

【Rocky的延伸思考】

  1. YOLOv4中的输入侧和Tricks具备在业务,竞赛以及研究中进行实验的价值。
  2. 业务:YOLOv4 Backbone中使用的CSP思想可以方便地与业务场景相结合。Neck结构和Head中提出的CIOU Loss和DIOU NMS可以作为工程基线模型的首选。
  3. 竞赛:YOLOv4 Backbone中提到的CSP结构和Mish激活函数在竞赛中是比较有效的Tricks。Neck结构可以作为竞赛的入场结构。Head中提出的CIOU Loss和DIOU NMS在竞赛中的依旧是提分利器。
  4. 研究:YOLOv4 整体结构具备作为研究Baseline的价值。

【七】YOLOv5 输入侧,Backbone,Neck,Head,Tricks大解析

同样的,Rocky在这里先分享一下YOLOv5的整体结构:

YOLOv5 输入侧大解析

YOLOv5的输入侧同样使用了Mosaic高阶数据增强策略,并增加自适应图像调整策略

值得一提的是,正是Mosaic论文的作者提出了YOLOv5,并且YOLOv5的输入侧做了很多工程优化,对工业界非常友好

而自适应图像调整策略可以优化常规图像缩放填充引入过多无效信息导致Inference耗时增加的问题。其逻辑主要是计算图像原生尺寸与输入尺寸的缩放比例,并获得缩放后的图像尺寸,最后再进行自适应填充获得最后的输入图像,具体代码逻辑可以在datasets.py的letterbox函数中查看。

YOLOv5 Backbone大解析

YOLOv5的Backbone同样使用了YOLOv4中使用的CSP思想

值得一提的是,YOLOv5最初版本中会存在Focus结构,在YOLOv5第六版开始后,就舍弃了这个结构改用 6 × 6 , s t r i d e = 2 6\times6,stride=2 6×6stride2的常规卷积,其产生的参数更少,效果更好。

YOLOv5 Neck大解析

由于YOLOv5在YOLOv4发布之后没多久就开源了,且并没有论文的发表,创新性部分一直受到热议。

YOLOv5的Neck结构也使用了SPP模块和PAN模块,但是在PAN模块进行融合后,将YOLOv4中使用的常规CBL模块替换成借鉴CSPnet设计的CSP_v5结构,加强网络特征融合的能力

YOLOv5 Head大解析

YOLOv5的Head结构在YOLOv4的基础上引入了Auto Learning Bounding Box Anchors(自适应anchor box)和邻域正负样本分配策略

YOLOv5的anchor box是自适应于训练数据的,会根据不同的训练数据自动学习适配相应的anchor box。代码中具体的对应函数是check_anchor函数。

由于增加高质量正样本检测框可以显著加速收敛,故YOLOv5设计了相应的邻域正负样本分配策略,其主要流程如下:

  1. 将ground truth与当前feature map中的anchor box进行比较,如果ground truth与anchor box的宽高比例都处在 [ 1 4 , 4 ] [\frac{1}{4},4] [41,4],那么这个ground truth就能与当前featuer map相匹配。
  2. 将当前feature map中的ground truth分配给对应的grid cell。将这个grid cell分为四个象限,针对与当前feature map匹配的ground truth,会计算该ground truth处于四个象限中的哪一个,并将邻近的两个grid cell中的检测框也作为正样本。如下图所示,若ground truth偏向于右上角的象限,就会将ground truth所在grid cell的上面和右边的grid cell中的检测框也作为正样本。

比起yolov4中一个ground truth只能匹配一个正样本,YOLOv5能够在多个grid cell中都分配到正样本,有助于训练加速和正负样本平衡

YOLOv5 Tricks解析

YOLOv5中使用的Tricks基本上和YOLOv4一致,并在此基础上引入了更多的工程优化逻辑

YOLOv5通过不同的训练参数配置,用来获得不同复杂度的模型。

除此之外,YOLOv5还尝试了混合精度训练和模型EMA(Exponential Moving Average)策略

混合精度训练能在尽可能减少精度损失的情况下利用FP16加速训练,并使用FP16存储模型权重,在减少占用内存的同时起到了加速训练的效果

模型EMA(Exponential Moving Average)策略将模型近期不同epoch的参数做平均,提高模型整体检测性能以及鲁棒性

【Rocky的延伸思考】

  1. YOLOv5 整体结构的易用性使得其不管在业务,竞赛还是研究中都非常友好,且其github库更新频率让人敬佩。YOLOv5可以说是YOLO系列在工业界用的最多最广泛的一个分支,因为其是Pytorch架构的,减少了工业界人员对Darknet不熟悉不从容的麻烦。

【八】YOLOx 输入侧,Backbone,Neck,Head,Tricks大解析

首先,Rocky在这里先分享一下YOLOx的整体结构:

YOLOx 输入侧大解析

YOLOx的输入侧在YOLOv5的基础上摒弃了预训练逻辑,并使用Mosaic和MixUp高阶数据增强算法

MixUp最初应用在分类任务上,将两张图片通过设定的融合系数进行融合,两个图片上的label也对应融合。

由于Mosaic和MixUp高阶数据增强算法已经足够强大,在这种情况下ImageNet预训练并不能带来有效增益,故YOLOx摒弃了预训练逻辑,并从头训练

YOLOx Backbone大解析

YOLOx的Backbone沿用了YOLOv3的Backbone结构,故在此不在展开介绍。

YOLOx Neck大解析

YOLOx的Neck依然使用了YOLOv3的结构,并且使用了SPP模块。

YOLOx Head大解析

YOLOx的Head结构在YOLOv5的基础上在网络结构中引入了Decoupled Head,并使用anchor-free思想和SimOTA正负样本分配策略进行损失函数的计算与优化

YOLOx使用了三个Decoupled Head(解耦头),分别聚焦cls(分类信息),reg(检测框信息)和IOU(置信度信息)。常规的检测头在特征的表达与学习能力上比起Decoupled Head有所欠缺,并且Decoupled Head模块能加快模型的收敛速度

除此之外,YOLOx还使用anchor-free思想,比起YOLO系列中常规的anchor-based,在Head侧可以减少约 2 3 \frac{2}{3} 32 的参数。比起anchor-based方法使用先验知识设计anchor尺寸,anchor-free思想将感受野作为“anchor”信息。上述三个Decoupled Head中最上面的分支对应着大anchor框,中间的分支对应着中等anchor框最下面的分支对应着小anchor框。最后的输出将这个三个分支融合成一个 85 × 8400 85 \times 8400 85×8400 的特征向量。

接下来就是介绍YOLOx的正负样本分配策略了,我们知道目标检测场景一张图像中往往负样本占绝大多数,而正样本只是少数。为了获得更多高质量的正样本,YOLOx中设计了样本初筛+SimOTA逻辑。

在样本初筛中,有两种方法来筛选正样本:

  1. 根据中心点判断:找到中心点落在ground truth框中的所有anchor box。
  2. 根据检测框判断:以ground truth中心点作为基准,绘制一个边长为5的正方形,找到中心点落地这个正方形中的所有anchor box。

经过初筛之后,再使用SimOTA进行精细化筛选。其主要流程如下:

  1. 通过上面提到的样本初筛方法,获取正样本,同时获取它们的特征信息(cls,reg,IOu)。
  2. 计算正样本与ground truth的Reg Loss和Cls Loss,并将它们加权相加,Reg和Cls的权重为 3 : 1 3:1 3:1。(loss aware)
  3. 通过每个ground truth的检测样本来确定其能分配到的高价值正样本数(Dynamic K),其逻辑是获取与当前ground truth的IOU值前10的检测框,并将它们求和并取整,计算出来的整数就作为当前ground truth的正样本数“容量”。
  4. 确定每个ground truth的Dynamic K个正样本,其逻辑是选取步骤2中加权Loss最小的前K个样本作为正样本。
  5. 共用正样本去重,其逻辑是如果一个检测框被两个及以上的ground truth认作正样本,那么再次使用加权Loss进行评判,将这个检测框分给加权Loss最小的那个ground truth,作为其独有的正样本。

YOLOv5的正负样本分配策略是基于邻域匹配,并通过跨网格匹配策略增加正样本数量,从而使得网络快速收敛,但是该方法属于静态分配方法,并不会随着网络训练的过程而调整。YOLOx使用的SimOTA能够算法动态分配正样本,进一步提高检测精度。而且比起OTA由于使用了Sinkhorn-Knopp算法导致训练时间加长,SimOTA算法使用Top-K近似策略来得到样本最佳匹配,大大加快了训练速度

YOLOx Tricks解析

YOLOx使用了YOLOv5中提到的模型EMA(Exponential Moving Average)策略,并且使用余弦退火学习率优化训练过程

余弦退火学习率衰策略(CosineAnnealingLR)使得学习率呈周期性变化,但我们通常取它的一个余弦周期来完成整个训练过程。

另外,固定步长衰减(StepLR),多步长衰减(MultiStepLR),指数衰减(ExponentialLR)等都是经典实用的学习率衰减策略。

固定步长衰减在每隔一定的步长或者epoch对学习率进行一定衰减,而多步长衰减策略比起固定步长衰减则更加灵活,它可以在不同阶段使用不同强度和频率的衰减策略。指数衰减策略是使用指数逻辑对学习率进行衰减。

【Rocky的延伸思考】

YOLOx 整体结构给业务,竞赛以及研究提供了一些新思路,一定的落地价值。Rocky也很想知道YOLOv7引入Decoupled Head会是什么样的效果。

【九】YOLOv6 输入侧,Backbone,Neck,Head,Tricks大解析

首先,Rocky在这里先分享一下YOLOv6的整体结构:

YOLOv6 输入侧大解析

YOLOv6的输入侧沿用了YOLOv5的整体逻辑,并没有引入新的Tricks,故就不再展开赘述。

YOLOv6 Backbone大解析

YOLOv6的Backbone结构在YOLOv5的基础上,设计了EfficientRep Backbone结构

和YOLOv5的Backbone相比,YOLOv6的Backbone不但能够高效利用硬件算力,而且还具有较强的表征能力。

YOLOv6的Backbone中将普通卷积都替换成了RepConv结构。同时,在RepConv基础上设计了RepBlock结构,其中RepBlock中的第一个RepConv会做channel维度的变换和对齐。

另外,YOLOv6将SPPF优化设计为更加高效的SimSPPF,增加特征重用的效率。

YOLOv6 Neck大解析

YOLOv6的Neck结构受到硬件感知神经网络设计思想的启发,基于RepVGG style设计了可重参数化、更高效的Rep-PAN

硬件感知神经网络设计的思想基于硬件的特性、推理框架/编译框架的特点,以硬件和编译友好的结构作为设计原则,在网络构建时,综合考虑硬件计算能力、内存带宽、编译优化特性、网络表征能力等,进而获得又快又好的网络结构。

Rep-PAN在PAN模块基础上,引入RepVGG style的RepBlock替换了YOLOv5中使用的CSP-Block,同时对整体Neck中的算子进行了调整,目的是在硬件上达到高效推理的同时,保持较好的多尺度特征融合能力。

RepVGG论文:RepVGG: Making VGG-style ConvNets Great Again

YOLOv6 Head大解析

YOLOv6的Head结构和YOLOx一样使用Anchor-free逻辑和SimOTA标签分配策略,并在其基础上改进了Decoupled Head(解耦检测头)结构,在损失函数中引入了SIoU边界框回归损失

YOLOv6依然采用了Decoupled Head结构,并对其进行了精简设计。YOLOX的检测头虽然提升了检测精度,但一定程度上增加了网络延时。YOLOv6采用Hybrid Channels策略重新设计了一个更高效的Decoupled Head结构,在维持精度的同时降低了延时,缓解了Decoupled Head中 3 × 3 3\times 3 3×3 卷积带来的额外延时开销

为了进一步提升回归精度,YOLOv6使用了SIoU检测框回归损失函数来优化网络的学习过程。

YOLOv4中的CIoU Loss虽然考虑到检测框与ground truth之间的重叠面积、中心点距离,长宽比这三大因素,但是依然缺少了对检测框与ground truth之间方向的匹配性的考虑。SIoU Loss通过引入了所需回归之间的向量角度,重新定义了距离损失,有效降低了回归的自由度,加快网络收敛,进一步提升了回归精度

SIOU Loss论文地址:SIoU Loss: More Powerful Learning for Bounding Box Regression

YOLOv6 Tricks大解析

YOLOv6进行了很多蒸馏方向上的尝试

比如Self-distillation,Reparameterizing Optimizer,使用 Channel-wise Distillation进行量化感知训练等方法,进一步加强模型的整体性能。

【Rocky的延伸思考】

  1. 业务:YOLOv6 Backbone可以高效用于业务向的部署端。Neck结构使用了端侧友好的设计策略,Rocky也在实际中测试过,发现其效果会因任务类型与场景的改变而变化,是否使用还需要通过实验来反馈。
  2. 竞赛:YOLOv6 Backbone可以用于竞赛的Baseline尝试。Rocky也相信YOLOv6会在一些限定算力资源的竞赛中会大放异。
  3. 研究:YOLOv6 整体结构可以用于研究的入场Baseline。

【十】YOLOv7 输入侧,Backbone,Neck,Head,Tricks大解析

首先,Rocky在这里先分享一下YOLOv7的整体结构:

YOLOv7 输入侧大解析

YOLOv7的输入侧沿用了YOLOv5的整体逻辑,并没有引入新的Tricks,故就不再展开赘述。

YOLOv7 Backbone大解析

YOLOv7的Backbone结构在YOLOv5的基础上,设计了E-ELAN和MPConv结构

E-ELAN结构会在后面的Neck部分中详细介绍,这里就不再展开。MPConv结构由常规卷积与maxpool双路径组成,增加模型对特征的提取融合能力。不管是E-ELAN还是MPConv结构,都将特征重用逻辑演绎到了比较高的水准,让人眼前一亮

YOLOv7 Neck大解析

YOLOv7的Neck结构主要包含了SPPSCP模块和优化的PAN模块

SPPCSP模块在SPP模块基础上在最后增加concat操作,与SPP模块之前的特征图进行融合,更加丰富了特征信息。

PAN模块引入E-ELAN结构,使用expand、shuffle、merge cardinality等策略实现在不破坏原始梯度路径的情况下,提高网络的学习能力。

论文原文:(E-ELAN uses expand, shuffle, merge cardinality to achieve the ability to continuously enhance the learning ability of the network without destroying the original gradient path.)

YOLOv7 Head大解析

YOLOv7的Head结构使用了和YOLOv5一样的损失函数,引入RepVGG style改造了Head网络结构,并使用了辅助头(auxiliary Head)训练以及相应的正负样本匹配策略

RepVGG style在训练过程中可以通过多路分支提升性能,推理可以通过结构重新参数化实现推理速度的加快

Rocky之前也对RepVGG style思想进行迁移性实验,发现RepVGG style在不同模型中的兼容性并不是很强,往往需要针对当前的模型和场景进行大量调参才能展现效果。

YOLOv7在Head结构引入了辅助头(auxiliary Head)进行训练。正常网络训练如上图(a)所示,而用辅助头参与训练时,将对模型的训练进行深度监督,如上图(b)所示。将辅助头和检测头的损失进行融合,相当于在网络高层进行局部的模型ensemble操作,提升模型的整体性能

而YOLOv7的正负样本分配策略正是围绕着检测头(lead head)与auxiliary Head进行设计,其主要是将YOLOv5和YOLOx的正负样本分配策略相结合:

  1. 使用YOLOv5的正负样本分配策略分配正样本。

  2. 使用YOLOx的正负样本分配策略确定正样本。

YOLOv7的正负样本分配策略相较于yolov5,加入了loss aware,利用当前模型的表现,能够实时精筛;而较于只使用YOLOX中的SimOTA算法,能够提供更精确的先验知识

上图(d)中,lead head和auxiliary head使用一样的正负样本匹配策略,通过让浅层的auxiliary head学习到lead head已经获得的特征,让lead head更能专注于学习尚未学习到的剩余特征

而上图(e)中,在使用lead head和auxiliary head一起优化模型的时候,auxiliary head的正样本是较为“粗糙的“,主要是通过放宽正样本分配过程的约束来获得更多的正样本。lead head中的一个anchor如果匹配上ground truth,则分配3个正样本,而同样的情况下auxiliary head分配5个。lead head中将top10个样本IOU求和取整,而auxiliary head中取top20。auxiliary head的学习能力不如lead head强,为了避免丢失需要学习的信息,将重点优化auxiliary head的召回率。而lead head可以从高recall的结果中筛选出高精度的结果作为最终输出。lead head和auxiliary head的损失函数权重设置为 4 : 1 4:1 4:1

YOLOv7 Tricks大解析

YOLOv7也使用了YOLOv5中提到的模型EMA(Exponential Moving Average)策略,并引入了YOLOR中使用的隐性知识

YOLOR中的隐式知识可以在推理阶段将计算值简化为向量。这个向量可以与前一层或后一层卷积层的偏差和权重相结合。

由于篇幅原因,在这里就不展开讲了,后续Rocky将专门对蒸馏技术撰写一篇总结文章,大家敬请期待!

【Rocky的延伸思考】

  1. 蒸馏技术在业务,竞赛以及研究中的应用落地,以及蒸馏技术自身的发展,都是值得我们关注的地方。
  2. 业务:YOLOv7 整体结构作为YOLO系列最新的一版,其值得我们在业务中进行实验验证其效果。
  3. 竞赛:YOLOv7 整体结构可以在竞赛中实验其效果,在竞赛中去融入,去从容。
  4. 研究:YOLOv7 作为最新的YOLO版本,有很强的研究价值,Rocky这边准备进行更多实验。

精致的结尾

Rocky将算法高价值面试知识点即“三年面试五年模拟”之独孤九剑秘籍前六式进行汇总梳理成汇总篇,并制作成pdf版本,大家可在公众号后台 【精华干货】菜单或者回复关键词“三年面试五年模拟” 进行取用。由于“三年面试五年模拟”之独孤九剑秘籍pdf版本是Rocky在工作之余进行整理总结,难免有疏漏与错误之处,欢迎大家对可优化的部分进行指正,Rocky将在后续的优化迭代版本中及时更正。

Rocky一直在运营技术交流群(WeThinkIn-技术交流群),这个群的初心主要聚焦于技术话题的讨论与学习,包括但不限于算法,开发,竞赛,科研以及工作求职等。群里有很多人工智能行业的大牛,欢迎大家入群一起学习交流~(请添加小助手微信Jarvis8866,拉你进群~)