目标检测-YOLOv3
传统的目标检测算法适用的场景有限,而且维护成本很大。深度学习方法应用于目标检测,不仅算法适应性好,还可以进行迁移学习,降低成本。
1. 基础概念
深度学习目标检测算法中,基于锚框(Anchor)的方法主要分为一阶段方法和两阶段方法。
两阶段方法先对感兴趣的区域进行选择,然后进一步对候选框内做分类和回归,最终输出选择的框以及对应的分类。两阶段的模型有R-CNN系列,比如R-CNN,Fast-RCNN,Faster-RCNN等。两阶段模型的优点是精度高,但是速度及较慢。
一阶段方法直接对anchor进行回归和分类,得到最终目标框和类别,算法有YOLOv2,v3,SSD,RetinaNet等。一阶段模型的推理速度较快,但是相对的精度会下降一些。
此外还有一些anchor-free的方法,包括基于关键点的检测算法以及基于中心检测算法等。
下面是一些基础概念和缩写:
BBox:Bounding Box 边界框
Anchor:锚框
RoI: Region of Interest 特定的感兴趣区域
Region Proposal: 候选区域
RPN: Region proposal network 提取候选区域的网络
IoU: Intersaction over Union (Area of Overlap/ Area of Union) 交并比,预测框的质量
mAP:mean average precision
NMS:non-maximum suppression 非极大值抑制
2. YOLO
YOLO系列的模型在保有一定精度的基础上拥有很快的推理速度,在下面图中YOLOv3的推理速度远超其他模型,因此在实时监测领域中有很好的应用。
推理速度比较
2.1 YOLOv1
YOLO的名字来源于you only look once,从名字上就道出了YOLO的精髓。
YOLOv1将图像划分为S*S个网络,物体真实框的中心落在哪个网格上,哪个网格对应的锚框就负责检测物体。
每个网格会预测一个边界框以及对应的置信度,这里的置信度反映的是模型认为这个框里包含着物体的把握以及它预测到这个物体的精确程度。所以置信度就等于。如果物体不存在,那么置信度应该等于零。
每个边界框会预测5个值。(x,y)坐标表示框相对于网格单元边界的中心。 w,y是相对于整个图像预测宽度和高度。 最后,置信度预测表示预测框与任何真实框之间的IOU。
模型的检测网络如下图,包括24个卷积层和2个全连接层,最终输出的应该是一个,在图里是。
在全连接层输出预测中,边界框的宽度和高度进行了归一化,落在0和1之间。边界框的x和y坐标参数化为特定网格单元位置的偏移量,因此它们也被限制在0和1之间 。
最终层使用线性激活函数,所有其他层均使用了leaky ReLU。
YOLOv1对于输出的平方和误差进行了优化,原因是平方和比较好优化。
YOLOv1模型结构
在训练过程中,网格上的每个格子只会输出一个预测框,在这里选取与真实框IoU最大的那个框,一个预测框只会预测一个类别。
因此这也限制了YOLO能预测的物体的数量。对于尺寸小数量多的物体,预测效果也不是很好。
2.2 YOLOv2,v3
YOLOv2在v1的基础上进行了优化,骨干网络使用了DarkNet19,并且将输入图片给尺寸从224增大到448,并且将网络结构设为全卷积网络结构加上Batch Norm,使用了Kmeans聚类方法来计算anchor,引入了多尺度训练,使网络在训练过程中学习不同尺度的图像。不过待改进的地方有在小目标上召回率不高,靠近的群体目标检测效果不好,检测精度还有优化空间。
YOLOv3使用了更加深的骨干网络DarkNet53,同时加入了多尺度预测,在COCO数据集上聚类; 9中不同尺度的anchor,在分类上使用sigmoid激活函数,支持了目标的多分类。YOLOv3的优点是推理速度快,性价比高,通用性强;缺点是召回率较低,定位精度较差,对于靠近或者遮挡的群体、小物体的检测能力相对较弱。
YOLOv3在v1的基础上做了很多改动。
边界框预测
YOLOv3使用聚类预测到的边界框作为锚框。网络为边界框预测4个坐标值,如果单元格从图像的左上角偏移了,并且先验边界框的宽度和高度为,则预测如下图:
将上图公式里的反一下,就能通过真实框的坐标得到监督信息。
YOLOv3给每个边界框用逻辑回归预测一个objectness score,如果某个边界框和真实框重合度比其他都高,那么它的objectness score应该是1。而其他框虽然也与真实框有重叠,会被忽略掉。
类别预测
使用的是sigmoid函数,没有用softmax因为没必要。
不同尺度的预测
YOLOv3使用k-means聚类来确定bounding box priors,选择了9个clusters和3个scales,然后在整个scales上均匀分割clusters。在COCO数据集上,9个cluster分别为(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90) ,(156×198),(373×326)。
特征提取
YOLOv3使用了Darknet-53,特点是加入了残差,比之前的网络更深了(有53层卷积层所以叫Darknet-53)。
借一张图看一下YOLOv3的整个流程:
输入图像,通过DarkNet53进行特征提取,网络会经过5个阶段,每个阶段经行一个倍数为2的下采样,也就是说5次的下采样是2^5=32倍的下采样。这个32倍的下采样通过特征提取后得到一个输出网格,同时也会经过一个上采样之后,与16倍的下采样之后的特征图进行堆叠,然后进一步进行特征提取得到第二个网格。32倍与16倍下采样堆叠得到的特征图,再一次通过上采样,与8倍下采样的结果进行堆叠,得到了第三个网格。
每个输出分支上对应着三个尺寸的先验框(总共33=9种尺度)。经过32倍下采样的网格,每一个网格对应着输入图像上3232的区域,适合检测尺寸较大的目标,而8倍下采样的网格适合检测尺寸小的目标。
输出特征的高度H和宽度W,相当于将图像划分为H*W个网格,而不是直接在图像上画网格。也就是说32倍下采样之后得到的,相当于在输入图像上划一个的网格,每一个网格对应着输出特征图上的一个点。
特征图的C通道上表示预测框的信息,包括坐标信息,目标置信度,分类。
C=B*(1+4+class_num),B为特征图上分配的锚框个数。
损失函数有三个,分类损失,定位损失和objectness损失。分类使用sigmoid激活函数,loss是sigmoid cross entropy。定位损失在x,y上使用sigmoid函数和sigmoid cross entropy损失,在w,h上使用L1损失。objectness损失用的是sigmoid激活函数和sigmoid cross entropy损失。
对于与真实框重叠的框,三种损失都要计算
对于没有真实框重叠的框,只计算objectness(0);对于与真实框重叠但不是最匹配的框,忽略它们。
参考资料:
[1]YOLOv1 paper:You Only Look Once: Unified, Real-Time Object Detection
[2]Yolo三部曲解读——Yolov1
[3]YOLOv3论文解析: An Incremental Improvement
[4]yolo v3 的keras 版本(转载)
[5]YOLOv3 paper:YOLOv3: An Incremental Improvement