三、巅峰之作:YOLOv3
3.1 简介
2018年,作者 Redmon 又在 YOLOv2 的基础上做了一些改进。特征提取部分采用darknet-53网络结构代替原来的darknet-19,利用特征金字塔网络结构实现了多尺度检测,分类方法使用逻辑回归代替了softmax,在兼顾实时性的同时保证了目标检测的准确性。
从YOLOv1到YOLOv3,每一代性能的提升都与backbone(骨干网络)的改进密切相关。在YOLOv3中,作者不仅提供了darknet-53,还提供了轻量级的tiny-darknet。如果你想检测精度与速度兼具,可以选择darknet-53作为backbone;如果你希望达到更快的检测速度,精度方面可以妥协,那么tiny-darknet是你很好的选择。总之,YOLOv3的灵活性使得它在实际工程中得到很多人的青睐!
3.2 网络结构
相比于 YOLOv2 的 骨干网络,YOLOv3 进行了较大的改进。借助残差网络的思想,YOLOv3 将原来的 darknet-19 改进为darknet-53。论文中给出的整体结构如下:
?
Darknet-53主要由1×1和3×3的卷积层组成,每个卷积层之后包含一个批量归一化层和一个Leaky ReLU,加入这两个部分的目的是为了防止过拟合。卷积层、批量归一化层以及Leaky ReLU共同组成Darknet-53中的基本卷积单元DBL。因为在Darknet-53中共包含53个这样的DBL,所以称其为Darknet-53。?
为了更加清晰地了解darknet-53的网络结构,可以看下面这张图:
为了更好的理解此图,下面我将主要单元进行说明:
- DBL: 一个卷积层、一个批量归一化层和一个Leaky ReLU组成的基本卷积单元。
- res unit: 输入通过两个DBL后,再与原输入进行add;这是一种常规的残差单元。残差单元的目的是为了让网络可以提取到更深层的特征,同时避免出现梯度消失或爆炸。
- resn: 其中的n表示n个res unit;所以 resn = Zero Padding + DBL + n × res unit 。
- concat: 将darknet-53的中间层和后面的某一层的上采样进行张量拼接,达到多尺度特征融合的目的。这与残差层的add操作是不一样的,拼接会扩充张量的维度,而add直接相加不会导致张量维度的改变。
- Y1、Y2、Y3: 分别表示YOLOv3三种尺度的输出。
与darknet-19对比可知,darknet-53主要做了如下改进:
- 没有采用最大池化层,转而采用步长为2的卷积层进行下采样。
- 为了防止过拟合,在每个卷积层之后加入了一个BN层和一个Leaky ReLU。
- 引入了残差网络的思想,目的是为了让网络可以提取到更深层的特征,同时避免出现梯度消失或爆炸。
- 将网络的中间层和后面某一层的上采样进行张量拼接,达到多尺度特征融合的目的。
网络结构解析:
- Yolov3中,只有卷积层,通过调节卷积步长控制输出特征图的尺寸。所以对于输入图片尺寸没有特别限制。流程图中,输入图片以256*256作为样例。
- Yolov3借鉴了金字塔特征图思想,小尺寸特征图用于检测大尺寸物体,而大尺寸特征图检测小尺寸物体。特征图的输出维度为??,??为输出特征图格点数,一共3个Anchor框,每个框有4维预测框数值()??,1维预测框置信度,80维物体类别数。所以第一层特征图的输出维度为 8 X 8 X 255??。
- Yolov3总共输出3个特征图,第一个特征图下采样32倍,第二个特征图下采样16倍,第三个下采样8倍。输入图像经过Darknet-53(无全连接层),再经过Yoloblock生成的特征图被当作两用,第一用为经过3*3卷积层、1*1卷积之后生成特征图一,第二用为经过1*1卷积层加上采样层,与Darnet-53网络的中间层输出结果进行拼接,产生特征图二。同样的循环之后产生特征图三。
- concat操作与加和操作的区别:加和操作来源于ResNet思想,将输入的特征图,与输出特征图对应维度进行相加,即??;而concat操作源于DenseNet网络的设计思路,将特征图按照通道维度直接进行拼接,例如8*8*16的特征图与8*8*16的特征图拼接后生成8*8*32的特征图。
- 上采样层(upsample):作用是将小尺寸特征图通过插值等方法,生成大尺寸图像。例如使用最近邻插值算法,将8*8的图像变换为16*16。上采样层不改变特征图的通道数。
Yolo的整个网络,吸取了Resnet、Densenet、FPN的精髓,可以说是融合了目标检测当前业界最有效的全部技巧。
3.3 改进之处
YOLOv3最大的改进之处还在于网络结构的改进,由于上面已经讲过。因此下面主要对其它改进方面进行介绍:
(1)多尺度预测 为了能够预测多尺度的目标,YOLOv3 选择了三种不同shape的Anchors,同时每种Anchors具有三种不同的尺度,一共9种不同大小的Anchors。在COCO数据集上选择的9种Anchors的尺寸如下图红色框所示:
借鉴特征金字塔网的思想,YOLOv3设计了3种不同尺度的网络输出Y1、Y2、Y3,目的是预测不同尺度的目标。由于在每一个尺度网格都负责预测3个边界框,且COCO数据集有80个类。所以网络输出的张量应该是:N ×N ×[3?(4 + 1 + 80)]。由下采样次数不同,得到的N不同,最终Y1、Y2、Y3的shape分别为:[13, 13, 255]、[26, 26, 255]、[52, 52, 255]。可见参见原文:
(2)损失函数 对于神经网络来说,损失函数的设计也非常重要。但是YOLOv3这篇文中并没有直接给出损失函数的表达式。下面通过对源码的分析,给出YOLOv3的损失函数表达式:
对比YOLOv1中的损失函数很容易知道:位置损失部分并没有改变,仍然采用的是sum-square error的损失计算方法。但是置信度损失和类别预测均由原来的sum-square error改为了交叉熵的损失计算方法。对于类别以及置信度的预测,使用交叉熵的效果应该更好!
(3)多标签分类 YOLOv3在类别预测方面将YOLOv2的单标签分类改进为多标签分类,在网络结构中将YOLOv2中用于分类的softmax层修改为逻辑分类器。在YOLOv2中,算法认定一个目标只从属于一个类别,根据网络输出类别的得分最大值,将其归为某一类。然而在一些复杂的场景中,单一目标可能从属于多个类别。
比如在一个交通场景中,某目标的种类既属于汽车也属于卡车,如果用softmax进行分类,softmax会假设这个目标只属于一个类别,这个目标只会被认定为汽车或卡车,这种分类方法就称为单标签分类。如果网络输出认定这个目标既是汽车也是卡车,这就被称为多标签分类。
为实现多标签分类就需要用逻辑分类器来对每个类别都进行二分类。逻辑分类器主要用到了sigmoid函数,它可以把输出约束在0到1,如果某一特征图的输出经过该函数处理后的值大于设定阈值,那么就认定该目标框所对应的目标属于该类。
3.4 性能表现
如下图所示,是各种先进的目标检测算法在COCO数据集上测试结果。很明显,在满足检测精度差不都的情况下,YOLOv3具有更快的推理速度!
如下表所示,对不同的单阶段和两阶段网络进行了测试。通过对比发现,YOLOv3达到了与当前先进检测器的同样的水平。检测精度最高的是单阶段网络RetinaNet,但是YOLOv3的推理速度比RetinaNet快得多。
4. 解释输出
???? 输入是(m,416,416,3)。输出是带有识别类的边界框列表,每个边界框由六个参数表示。如果c表示80个类别,那么每个边界框由85个数字表示。 ???? 在YOLO中,预测过程使用一个1X1卷积,所以输入是一个特征图。由于使用卷积1X1,因此预测图正好是特征图大小(1X1卷积只是用于改变通道数)。在YOLOv3中,此预测图是每个cell预测固定数量的边界框。 ? ? ?如网络结构图所示,预测图的深度为75,假设预测图深度为B*(5+C),B表示每个cell可以预测的边界框数量。这些B个边界框可以指定检测到一个物体。每个边界框有5+C个特征,分别描述中心点坐标和宽高(四个)和物体分数(一个)以及C个类置信度。YOLOv3每个cell预测三个边界框。 ???? 如果对象的中心(GT框中心)落在该cell感受野范围内,我们希望预测图的每个单元格都能通过其中一个边界框预测对象。其中只有一个边界框负责检测物体,首先我们需要确定此边界框属于哪个cell。 ???? 为了实现上面的想法,我们将原始图像分割为最后预测图维度大小的网格。如下图所示,输入图像维度为416*416,步幅为32(最后的预测图降采样32倍),最后预测图维度为13 * 13,所以我们将原始图像划分为13X13的网格。
Figure 3. 图像分割为网格示意图
???? cell(输入图像中)包含了目标物体GT边界框中心被选择为对预测物体进行负责。如上图所示,红色的框包含了狗的边界框(黄色框)的中心,因此红色cell对预测狗进行负责。 ???? 如上图,红色框在第7行第7列的网格,预测特征图是中间的粉黄色长方体,其中的第7行第7列红色的对原图红色方格负责。也就是预测特征图中每个对相对应的原图中的cell负责。 ???? 每个cell可以预测三个边界框(这些边界框都是通过K-means方法聚类得到的长宽,不一定能完整包含物体,后期还会调整边界框范围),那么哪一个边界框会对物体负责呢(被赋为狗的GT标签)?简单介绍下,这里是每个cell预测的边界框数,这里;5是4+1,4个数字表示边界框,1个是边界框类是否有物体的得分;表示需要预测的物体的数目。 ???? 下面我们使用另一个例子详细描述(注意这里是YOLOv2例子,每个cell给出五个边界框)。 ???? 现在我们使用五个边界框。YOLO框架如下:image Deep CNN Encoding 。19是608/32。
Figure 4. Encoding详细情况
???? 上图是YOLOv2的结果,输出预测特征图,每个cell有五个边界框进行预测,85分别表示是否为物体的分数(1个数字),边界框的表示(4个数字)和类概率(80个类)。如果物体的中心落在某个cell中,那么这个cell对预测物体负责(即使用相对应的预测图中的)。为了简便,我们将的最后两个进行铺平得到。如下图所示:
Figure 5. 预测特征图简便表示
???? 现在,对于每个cell的每个锚框我们计算下面的元素级乘法并且得到锚框包含一个物体类的概率,如下图:
Figure 6. 每个锚框物体类概率计算
???? 下面是YOLO在一张图像上的预测视觉化体现:对于每个表格cell,找到最大的概率分数(在5个锚框和不同类别中获取最大值);每个颜色表示表格cell中认为最可能的类。
Figure 7. 每个表格表示的最可能的类
???? 上面的图仅仅是直观上的表现,不是YOLO算法的重点。另一个方法是画出预测的边界框:
Figure 8. 预测的边界框
???? 上面绘制的框的数量还是太多了,为了减少预测框的数量,我们使用NMS(非极大值抑制)去除多余的边界框。
4. 锚框和预测
???? 直接预测框的宽高会导致训练时不稳定的梯度问题,因此,现在的很多目标检测方法使用log空间转换或者简单的偏移(offset)到称为锚框的预定义默认边界框。然后将这些变换应用到锚框以获得预测,YOLOv3具有三个锚框,可以预测每个单元格三个边界框。 ???? 锚框是边界框的先验,是使用k均值聚类在COCO数据集上计算的。我们将预测框的宽度和高度,以表示距聚类质心的偏移量。 ???? 以下公式描述了如何转换网络输出以获得边界框预测:
这里分别是我们预测的中心坐标、宽度和高度。是网络的输出。是网格从顶左部的坐标。是锚框的维度(见下图)。
中心坐标????
通过sigmoid函数进行中心坐标预测,强制将值限制在0和1之间。YOLO不是预测边界框中心的绝对坐标,它预测的是偏移量:相对于预测对象的网格单元的左上角;通过特征图cell归一化维度。 ???? 例如,考虑上面狗的图像。如果预测中心坐标是(0.4,0.7),意味着中心在(因为红色框左上角坐标是(6,6))。但是如果预测的坐标大于1,例如(1.2,0.7),意味着中心在(7.2,6.7),现在中心在红色框右边,但是我们只能使用红色框对对象预测负责,所以我们添加一个sidmoid函数强制限制在0和1之间。
5. 边界框维度
???? 通过对输出应用对数空间转换,然后与锚框相乘,可以预测边界框的尺寸(如上面的计算公式)。
Figure 9. 预测边界框尺寸
这里预测通过图像高度和宽度标准化。因此,如果对于包含狗的边界框的预测为,则特征图上实际宽度和高度为。
6. 物体分数和类置信度
???? 物体分数表示一个边界框包含一个物体的概率,对于红色框和其周围的框几乎都为1,但边角的框可能几乎都为0。物体分数也通过一个sigmoid函数,表示概率值。 ???? 类置信度表示检测到的物体属于一个具体类的概率值,以前的YOLO版本使用softmax将类分数转化为类概率。在YOLOv3中作者决定使用sigmoid函数取代,原因是softmax假设类之间都是互斥的,例如属于“Person”就不能表示属于“Woman”,然而很多情况是这个物体既是“Person”也是“Woman”。
7. 不同尺度的预测
???? 为了识别更多的物体,尤其小物体,YOLOv3使用三个不同尺度进行预测(不仅仅只使用(13*13))。三个不同尺度步幅分别是32、16和8。这意味着,输入图像416*416,检测尺度分别为13*13、26*26和52*52(如下图或者更详细如图2所示)。 ???? YOLOv3为每种下采样尺度设定3个先验框,总共聚类9个不同尺寸先验框。在COCO数据集上9个先验框分别是:(10*13),(16*30),(33*23),(30*61),(62*45),(59*119),(116*90),(156*198),(373*326)。
下表是9个先验框分配情况:
Table 1. 先验框分配情况
Figure 10. 不同尺度预测
???? 网络降采样输入图像一直到第一个检测层(),步幅是32;然后,将此层上采样2倍与上面的同样大小的特征图进行按通道堆叠,第二个检测层按步幅16形成;同样地,相同的上采样过程,最后的检测层步幅为8(详见图2网络步骤)。在每个尺度上,每个cell使用三个锚框预测三个边界框,共9个锚框。所有锚框加起来一共个。
Figure 11. 不同尺度预测框
8. 输出处理(在类分数上通过一个阈值过滤)
???? 我们的网络生成10647个锚框,而图像中只有一个狗,怎么将10647个框减少为1个呢?首先,我们通过物体分数过滤一些锚框,例如低于阈值(假设0.5)的锚框直接舍去;然后,使用NMS(非极大值抑制)解决多个锚框检测一个物体的问题(例如红色框的3个锚框检测一个框或者连续的cell检测相同的物体,产生冗余),NMS用于去除多个检测框。 ???? 具体使用以下步骤:抛弃分数低的框(意味着框对于检测一个类信心不大);当多个框重合度高且都检测同一个物体时只选择一个框(NMS)。 ???? 为了更方便理解,我们选用上面的汽车图像。首先,我们使用阈值进行过滤一部分锚框。模型有19*19*5*85个数,每个盒子由85个数字描述。将(19,19,5,85)分割为下面的形状:box_confidence:(19*19,5,1)表示19*19个cell,每个cell5个框,每个框有物体的置信度概率;
boxes:(19*19,5,4)表示每个cell5个框,每个框的表示;
box_class_probs(19*19,5,80):表示每个cell5个框,每个框80个类检测概率。 ???? 即使通过类分数阈值过滤一部分锚框,还剩下很多重合的框。第二个过程叫NMS,里面有个IoU,如下图所示。
Figure 12. IoU
???? 实现非极大值抑制,关键在于:选择一个最高分数的框;计算它和其他框的重合度,去除重合度超过IoU阈值的框;回到步骤1迭代直到没有比当前所选框低的框。
Figure 13. 使用NMS前后对比
|