由于在海量数据与计算力的加持下,深度学习对图像数据表现出强大的表示能力,成为了机器视觉的热点研究方向。
关于目标检测
图像理解包括分类、定位、检测与分割等单个或组合任务,如下图所示:
目标检测也可以看作是对图像中的背景和前景作某种理解分析,即从图像背景中分离出感兴趣的目标,得到对于目标的描述<位置,类别>
。
由于可能有多个目标存在,模型输出是一个列表,包含目标的位置以及目标的类别。目标位置一般用矩形检测框(包围盒)的中心和宽高来表示。
目标检测的核心问题可以简述为图像中什么位置有什么物体
:
- 定位问题:目标出现在图像中哪个位置(区域)。
- 分类问题:图像的某个区域里的目标属于什么类别。
基于深度学习的目标检测算法目前主要分为两类:Two-stage
和 One-stage
。
- Tow-stage:先生成区域(region proposal,简称 RP),即一个可能包含待检物体的预选框,再通过卷积神经网络进行分类。
任务流程:特征提取 --> 生成 RP --> 分类/定位回归。 常见
Two-stage
目标检测算法有:R-CNN、Fast R-CNN、Faster R-CNN、SPP-Net 和 R-FCN 等。
- One-stage:直接用网络提取图像特征来预测物体位置和分类,因此不需要 RP。
任务流程:特征提取–> 分类/定位回归。
常见的 One-stage
目标检测算法有:YOLO 系列、SSD 和 RetinaNet 等。不过,为了得到最终目标的定位和分类,往往需要后处理。
yolo 简介
YOLO 全称叫 You Only Look Once。它通过一系列的卷积操作来实现端到端的目标检测。YOLO 会将图片划分为 S x S 的网格(grid),每个网格负责检测落入其中的目标,最后输出所含目标的边框(bounding box)、定位的位置信息、以及所有类别的置信度。
基本流程如下:
- 首先将输入图片 resize 到固定大小。
- 输入到网络中,最后得到预测结果检测到的目标。
- 使用非极大抑制算法来过滤冗余目标。
非极大值抑制算法(nms)
不仅仅是YOLO才会使用到nms,其实在大多数目标检测算法都会使用nms。它主要是为了解决一个目标被重复检测的现象。如下图,我们可以看到人脸被重复检测了。虽然每个框都检测对了,但我们只需要得到一个框,即最好的那一个框。
那么采用NMS就可以实现这样的效果。首先从所有的检测框中找到置信度最大的那个,然后遍历剩余的框,计算其与最大框之间的IOU。如果其值大于一定阈值,则表示重合度过高,那么就将该框就会被剔除;然后对剩余的检测框重复上述过程,直到处理完所有的检测框。
YOLOv1(2015)
其实 YOLOv1 和后续的 YOLO 算法最大的不同是 YOLOv1 并没有使用锚点框(anchor box),在 YOLOv1 中是没有 anchor 这个概念的,严格上来说 YOLOv1 属于 anchor free。
-
将图像划分为 S x S 的网格,论文中的设置是 7 x 7 的网格。如果某个物体的中心落在这个网格中,那么这个网格就负责预测这个物体。
-
然后每个网格预测 B 个边框,论文中的设置是2个边框,即预测出 7 x 7 x 2 个边框,这个边框负责预测物体的位置。
-
每个边框除了要预测物体的位置之外,还要附带预测一个置信度。这里的置信度指的是边框的概率,无关目标属于哪一个类别,表示的是边框内是否有物体。
-
每个网格还要预测C个类别的分数。比如说在 VOC 数据集上则会预测出20个类别。
-
因此,对于 VOC 数据集来说,YOLOv1 的网络最后是输出预测位置(xywh)+置信度以及类别分数,所以输出为 7 x 7 x (5 + 5 + 20)。
-
最后一层全连接层用线性激活函数,其余层采用 Leaky ReLU。
不足之处
-
因为每个网格单元只预测两个框,并且只有一个类别。即每个网格只会选择出 IOU 最高的那个目标,所以如果每个网格包含多个物体,就只能检测出其中一个,所以对于拥有群体小目标的图片来说,比如鸟群,检测效果会很差。也可能是因为这种方式导致减少了对同一目标的多次检测,最终识别物体位置精准性差,召回率低。
-
当出现新尺寸的目标时,效果也会变差,原因是 YOLOv1 使用简单的特征来预测边界框,并没有使用 anchor,导致定位的不准确。
-
最后的输出层为全连接层。因为全连接层输出大小是固定的,所以导致图像的输入大小也必须固定,这在一定程度上来说有局限性。
-
MSE 在处理大边框和小边框时,赋予的权重是一样的。假设同样是预测与实际相差25个像素点,但是对于大边界框来说,小错误通常是无足轻重的,甚至可以忽略不计,但对于小边界框来说,这个数值对于它的影响就很大了。
YOLOv2(2016)
【亮点】 比Yolo v1在精度、速度和分类数量上都有了很大的改进,检测种类扩充到了上千种。
YOLOv2 也叫 YOLO9000,因为使用了 COCO 数据集以及 Imagenet 数据集来联合训练,最终可以检测9000个类别。
-
使用 Darknet19 作为网络的主干网络。Darknet19 有点类似 VGG,在 Darknet19 中,使用的是 3 x 3 大小的卷积核,并且在每次Pooling 之后都增加一倍通道数,以及将特征图的宽高缩减为原来的一半。网络中有19个卷积层,所以叫 Darknet19,以及有5个Max Pooling 层,所以这里进行了32倍的下采样。
-
采用了 Batch Normal 层来加速训练时的收敛速度,并且使用了 Batch Normal 就可以从去掉 Dropout,而不会产生过拟合。在 Batch Normal 的论文中讲道, Batch Normal 作用和 Dropout 的作用是类似的。
-
使用了先验框 anchor,基于 Kmeans 的聚类方法来根据数据集的标签来自动提取先验框的信息,所以可根据不同的数据集设置 anchor 。当 Cluster IOU 选择值为5时,Avg IOU比不用聚类的方法要高一些。选择值为9的时候,Avg IOU有更加明显地提升。
-
使用了更高的分辨率,训练时从 224 x 224 提升到了 448 x 448。并且采用了随机裁剪、旋转、颜色变换、饱和度变换, 曝光度变换等数据增强的操作。
-
可以进行多尺度训练,每迭代10个 batch,随机更换尺寸320、352...608,注意这里都为32的倍数,因为在 Darknet19 中进行了32倍的下采样操作。
-
使用了 Pass through,类似 Pixel-shuffle,融合高层和低层的信息,这样可以保留一些细节信息,这样可以更好检测小物体。具体来说,就是进行一拆四的操作,直接传递到池化后的特征图中,进行卷积后再叠加两者,最后一起作为输出特征图进行输出。通过使用 Pass through 层来检测细粒度特征使 mAP 提升了1个点。
-
网络去掉了最后一个卷积层,而加上了三个 3 x 3 卷积层,分别预测大尺度、中尺度、小尺度的物体。其中每个卷积层有1024个卷积核,并且每个卷积层紧接着一个 1 x 1 卷积层。每个 anchor 预测5个边界框,所以对于 VOC 数据集来说,每个边界框会输出5个坐标的相关信息和20个类别的相关信息。
在 YOLOv2 中,就是预测边界框中心点是相对于对应网格的左上角位置进行相对偏移,为了将边界框中心点约束在当前网格中,使用 sigmoid 函数处理偏移值,这样预测的偏移值在(0,1)范围内。这里将每个网格的尺度看做是1的基本单位。
YOLOv3(2018)
YOLOv3 采用了作者自己设计的 Darknet-53 作为主干网络,Darknet-53 借鉴了残差网络的思想,与 Resnet101、Resnet152 相比,在精度上差不多的同时,有着更快的速度。
在下采样操作中使用了步长为2的卷积来代替传统的池化操作;在特征融合方面,为了提高小目标的检测性能,引入了类似 FPN 的多尺度特征融合方法,特征图在经过上采样后与前面层的输出进行 concat 操作,这样可以融合浅层特征和深层特征,使得 YOLOv3 在小目标的精度上有了很大的提升。并且使用逻辑回归替代 softmax 作为分类器,为的就是解决多标签分类问题,比如一个物体既属于A类,又属于B类。
从 Yolo v3 的流程图可以看到,总共有 106 层,实现了对每张图像在大、中、小三个尺度上检测目标。这个网格有三个出口,分别是 82 层、94 层、106 层。
算法思想
-
YOLOv3 的输出依旧分为三个部分,首先是置信度、然后是坐标信息,最后是分类信息。在推理的时候,特征图会等分成 S x S 的网格,通过设置置信度阈值对网格进行筛选,如果某个格子上存在目标,那么这个格子就负责预测该物体的置信度、坐标和类别信息。
-
使用了残差模型的思想:Darknet-53。这个是类似 Resnet 的结构,不断堆叠残差结构,并且没有最大池化层。既然没有池化来进行下采样,那么下采样的操作就通过两个步长的卷积操作完成。所以整体来看,网络全部由卷积搭建而成,也就是全卷积网络。基本部件DBL:Conv + BN + Leaky ReLU、残差结构 res_unit。
-
多尺度预测,采用类似 FPN 融合的方式,在三个不同尺寸大小的特征层上预测不同尺度信息,每个特征层三种尺度,所以最后为9个,从 YOLOv2 的5个变成9个。
-
大目标输出维度:13 x 13 x 255,其中255 = ( 80 + 5 ) × 3;中目标输出维度:26 × 26 × 255;小目标输出维度:52 × 52 × 255。这里的80个类别是因为使用了COCO 数据集。
-
采用了新的正负样本匹配策略:如果重合度高但不是最高的,则依旧抛弃。只选取重合度最高的。
-
分类器损失采用二分类交叉损失熵 binary cross-entropy loss(BCE),而不是使用 softmax,因为有的目标可能存在重叠的类别标签,也就是多标签分类。如 SUV 又是车又是 SUV,而 softmax 只会输出最大的那一个类别。
为什么 YOLOv3会比 SSD 快3倍?因为 SSD 的 backbone 使用的是 VGG16,YOLOv3 用的其最新原创的 Darknet,Darknet-53 与 Resnet 的网络结构,Darknet-53 会先用 1 x 1 的卷积核对 feature 进行降维,随后再使用 3 x 3 的卷积核升维。
在这个过程中,这样可以大大降低参数的计算量以及模型的大小,有点类似于低秩分解。究其原因还是做了很多优化,比如用卷积替代全连接,1 x 1 卷积减小计算量等。
【不足】 YOLO v3采用MSE作为边框回归损失函数,这使得YOLO v3对目标的定位并不精准。
【后人改进思考】 出现后来IOU的变种,如GIOU,DIOU和CIOU等一系列边框回归损失,并大大改善了YOLO v3对目标的定位精度。
YOLOv4(2020)
【亮点】 已是2020年,将近年来深度学习领域最新研究的tricks都引入到了YOLO v4做验证测试,在YOLO v3的基础上更进一大步。
【Data augumentation】
- Mosaic数据增强
- 自对抗训练(Self-adversarial-training,SAT):它包括两个阶段。第一个阶段,神经网络更改原始图像;第二阶段,训练神经网络以正常方式在修改后的图像上执行目标检测任务。
【让训练更好的Tricks】
- CmBN归一化:BN是对当前mini-batch进行归一化,CBN是对当前以及当前往前数3个mini-batch的结果进行归一化,而CmBN则是仅仅在这个Batch中进行累积。
- Mish激活函数
- CSAM注意力机制
- 在Neck前,引入了SPP模块
- Cosine annealing scheduler余弦退火学习率
【防止过拟合的Tricks】
- Label Smoothing(防止过拟合)
- Dropblock(放弃掉相关区域特征)
- Random Training Shapes,每隔多少个epoch就随机Resize
【Backbone】 CSPDarknet53
【Neck】 FPN+PAN结构
【分类器】 Logistic
【回归器】 采用CIOU作为网络的边界框损失函数,同时将NMS换成了DIOU_NMS等。
YOLOv5(2020)
YOLOv5 是在 YOLOv4 出来之后没多久就横空出世了。
【亮点】
- 由公司开发,与YOLO V4有点相似,都大量整合了计算机视觉领域的SOTA
- 相比于YOLO V4,YOLO V5在性能上稍微逊色,但其灵活性与速度上远强于YOLO V4,
- 在模型的快速部署上也具有极强优势。
与之前的 YOLOv3、YOLOv4 不同,v3、v4 除了有完整的大模型之外,只有一个轻量级的 tiny 模型,值得注意的是,在 tiny 中,只有两个输出层。而 YOLOv5 则具备四种网络模型:YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x 四种模型。
它们是通过 depth_multiple 和 width_multiple 来控制网络的宽度和深度,这类似 EfficientNet 的思想。
其中,YOLOv5s 在该系列中是深度最小,并且特征图的宽度也最小的网络。其他的网络是在此基础上进行不断地加深、加宽。
YOLOv6(2022)
由美团视觉智能部开源。YOLOv4、YOLOv5更多是注重于数据增强,而对网络结构的改动则比较少。和YOLOv4、YOLOv5不同,YOLOv6对网络结构的改动还是蛮大的。
从YOLOv6的报告来看,它的性能也是再创新高。YOLOv6-s在COCO上精度达到了43.1%AP,在T4上推理速度也高达520FPS!此外,YOLOv6不仅仅关注于学术界所重点关注的AP、FPS指标,对于工业界也是十分友好。
YOLOv6的Backbone不再使用Cspdarknet,而是转为比Rep更高效的EfficientRep;它的Neck也是基于Rep和PAN搭建了Rep-PAN;而Head则和YOLOX一样,进行了解耦,并且加入了更为高效的结构。
值得一提的是,YOLOv6也是沿用anchor-free的方式,抛弃了以前基于anchor的方法。
除了模型的结构之外,它的数据增强和YOLOv5的保持一致;而标签分配上则是和YOLOX一样,采用了simOTA;并且引入了新的边框回归损失:SIOU。这样看来,YOLOv6可谓是结合了两者的优良点。
YOLOv7 (2022)
时隔两年多,YOLOv4官方团队(Chien-Yao Wang , Alexey Bochkovskiy等大佬) 正式发布 YOLOv7!
在 5FPS 到 160 FPS的范围内,YOLOv7 的速度和精度都超过了所有已知的目标检测器。在 V100 上所有已知的 30 FPS或更快的实时目标检测器中,YOLOv7 的准确率最高,AP 达到 56.8%。
YOLOv7-E6
目标检测器(56 FPS V100,55.9% AP)比基于Transformer
的检测器 SWIN-L Cascade-Mask R-CNN
(9.2 FPS A100,53.9% AP)的速度和准确度分别高出 509% 和 2%,并且比基于卷积的检测器 ConvNeXt-XL Cascade-Mask R-CNN
(8.6 FPS A100, 55.2% AP) 速度提高 551%,准确率提高 0.7%,以及 YOLOv7
的表现还优于:YOLOR
、YOLOX
、Scaled-YOLOv4
、YOLOv5
、 DETR
、Deformable DETR
、DINO-5scale-R50
、ViT-Adapter-B
和许多其他速度和准确度的目标检测器。此外,只在 MS COCO
数据集上从零开始训练 YOLOv7
,而不使用任何其他数据集或预训练的权重。
YOLOV7主要的贡献在于:
- 模型重参数化: YOLOV7将模型重参数化引入到网络架构中,重参数化这一思想最早出现于REPVGG中。
- 标签分配策略z: YOLOV7的标签分配策略采用的是YOLOV5的跨网格搜索,以及YOLOX的匹配策略。
- ELAN高效网络架构: YOLOV7中提出的一个新的网络架构,以高效为主。
- 带辅助头的训练: YOLOV7提出了辅助头的一个训练方法,主要目的是通过增加训练成本,提升精度,同时不影响推理的时间,因为辅助头只会出现在训练过程中。
整体上和YOLOV5是相似的,主要是网络结构的内部组件的更换(涉及一些新的sota的设计思想)、辅助训练头、标签分配思想等。整体预处理、loss等可参考yolov5.
YOLOv8 (2023)
YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本,目前支持图像分类、物体检测和实例分割任务,在还没有开源时就收到了用户的广泛关注。
其核心特性和改动可以归结为如下:
- 提供了一个全新的 SOTA 模型,包括 P5 640 和 P6 1280 分辨率 的目标检测网络和基于 YOLACT 的实例分割模型。和 YOLOv5 一样,基于缩放系数也提供了 N/S/M/L/X 尺度的不同大小模型,用于满足不同场景需求
- 骨干网络和 Neck 部分可能参考了 YOLOv7 ELAN 设计思想,将 YOLOv5 的 C3 结构换成了梯度流更丰富的 C2f 结构,并对不同尺度模型调整了不同的通道数,属于对模型结构精心微调,不再是无脑一套参数应用所有模型,大幅提升了模型性能。不过这个 C2f 模块中存在 Split 等操作对特定硬件部署没有之前那么友好了
- Head 部分相比 YOLOv5 改动较大,换成了目前主流的解耦头结构,将分类和检测头分离,同时也从 Anchor-Based 换成了 Anchor-Free
- Loss 计算方面采用了 TaskAlignedAssigner 正样本分配策略,并引入了 Distribution Focal Loss
- 训练的数据增强部分引入了 YOLOX 中的最后 10 epoch 关闭 Mosiac 增强的操作,可以有效 地 提升精度
从上面可以看出,YOLOv8 主要参考了最近提出的诸如 YOLOX、YOLOv6、YOLOv7 和 PPYOLOE 等算法的相关设计,本身的创新点不多,偏向工程实践,主推的还是 ultralytics 这个框架本身 。
按照官方描述,YOLOv8 是一个 SOTA 模型,它建立在以前 YOLO 版本的成功基础上,并引入了新的功能和改进,以进一步提升性能和灵活性。具体创新包括一个新的骨干网络、一个新的 Ancher-Free 检测头和一个新的损失函数,可以在从 CPU 到 GPU 的各种硬件平台上运行。
不过 ultralytics 并没有直接将开源库命名为 YOLOv8,而是直接使用 ultralytics 这个词,原因是 ultralytics 将这个库定位为算法框架,而非某一个特定算法,一个主要特点是可扩展性。其希望这个库不仅仅能够用于 YOLO 系列模型,而是能够支持非 YOLO 模型以及分类分割姿态估计等各类任务。
总而言之,ultralytics 开源库的两个主要优点是:
- 融合众多当前 SOTA 技术于一体
- 未来将支持其他 YOLO 系列以及 YOLO 之外的更多算法
YOLOv8 相比 YOLOv5 精度提升非常多,但是 N/S/M 模型相应的参数量和 FLOPs 都增加了不少,但相比 YOLOV5 大部分模型推理速度变慢了。
现在各个 YOLO 系列改进算法都在 COCO 上面有明显性能提升,但是在自定义数据集上面的泛化性还没有得到广泛验证,至今依然听到不少关于 YOLOv5 泛化性能较优异的说法。
官方开源地址: github.com/ultralytics…
总结
YOLOv5一直是YOLO系列中最成功和最常用的版本之一。