实时目标检测方法 YOLO — 从 V1 到 V4
Apr 25, 2020 in Computer Science, Deep Learning
目前真正能实时(30fps 以上)的目标检测算法效果最好的可能就是 YOLO 了,本文注重它从五年前最初版本到前两天公布的 v4 版本的进化过程,会涉及到很多其它关联算法,希望能说清楚算法流程。此文不会对各种 ablation experiment 有分析,这种实验结果类的应当去看原文,只会提及 mAP 等关键数据;对于 related work 中 YOLO 没有使用的,也不会提到,这也应该去看原文。
论文地址:
- V1,CVPR2016:https://arxiv.org/abs/1506.02640
- V2,CVPR2017:https://arxiv.org/abs/1612.08242
- V3:https://arxiv.org/abs/1804.02767
- V4:https://arxiv.org/abs/2004.10934
- 作者网站:https://pjreddie.com/,上面有一些 slides、oral 视频、审稿 review
- 代码:https://github.com/AlexeyAB/darknet,官方代码是 C/CUDA 写的,除了 OpenCV 不依赖任何第三方库,包括现代的 tensor 库比如 TensorFlow、PyTorch 这些,它本身就是一个框架
下个月应该会把一个两年前做的 R-CNN 系列的 slides 放上来(已更新至 Google Presentation),这样双极网络和单级网络的代表算法系列就齐活了。当然去年以来有一些很重要的 Anchor Free 的算法,虽然也可以划分为双极和单级,但其实挺大区别的,大致它们都是关键点检测的思想用了进来。
下面的图来自 YOLOv4 的论文,检测的各个步骤和相应研究,我觉得分地挺好的。
通常而言,单级网络去除了 Proposals 的生成过程,直接由预设好的 Anchors 加上回归值(SSD),或者网络直接预测框的中心和宽高(YOLO),来给出图像内 BBox 的位置。且单级网络没有特征重采样的过程,始终是一个密集预测,这使得一些平衡正负样本或其它作用的采样方式无法使用。
此外,在两级网络中,对于一个位置上的一组 Anchors 或者一组 Proposals 的 类别 和 回归值,通常是由两个并行的全连接层分支给出的;而单级网络中,类别 和 Anchor 的回归值(或 BBox 的宽高)一般直接由一个预测卷积层给出,类别和回归值按照一定次序排列在输出特征的特定通道中。且通常一个点上只有一个位置预测,而不像两级网络一样,一个点上多个类别有对应的多个位置预测。
Table of Contents
- Overview
- You Only Look Once: Unified, Real-Time Object Detection
- YOLO9000: Better, Faster, Stronger
- YOLOv3: An Incremental Improvement
- YOLOv4: Optimal Speed and Accuracy of Object Detection
Overview
以下速度数据均在 Titan X (Maxwell) 上测试,Tesla M40 基本是相同的 GPU。新一代构架的是 Titan X (Pascal)、Titan Xp、GTX 1080 Ti、Tesla P100 这些。Titan Volta (Titan V)、Tesla V100 是更加新一代。再就到目前的 Turing,Titan RTX 这些。
在 Pascal VOC 07 test 上,使用 07+12 训练
名称 | 速度(fps) | 精度(mAP) | 输入尺寸 | 网络结构 |
---|---|---|---|---|
YOLOv1 | 45 | 63.4% | 448 × 448 | Darknet-24 |
Fast YOLOv1 | 155 | 52.7% | 448 × 448 | Darknet-9 |
YOLOv2 | 40 | 78.6% | 544 × 544 | Darknet-19 |
YOLOv2 | 59 | 77.8% | 480 × 480 | Darknet-19 |
YOLOv2 | 67 | 76.8% | 416 × 416 | Darknet-19 |
YOLOv2 | 81 | 73.7% | 352 × 352 | Darknet-19 |
YOLOv2 | 91 | 69.0% | 288 × 288 | Darknet-19 |
在 Pascal VOC 12 test 上,使用 07++12(即含 07 test)训练
名称 | 速度(fps) | 精度(mAP) | 输入尺寸 | 网络结构 |
---|---|---|---|---|
YOLOv1 | 45 | 57.9% | 448 × 448 | Darknet-24 |
YOLOv2 | – | 73.4% | – | Darknet-19 |
在 MS COCO test-dev 上,使用 2017 split (trainval35k) 训练
名称 | 速度(fps) | 精度(mAP) | 精度(mAP 50) | 输入尺寸 | 网络结构 |
---|---|---|---|---|---|
YOLOv2 | – | 21.6% | 44.0% | – | Darknet-19 |
YOLOv3 | 19.6 | 33.0% | 57.9% | 608 × 608 | Darknet-53 |
YOLOv3 | 34.5 | 31.0% | 55.3% | 416 × 416 | Darknet-53 |
YOLOv3 | 45.5 | 28.2% | 51.5% | 320 × 320 | Darknet-53 |
YOLOv4 | 23 | 43.5% | 65.7% | 608 × 608 | CSPDarknet-53 |
YOLOv4 | 31 | 43.5% | 64.9% | 512 × 512 | CSPDarknet-53 |
YOLOv4 | 38 | 43.5% | 62.8% | 416 × 416 | CSPDarknet-53 |
You Only Look Once: Unified, Real-Time Object Detection
思想:缩放图片一次通过卷积神经网络同时得出位置和类别,这样速度快、中间步骤简单、基于一整张图所有信息而不是每个 Proposal 中部分信息进行检测。
Architecture
YOLO 的检测方法是将输入图划分成 S×S 个格子(Grid),每一个格子预测出 B 个框。如果一个物体的中心落在某一个格子内部,那么这个格子负责预测这个物体。一个格子首先要预测它负责预测的物体的类别概率,这是一个长度为 Class (C) 的数组。此外,对于一个格子内的每个框,都还要预测另外的 5 个值 x, y, w, h, Pr*IoU
,前两个值 x, y ∈ [0, 1]
表示框的中心点相对于这个格子的偏移,w, h
表示这个框在原图尺寸上的宽长(相对值,归一化到 [0, 1]
)。这样得到预测值之后,先应用偏移 x, y
找到框的中心点,再通过 w, h
即可作出一个框。最后一个值 confidence = Pr(Object)*IoU
表示框内有物体的概率乘以这个框和 GT 之间的 IoU,也就是说,如果这个框对应的是背景,那么这个值应该是 0
,如果这个框对应的是前景,那么这个值应该是与对应前景 GT 的 IoU。
从上面我们可以看出:
- YOLO 所需要的整个输出为一个
S × S × (B*5 + C)
的 tensor,且这里 C 是前景的类别数,无需加上背景一类(例如对于 Pascal VOC,C=20)。它无需两级检测网络的两个全连接分开输出类别和位置,也无需 Proposals 生成、特征重采样等过程。实验中,S=7,B=2。 - 每个格子预测的长度为 Class 的概率是一个条件概率,是在有物体下的概率,即
Pr(Class_i|Object)
,所以在预测的时候,把这个和每个框内预测的概率相乘Pr(Class_i|Object) * Pr(Object) * IoU = Pr(Class_i) * IoU
就得到对每个框的逐类别概率。这里与 R-CNN 等两级网络不同之处在于,两级网络中一般使用 C+1 类判断前背景,而 YOLO 使用框内一个额外概率值判断前背景。 - 得到的条件概率的意思是,以上图 class probability map 为例,每个格子取输出 tensor 对应的向量中的 class 分数的最大值对应的类别,就可以得到此图。最下方的红色是 C=20 类中的一个类别,假设代表「飞机」。但是它并不表示这个格子就是「飞机」,而是,如果这个格子内有物体,那么这个格子内的物体的类别是「飞机」。而有没有物体,需要看上方图的 confidence,经提醒,这个图内的 98 个框(位置和大小反映
x, y, w, h
)的粗细可能就代表这个 confidence 分数,只有 confidence 大的框,才认为里面有物体。
下面看得到这个输出 tensor 的网络结构,YOLO 系列用了一个自创的网络结构,叫做 darknet,灵感源于 GoogLeNet (Inception V1)。在 YOLOv1 中,它有 24 层卷积层(加上 4 个池化层和 2 个全连接层),结构图如下。
Darknet-24 (Unofficial name) Architecture
这里没有使用 Inception Module,但是使用了同样的减少计算量的方法,即先用 1 × 1 reduction layer,再使用 3 × 3 convolutional layer。可以简单计算一下,在 1024 × 14 × 14 层,如果直接使用 1024 × 1024 × 3 × 3 卷积,计算量为 (1024 × 14 × 14) × (1024 × 3 × 3) = 1849.7M
。而如果像图上结构一样先降维(可以理解为非线性映射到低维空间,可能联想到 PCA 虽然它是线性的)再卷积,计算量为 (512 × 14 × 14) × (1024 × 1 × 1) + (1024 × 14 × 14) × (512 × 3 × 3) = 102.7M + 924.8M = 1027.5M
,接近于小到一半。这种 bottleneck 结构在现代 backbone 上很常见。
对于激活层,最后一层使用的是线性激活函数,其它层使用的是 leaky ReLU,f(x) = 0.1x when x<0
。
Training and Inference
首先在 ImageNet 上预训练前 20 层卷积,把后面替换为一个平均池化层和一个全连接层,输入尺寸为 224 × 224。训练好后改为 4 个卷积层和 2 个全连接层,输入尺寸改为 448 × 448。
Loss 函数选择为 sum-squared error,SSE=∑i(xi−x^)2。这有几个不平衡的问题:
- 位置预测和类别预测是相等权重的;
- 对于不含任何物体的格子,即负样本总是多于正样本的,所以 confidence 分数(每个 BBox 的第五个预测参数)会趋向于
0
; - 大物体和小物体位置预测错误的权重是相等的,对于大物体,相同数量的位置偏移在 Loss 上的反映应当小于小物体的,因为对于 IoU 的影响会更小。
对于前两个问题,通过增加权重 λcoord=5, λnoobj=.5 来解决。第三个问题,通过预测 BBox 宽高的平方根来解决。
还有一个关于 GT 的问题是,一个格子负责预测中心点落在其内的物体,但一个格子预测了 B 个 BBox,我们只希望一个 BBox Predictor 负责一个物体。所以在训练时,只有预测出的框的与 GT 的 IoU 最大的那个 BBox 认为是有物体的(正样本)。所以这里与 R-CNN 系列两级网络不同,在那里一个 GT 是可以匹配到多个预测框的。作者这么设计意图是让每个 Predictor 专门化,专注于一种尺寸、长宽比或类别的物体。
整个损失函数如下:
λcoord∑i=0S2∑j=0BIijobj⋅([(xi−x^i)2+(yi−y^i)2]+[(wi−w^i)2+(hi−h^i)2])+∑i=0S2∑j=0BIijobj⋅(Ci−C^i)2+λnoobj∑i=0S2∑j=0BIijnoobj⋅(Ci−C^i)2+∑i=0S2Iiobj∑c∈classes(pi(c)−p^i(c))2
公式中第一行是 BBox 的位置和大小;第二行是 BBox 内的 Pr*IoU
;第三行是每个格子内的类别概率,可以看到只有格子内有物体时才有这项 loss,这与之前的条件概率是对应的。Icondition 表示如果 condition
,那么这个值为 1
,否则为 0
。
训练细节:
- epochs = 135,batch size = 64,momentum = 0.9,weight decay = 0.0005。
- lr:第一个 epoch 从 10e-3 增加到 10e-2,继续保持 75 个 epochs,然后 10e-3 训练 30 个 epochs,最终 10e-4 训练 30 个 epochs。
- 第一个全连接层后加了一个
.5
的 Dropout 层防止过拟合。数据增强:20% 尺度的随机 translation 和 scaling,在 HSV 空间中 1.5x 的曝光和饱和度调整。
对于测试,YOLO 设计为预测 98 个框,使用每个框内的第五个预测值决定是否留下这个框,类别使用格子预测的类别。对于一些大的物体,可能在多个格子内都给出接近的框,使用 NMS 可以增加 2% ~ 3% mAP。而对于 R-CNN 等基于区域分类的算法,NMS 是必不可少的。
Summary and Results
YOLO 的几个问题:
- 对小物体效果不好;
- YOLO 通过下采样后数据得出 BBox 的位置偏移和宽高,所以精度不高,同时对于一些罕见的长宽比或者尺寸的物体的效果不好;
- loss 只是近似反映检测效果的好坏,比如对于不同大小的物体,
x, y, w, h
的误差仍不能准确反映 IoU 的误差。YOLO 对于位置的预测较差,是降低 mAP 的主要原因。
数据集使用 Pascal VOC 07+12。如果在 12 测试,那么 07 的 test 也被用于训练。在 07 的测试结果为 63.4%
mAP,在 12 的测试结果为 57.9%
mAP。
YOLO9000: Better, Faster, Stronger
改进:除了一些提高精度的,YOLOv2 还引入了 multi-scale training,所以它可在不同输入尺寸上工作,提供速度精度的 tradeoff。此外,提出了一种联合训练,可以同时在 COCO 和 ImageNet 上训练,网络可以学习检测那些没有在检测数据集中标注的类别。
Architecture
首先看网络,作者将网络减少了几层,提高了速度,同时加入了 BN 层,提高了精度。
整个网络(左图)含有 19 个卷积层和 5 个最大值池化层,不再有全连接层,网络的 output stride 减小了一倍变为 32。倒数第二层是 Global Average Pooling,出自 Network in Network,GoogLeNet 中也使用了,方法是在每个特征图通道上进行平均池化。在每个卷积层之后都加了 BN 层,网络不再需要 Dropout 层。
对于检测(右图),网络输入尺寸也进行了改动,希望最终输出一个奇数尺寸,这样就会有一个中心点。所以 v2 中默认输入尺寸是 416 × 416,增减输入尺寸是以 64 为单位进行。一般一个大物体的中心会落在图像中心,所以这样可以用一个格子去预测它而不是四个格子。
左图这个网络是用于 ImageNet Classification 的,在预训练完后需要改成检测网络。方法是去掉最后 Convolutional、AvgPool、Softmax 三层,然后加上三层 1024 × 3 × 3 卷积,最后用一个 1 × 1 卷积进行预测,得到所需 A × (5 + C) = 125
通道(这里通道数与 YOLOv1 不同,见下文)。此外,这里还加入一个 passthrough layer,使得网络对于小物体的检测效果更好。注意这里论文里说的和实际上代码里做的有些不同:论文中是把最后一个 512 × 3 × 3 卷积的结果,尺寸为 26 × 26 × 512 feature map 转化为 13 × 13 × 2048,然后 concat(通道上的连接)到倒数第二个卷积(也就是最后一个 3 × 3 卷积)的结果上;实际代码中对尺寸为 26 × 26 × 512 feature map 后面加了一个 64 × 1 × 1 的卷积,降低了通道数,然后再 reorg 转化为 13 × 13 × 256,并 concat 到 13 × 13 × 1024 的特征图上,输出一个 13 × 13 × 1280 的特征图。
再看其它的改进:
Anchor Box
YOLO 在 BBox 位置预测上表现并不好,一方面是因为它直接给出宽高。相比 R-CNN 中有预设的 Anchors,网络只需要预测一个 offset,这相对容易。作者在 v2 中引入了 Anchors。
第二个改动是,之前每个格子只预测一次类别,这实际上是对 BBox 的一种限制,现在需要 decouple。所以对每个 Anchor 都预测一组类别,它们的意义没变。同时,每个格子上的 BBox/Anchor 数量不再是 2。
output tensor of YOLOv1 against YOLOv2
此外,R-CNN 系列的 Anchors 是人工指定的,而这里的 Anchors 是通过 k-means 算法得到的,距离指标为 d(box, centroid) = 1 − IoU(box, centroid)
,即以 IoU 来判断。下图是在 COCO 和 VOC 上聚类出的 Anchor 形状,以及使用不同距离指标或人工指定得到的平均 IoU。
Direct location prediction
这里先回顾一下 R-CNN 系列中的 regressor 是怎么工作的(注意在 YOLO 的论文中符号错了):
x=(tx∗wa)+xa , y=(ty∗ha)+yaw=wa⋅etw , h=ha⋅eth
其中带下标 a
的是 Anchor,t
表示网络预测的值。
对于位置这样引入了尺度不变性,比如 tx = 1
框的中心点就向右移动一个框宽度的距离。但是这对于框的位置没有限定,对于随机化的初始值,框可能出现在图中的任何位置,导致难以训练。所以位置还是沿用 v1 中的相对于格子的预测方式,宽高则采用相同的指数形式。
bx=σ(tx)+cx , by=σ(ty)+cybw=pwetw , bh=pheth
公式里 sigma(·)
是一个 logistic activation (sigmoid) 用于将值限定在 [0, 1]
,即把中心点的变动限制在当前格子里。cx, cy
是所在格点左上角到图像左上角的距离,例如上图中是 (1, 1)
(网格大小归一化了)。这里可以看出,这个位置是直接预测出的,它不依赖于设定的 Anchors。
Train YOLOv2
网络 | top-5 | top-1 | 输入尺寸 | floating point operations |
---|---|---|---|---|
VGG-16 | 90.0% | - | 224 × 224 | 30.69 billion |
Darknet-24 | 88.0% | - | 224 × 224 | 8.52 billion |
Darknet-19 | 91.2% | 72.9% | 224 × 224 | 5.58 billion |
- 在 ImageNet 上训练 160 个 epochs。lr = 0.1,polynomial rate decay with a power of 4,weight decay = 0.0005,momentum = 0.9。随机裁剪、旋转、颜色和曝光调整。
- High Resolution Classifier:ImageNet 训练是使用 224 × 224,这样在进行检测训练时,网络不仅要学习更大的 448 × 448 输入,还要同时学习检测任务。所以在 v2 中,会在 ImageNet 上使用 448 × 448 fine tune 10 个 epochs 再进行检测训练,lr = 10e-3。准确率达到 76.5%/93.3%。
- Multi-Scale Training:接下来进行检测训练。训练中每过 10 个 epochs,会在
{320, 352, ..., 608}
中随机选择一个输入尺寸继续训练。共 160 个 epochs,lr = 10e-3,在 10、60、90 epoch 时减半。weight decay、momentum 与上面相同。
Summary
上表总结了从 v1 到 v2 的各项改进,说明一下:表中的 anchor boxes 指的是人工指定的,固定尺寸和长宽比的 anchors,使用这种框,mAP 69.5 -> 69.2,recall 81% -> 88%,精度小幅下降召回明显提高,说明网络有较大提升空间,所以作者采取了下面的 k-means 聚类找出最佳初始尺寸的方法。对于这种聚类得到的框,作者叫它 dimension priors,可能应该翻译成「先验框」。但是我觉得它本质和 anchors 没什么差别,且对于网络的修改也沿用了,其实在 v3 中作者也管它叫 anchors 了,所以在上文没有区分。
Joint train on object detection and classification (YOLO9000)
基本思路是对于检测的数据传入,BP 整个网络,对于分类的数据传入,只 BP 有关分类的网络部分。一个问题是检测数据集如 COCO 提供的是一个很泛的类别,比如「狗」,共 80 类;而分类数据集如 ImageNet 提供的类别是很具体的,如「哈士奇」,共 21841 类。而 Softmax 意味着各类别之间是相互排斥的,而我们希望只在每个数据集内类别相互排斥,而数据集之间不是。
下面仍然先要在分类上预训练,然后再训练检测。
Classification
ImageNet 的标签来自于 WordNet,一个语言数据集,它有详细的层级,比如 canine -> dog -> hunting dog -> terrier -> Norfolk terrier,但是它是一个 Graph 而不是 Tree,比如 dog 可以属于 canine 也可以属于 domestic animal,即有多个父节点。好在大多数类别通向 root 只有一条路径,对于有多条路径的,选择最短的路径,舍弃其它的,这样就可以构造一个 Word Tree。
对于 ImageNet-1000,构建完整个图之后有 1369 个节点,增加了额外的 369 个节点。每一个节点预测一个条件概率,最终的概率需要将它们相乘,例如 Pr(Norfolk terrier) = Pr(Norfolk terrier|terrier) * Pr(terrier|hunting dog) ∗ ... ∗ Pr(mammal|animal) * Pr(animal|physical object) * Pr(physical object)
。对于分类,每张图都有物体,所以这里最后一项 Pr(physical object) = 1
。
Prediction on ImageNet vs WordTree
在 ImageNet 上使用这个图训练网络,预测的形式如上图右侧,在每层级下分别 Softmax。一张图片会顺着这个 tree(可参考下面的图)走到 root,获得路径上的所有标签,即一张图现在有多个标注。这样训练的结果为 71.9%/90.4%。新增节点后准确率下降不多,同时如果网络见到了一个没训练过的狗的品种,那么预测中「狗」的概率会很大,同时所有具体类别的概率又很小。
Detection
对于框的分类结果,检测中每个格子内不一定有物体, Pr(physical object)
根据 confidence/objectness 分数(BBox 的第五个预测值)确定。判断一个框的类别时,从 WordTree 根节点开始向下遍历,对每一个节点,在它的所有子节点中,选择概率最大的那个(一个节点下面的所有子节点是互斥的),一直向下遍历直到某个节点的子节点概率低于设定的阈值(意味着很难确定它的下一层对象到底是哪个),或达到叶子节点,那么该节点就是对应的对象。
Combining datasets using WordTree hierarchy
训练总共选取了 9000 类,含有 COCO、ImageNet 分类和检测数据集。为了构造 Tree 产生的父节点,构造的方法与之前相同,加起来共 9418 类。Oversampling COCO 使得数据量之比为 4:1。
网络结构和 v2 相同,先验框的尺寸改为 3 种。标注和反向传播与之前类似,(1)对于检测数据集图像,loss 与之前相同,只是这里对于 class,只反向传播标注的那个节点及其父节点上的 loss,不 BP 其子节点上的;(2)对于分类数据集图像,首先找到 GT 所属类别的预测值最高的那个框,只反向传播这个框上的 class 和 objectness 部分,四个坐标不反向传播。对于 class,与检测的相同,只看其和其父节点的,对于 objectness,原文是「We also assume that the predicted box overlaps what would be the ground truth label by at least .3 IOU and we backpropagate objectness loss based on this assumption.」,我觉得意思是说如果预测的 objectness = Pr(object) * IoU
小于 1 * 0.3
的话就有一个损失在上面,具体损失形式需要以后看一下代码了更新。
Results
作者在 ImageNet Detection 上测试,其中 44 类是与 COCO 相同的,156 类是 COCO 中没有只出现在 ImageNet Classification 的。结果是 19.7 mAP,在不重合的 156 类上有 16.0 mAP。具体来看不重合的类别部分,对于各种动物,COCO 中有一些动物的标注,对于新动物的类别的表现不错:red panda = 50.7, fox = 52.1, koala bear = 54.3, tiger = 61.0, armadillo = 61.7
;对于一些 COCO 中完全没有相关(类似)的类别的,表现很差:diaper = 0.0, horizontal bar = 0.0, rubber eraser = 0.0, sunglasses = 0.0, swimming trunks = 0.0
。
YOLOv3: An Incremental Improvement
YOLOv3 和 v4 都是 tech report,更多是把别人的工作在保证速度前提下整合进 YOLO 以提高精度。
每一代 YOLO 都对网络或是说 backbone 进行了改进,YOLOv3 更是主要集中在这个网络上。
Network
YOLOv3 同样是先有一个检测网络,在 ImageNet 上预训练,然后改为检测网络训练。下图(右侧是左侧红线部分)是 DarkNet-53,含有 52 个卷积和 1 个全连接。可以看到,与 DarkNet-19 相比,层数多了不少,主要的改变在于:
- 去掉了池化层,全部由一个步长为 2 的卷积层完成下采样。
- 最后的全连接层又回来了。
- 内部出现了类似于 ResNet 的残差连接。
backbone | top-1 | top-5 | 测试尺寸 | Ops | FPS | BFLOP/s |
---|---|---|---|---|---|---|
Darknet-19 | 74.1% | 91.8% | 256 × 256 | 7.29 B | 171 | 1246 |
Darknet-53 | 77.2% | 93.8% | 256 × 256 | 18.7 B | 78 | 1457 |
ResNet-101 | 77.1% | 93.7% | 256 × 256 | 19.7 B | 53 | 1039 |
ResNet-152 | 77.6% | 93.8% | 256 × 256 | 29.4 B | 37 | 1090 |
上述数据统一在 TitanX 下测试,最后一项 BFLOP/s 意味着 Darknet 对 GPU 的利用更好。
再看检测网络,在这里作者引入了类似于 FPN 的多级预测结构。这个在论文里讲得有点零散混乱且没有结构图,我根据代码做了一个下面的网络结构图。
解释几点:
- 每一个 Conv 都跟着一个 BN 和 leaky ReLU 激活层,最后每个 Prediction 是通过一个无 BN、linear 激活的 1 × 1 卷积层得到的,就是一般的预测层,在图中没有画出(也可认为绿色的 Prediction 就是这个卷积)。
- 每一个 Add 之后有一个 linear activation。
- 这里每个 Residual Unit 里面只有两层,与 ResNet 的不一样。上方蓝色的
N×
表示括号内的模块重复 N 次。 - Conv 上方的尺寸是指经过这一层后的尺寸,以输入
416 × 416
为例。都是 CHW 的格式。 - 黄色的层是改为检测网络之后新加入的,白色的是原有的 Darknet-53 Backbone,共 52 层(去掉了最后的全连接)。
再看最后输出的 255 个通道是怎么回事,255 = 3 × (80 + 5)
,首先这里是以 COCO 为基准了,不再使用 VOC 的,所以是 80;5 就是从 v1 一直延续来的;3 指的是三个 Anchors,在 v2 里是五个,而 v3 实际用了 9 个,平均分在三级预测上。在 COCO 上尺寸分别是 (10×13),(16×30),(33×23),(30×61),(62×45),(59× 119), (116 × 90), (156 × 198), (373 × 326)
。
Other Improvements
Bounding Box Prediction (objectness)
对于 objectness 分数,YOLOv3 采用了 logistic regression,所以如果一个 BBox 与 GT 的交叠大于任何其它的 BBox,那么它的 objectness 分数应该为 1
。训练使用 binary cross-entropy loss,不再是 SSE loss。
同时引入了类似 RPN 的匹配机制:如果一个框与 GT 的交叠大于一个阈值 0.5
但它又不是交叠最大的框,那么这个将作为非正非负的样本,在训练时被忽略。
同样,一个 GT 只会与一个 Anchor/BBox 匹配上,对于没有匹配上的负样本,loss 中将没有 coordinate 和 class predictions 部分,只有 objectness loss。
Class Prediction (classes)
作者去掉了之前使用的 Softmax 进行类别分类,因为发现对准确率没有帮助,且一个大型数据集如 Open Images 上面有一些交叠的类别,比如 Woman - Person。使用 independent logistic classifiers 预测,并设定一个阈值,高于这个阈值的类别将被赋给对应的框。训练使用 binary cross-entropy loss,不再是 SSE loss。
Results
YOLO v3 results on COCO test-dev
从上表可以看出,YOLOv3-608 在 COCO 上的结果以及到了和 ResNet-FasterRCNN 接近的水平,但是时间仅需 51ms,是后者的三倍多。同时,在 AP50 指标上 YOLO 表现得很好,说明很大一部分的问题来自于框的位置的不准确。
precision-speed compare on COCO test-dev
YOLOv4: Optimal Speed and Accuracy of Object Detection
YOLOv4 是一篇将其它人提出许多的方法整合进 YOLO 的文章,但有一个前提就是保证速度,所以有些方法做了一些改动。同时基于这个原则,作者希望能使用较亲民的设备进行训练和预测,所以所有涉及多 GPU 的方法比如 SyncBN 均不予考虑。相应的测试也选用单个 RTX 2080Ti/RTX 2070/GTX 1080Ti 这类游戏显卡(但是 2080Ti 这好像不是所有打游戏的都买得起的?)。不过这篇文章还挺好的,对检测的研究也进行了一个相应的划分总结,还是挺全面的像综述一样,值得看看原文,本文里只有 YOLOv4 用到了的方法的分析。
其实我感觉很难写,因为涉及太多其它的文章,不知道简单几句能不能给一篇文章讲清楚。此外有些还是今年的,很新,我也没看过。。。
总的来说,作者将其它人的工作划分为 Bag of freebies (BoF) 和 Bag of specials (BoS)。前者指在训练时候的一些方法,不影响预测时间和模型复杂度;而后者指的是整个构架的改动,对预测(时间)会有影响。我花了点时间给整理了一下,下面两个表是用到的所有方法和对应论文,没有对应论文的就是作者在 YOLOv4 中应用的一些简单 BoF,可以看到,这篇文章各种 tricks 真的巨多,我相信给其它算法这么一顿军训效果也能好不少的。不过别人已经测试好了,直接能用,也很实用对吧。
Backbone BoF | arXiv | Detector BoF | arXiv |
---|---|---|---|
CutMix | ICCV 2019 1905.04899 | CIoU-loss | AAAI 2020 1911.08287 |
DropBlock regularization | NIPS 2018 1810.12890 | DropBlock regularization | 1810.12890 |
Class label smoothing | CVPR 2016 1512.00567 | Cross mini-Batch Normalization (CmBN) | 2002.05712 |
Cosine annealing scheduler | 1608.03983 |
Others:
- BoF: Mosaic data augmentation.
- Detector BoF: Eliminate grid sensitivity, Optimal hyper-parameters, Random training shapes, Self-Adversarial Training, Multiple anchors for a single ground truth.
Backbone BoS | arXiv | Detector BoS | arXiv |
---|---|---|---|
Mish activation | 1908.08681 | Mish activation | 1908.08681 |
Cross-stage partial connections (CSP) | 1911.11929 | SPP-block | TPAMI 2015 1406.4729 |
Multi-input weighted residual connections (MiWRC) | CVPR 2020 1911.09070 | Path-aggregation block (PAN) | CVPR 2018 1803.01534 |
SAM-block | ECCV 2018 1807.06521 | ||
DIoU-NMS | AAAI 2020 1911.08287 |
仍需要一点时间施工,不过我猜要拖到五月底了。
已经到五月底了,然而事情很多,考虑到眼下两个月之内应该不会有机会看论文,所以我愉快地宣布下面的内容鸽子了 🐦。
Bag of freebies
最常用的 bag of freebies 就是数据增强(data augmentation)了,YOLOv4 用了下面这些。
CutMix
CutMix 是一种 regional dropout strategy,这类方法通过去除一些 informative pixels 来使得网络学习图像中 less discriminative 部分的信息。
关于训练时的标签和损失函数,YOLOv4 中使用了下面这些。
Class label smoothing
使得 class 标签不绝对,提升分类器效果。
CIoU Loss
直接以 IoU 作为 regression 的损失函数,提高了回归精度。从 IoU -> GIoU -> DIoU -> CIoU 的变化过程,见 另一篇关于 regressor 的文中 IoU Loss 的部分。
Bag of specials
Multi-input weighted residual connections (MiWRC)、Path-aggregation block (PAN)
前者为带权重的特征融合方式,后者为 neck 上的新的特征融合路径。见 另一篇关于 EfficientDet 文中 BiFPN 的部分。
DIoU-NMS
在 NMS 时考虑两个 box 中心点之间的距离以稍微降低其 IoU 值的方法,见 另一篇关于 regressor 的文中 DIoU 的部分。