YOLO (You Only Look Once)
dl cnn object detection
一、YOLO
YOLO是一个实时的目标检测系统。最新的V2版本在Titan X 上可以每秒处理 40-90 张图片,在VOC 2007上可以取得78.6%的准确率,在COCO上可以取得48.1%准确率。
之间的检测系统对图像在不同的尺度、位置上进行多次检测,需要执行多次神经网络算法分别得到结果,YOLO只需要执行一次,所以速度上得到了较大的提升。
二、算法
算法发展过程:
RCNN --> SPPNet --> Fast RCNN --> Faster RCNN --> YOLO --> SSD --> YOLO V2
各算法比较:
Comparision
Comparision coordinate
YOLO V2版本在速度、准确率上都有较好的表现。
1. RCNN
是第一个使用RegionProposal+CNN这一框架。先利用Selective Search在一张图片上框出上千个可能是目标的区域,分别放到神经网络里生成特征,也就是一张图片需要检测上千次,比较耗时。
生成的特征用来训练一个分类器,判断是否是目标。
对所有是目标的特征再训练一个回归器,用来微调目标的位置。
RCNN在VOC2007上的mAP是58%左右。
RCNN framework
2. SPPNet
Contributtions:
- 金字塔池化
- 复用Feature Map
传统卷积网络要保证输入图片的大小相等,这是因为想要通过CNN生成一个固定维度的特征送给分类器。作者在最后生成特征(全连接层)之前,加入了一个金字塔池化层,这样保证最后输出的特征维度固定(16 + 4 + 1) * 256,也就不需要前面对图片进行裁剪、缩放生成固定大小的图片。
卷积网络输入
金字塔池化层
SPPNet只进行一次卷积操作,之后再取的特征是根据proposal region在特征图上提取,节省时间。
3. Fast RCNN
由于RCNN有重复计算问题,作者(R.B.G)根据SPPNet改进了RCNN,称为Fast RCNN。
Fast RCNN
Contribution:
Fast RCNN也和SPPNet一样,将Proposal region 映射到最后一层的feature map上,提高速度。
把bbox regression放进了神经网络内部,与region分类和并成为了一个multi-task模型,实际实验也证明,这两个任务能够共享卷积特征,并相互促进
Fast RCNN framework
在VOC2007上的mAP提高到了68%。
4. Faster RCNN
Faster RCNN也是Proposal Region + CNN模式,只是将前面的Proposal的提取由Selective Search改为使用卷积网络(RPN)来生成。
本篇论文着重解决了这个系统中的三个问题:
- 如何设计区域生成网络
- 如何训练区域生成网络
- 如何让区域生成网络和fast RCNN网络共享特征提取网络
用VGG net作为feature extractor时在VOC2007上mAP能到73%。
Faster RCNN
RPN:
• 在feature map上滑动窗口
• 建一个神经网络用于物体分类+框位置的回归
• 滑动窗口的位置提供了物体的大体位置信息
• 框的回归提供了框更精确的位置
RPN
5. YOLO
由于RCNN架构都是对局部区域进行分类,YOLO采用回归模型,只进行一次网络传播,便可以得到整幅图像的目标,速度快了许多。
YOLO
作者将图片划分成SxS(7x7)大小的网格(grid),每个网格预测B(2)个box,每个box包含x, y, w, h 以及其置信度, 另外每个网络还要预测属于类别(C = 20)的概率,所以最后生成的维度的是S x S x (B x 5 + C) = 7 x 7 x (2 x 5 + 20) = 1470维,需要预测7 x 7 x 2 = 98个box。
生成向量
只有当目标中心落入当前网格中,当前网格才为这个目标负责。这个网络中,IOU最大的box为这个目标负责,即
为1, 否则
为0,
为1。作者设计的loss总共有如下几个部分组成:
- x,y,w,h的损失
- 包含object目标的confidence损失
- 不包含object目标的confidence损失
- 类别预测损失
YOLO loss
loss映射到30维向量的关系如下图:
YOLO loss
因为没有object的框比较多,含有目标的框比较少,为了平衡两者的loss贡献,将没有目标系数
设为0.5, 包含目标系数
设为5。
检测阶段:
生成了7x7个grid cell,7x7x2=98个box,对于dog类,把所有box按照confidence(置信度)降序排序,先取第一个,然后依次判断后面的box与第前面记录box的IOU,超过一定阈值就舍掉(NMS:非极大值抑制),最后保留的就是所有dog的框。同理,处理其它类别,如人、自行车,得到整幅图像中的框。
Limitations:
一,YOLO的每一个网格只预测两个boxes,一种类别。这导致模型对相邻目标预测准确率下降。因此,YOLO对成队列的目标(如 一群鸟)识别准确率较低。
二,YOLO是从数据中学习预测bounding boxes,因此,对新的或者不常见角度的目标无法识别。
三,YOLO的loss函数对small bounding boxes和large bounding boxes的error平等对待,影响了模型识别准确率。因为对于小的bounding boxes,small error影响更大。
Tiny YOLO 与 YOLO比较:
YOLO每秒45帧, 基于extracting network, 这个网络是基于GoogleNet,网络在ImageNet上性能:
Top-1 Accuracy: 72.5%
Top-5 Accuracy: 90.8%
Forward Timing: 6.4 ms/img
CPU Forward Timing: 0.95 s/img
weight file (90 MB)
Tiny YOLO每秒155帧, 基于Darknet reference network, 在CPU上比AlexNet快2倍,这个网络在ImageNet上性能:
Top-1 Accuracy: 61.1%
Top-5 Accuracy: 83.0%
Forward Timing: 1.5 ms/img
CPU Forward Timing: 0.16 s/img
weight file (28 MB)
6. SSD
Contributions:
- 提出了SSD目标检测方法,在速度上,比之前最快的YOLO还要快,在检测精度上,可以和Faster RCNN相媲美
- SSD的核心是在特征图上采用卷积核来预测一系列default bounding boxes的类别分数、偏移量
- 为了提高检测准确率,在不同尺度的特征图上进行预测,此外,还得到具有不同aspect ratio的结果
- 这些改进设计,实现了end-to-end训练,并且,即使图像的分辨率比较低,也能保证检测的精度
- 在不同的数据集,如:PASCAL VOC、MS COCO、ILSVRC,对该方法的检测速度、检测精度进行了测试,并且与其他的方法进行了对比。
SSD结合了Anchor Box和Multi-scale Feature,结构上看起来比YOLO还复杂,但速度为什么比YOLO快呢?因为SSD的输入是300,而YOLO输入是448x448,另外SSD网络使用的是VGG,并去掉了全连接层,而YOLO使用的是24层卷积网络,参数更多。
YOLO的box个数只有98个,而SSD在不同的尺度上生成了8732个box,所以SSD的效果要比YOLO更好。
38x38x4 = 5776
19x19x6 = 2166
10x10x6 = 600
5x5x6 = 150
3x3x4 = 36
1x1x6 = 6
5776 + 2166 + 600 + 150 + 36 + 6 = 8734
SSD vs YOLO
SSD对于不同尺度的feature map进行卷积,假设每个feature map(m x n)点产生k(6)个box。每个box需要包含位置偏移(x, y, w, h)和属于每类(C)概率的信息,所以对于每个点生成的张量维度为kx(C+4),需要的卷积滤波器大小为3 x 3 x (k x (C+4)),feature map生成的张量大小为mxnx(k x (C+4)), 整个网络输出大小为
,也就是8732x(C+4)大小的张量。然后在这些8732个box中,利用NMS选择最优的box。
default box
本文将 default box 与任何的 groundtruth box 配对,只要两者之间的IOU 大于一个阈值,这里本文的阈值为 0.5。
表示default box i 与ground truth j 之间在p类别上匹配为1, 不匹配为0。loss损失函数由位置损失,置信度损失两部分加权(交叉验证:
):
SSD Loss
对于位置loss,使用default box对ground truth 进行规一化:
position loss
对于confidence loss,
confidence loss
SSD300输入大小为300x300, SSD512输入图片大小为512x512,如下是性能比较:
Performance
7. YOLO V2
基于YOLO有2个改进版,一个是YOLO V2, 一个是YOLO9000.
YOLO9000综合ImageNet数据集和COCO数据集训练YOLO9000,使之可以实时识别超过9000种物品。
YOLO V2相比于V1算法层面提升较少,主要是使用了更多的trick,使得检测准确率得到了极大的提升,下面是这些trick提升的结果分析:
YOLO vs YOLO_v2
YOLO vs YOLO_v2
1. Batch Norm
CNN在训练过程中网络每层输入的分布一直在改变, 会使训练过程难度加大,但可以通过normalize每层的输入解决这个问题。新的YOLO网络在每一个卷积层后添加batch normalization,通过这一方法,mAP获得了2%的提升。batch normalization 也有助于规范化模型,可以在舍弃dropout优化后依然不会过拟合。
2. High Resolution Classifier
目前的目标检测方法中,基本上都会使用ImageNet预训练过的模型(classifier)来提取特征,如果用的是AlexNet网络,那么输入图片会被resize到不足256 * 256,导致分辨率不够高,给检测带来困难。为此,新的YOLO网络把分辨率直接提升到了448 * 448,这也意味之原有的网络模型必须进行某种调整以适应新的分辨率输入。
对于YOLOv2,作者首先对分类网络(自定义的darknet)进行了fine tune,分辨率改成448 * 448,在ImageNet数据集上训练10轮(10 epochs),训练后的网络就可以适应高分辨率的输入了。然后,作者对检测网络部分(也就是后半部分)也进行fine tune。这样通过提升输入的分辨率,mAP获得了4%的提升。
3. 全卷积网络
为了使网络能够接受多种尺寸的输入图像,yolov2除去了v1网络结构中的全连层,因为全连接层必须要求输入输出固定长度特征向量。将整个网络变成一个全卷积网络,能够对多种尺寸输入进行检测。同时,全卷积网络相对于全连接层能够更好的保留目标的空间位置信息。
4. 新的基础卷积网络
基于Darknet-19。vgg16虽然精度足够好,但是模型比较大,网络传输起来比较费时间,因此,作者提出了一个自己的模型,Darknet-19。而darknetv2也正式已Darknet-19作为pretrained model训练起来的。
Network comparision
5. Anchor Boxes
YOLO采用全连接层来直接预测bounding boxes,而Fast R-CNN采用人工选择的bounding boxes。Fast R-CNN中的 region proposal network仅采用卷积层来预测固定的boxes(anchor boxes)的偏移和置信度。
作者去除了YOLO的全连接层,采用固定框(anchor boxes)来预测bounding boxes。首先,去除了一个pooling层来提高卷积层输出分辨率。然后,修改网络输入尺寸:由448×448改为416,使特征图只有一个中心。物品(特别是大的物品)更有可能出现在图像中心。YOLO的卷积层下采样率为32,因此输入尺寸变为416,输出尺寸为13×13。
采用anchor boxes,提升了精确度。
加入了anchor boxes后,可以预料到的结果是召回率上升,准确率下降。我们来计算一下,假设每个cell预测9个建议框,那么总共会预测13 * 13 * 9 = 1521个boxes,而之前的网络仅仅预测7 * 7 * 2 = 98个boxes。具体数据为:没有anchor boxes,模型recall为81%,mAP为69.5%;加入anchor boxes,模型recall为88%,mAP为69.2%。这样看来,准确率只有小幅度的下降,而召回率则提升了7%,说明可以通过进一步的工作来加强准确率,的确有改进空间.
6. Dimension Clusters(维度聚类)
作者在使用anchor的时候遇到了两个问题,第一个是anchor boxes的宽高维度往往是精选的先验框(hand-picked priors),虽说在训练过程中网络也会学习调整boxes的宽高维度,最终得到准确的bounding boxes。但是,如果一开始就选择了更好的、更有代表性的先验boxes维度,那么网络就更容易学到准确的预测位置。
和以前的精选boxes维度不同,作者使用了K-means聚类方法类训练bounding boxes,可以自动找到更好的boxes宽高维度。传统的K-means聚类方法使用的是欧氏距离函数,也就意味着较大的boxes会比较小的boxes产生更多的error,聚类结果可能会偏离。为此,作者采用的评判标准是IOU得分(也就是boxes之间的交集除以并集),这样的话,error就和box的尺度无关了,最终的距离函数为:
距离
作者通过改进的K-means对训练集中的boxes进行了聚类,判别标准是平均IOU得分,聚类结果如下图:
聚类结果
可以看到,从K=1到K=5,IOU曲线上升较快(对应匹配度高),因此从效果和复杂度进行Trade Off, 选定了 Anchor Box个数为5;意味着作者选择了5种大小的box维度来进行定位预测,这与手动精选的box维度不同。结果中扁长的框较少,而瘦高的框更多(这符合行人的特征),选定了5种不同 宽高比+Scale 的 Anchor Box;对应上图中的矩形。
当然,作者也做了实验来对比两种策略的优劣,如下图,使用聚类方法,仅仅5种boxes的召回率就和Faster R-CNN的9种相当。说明K-means方法的引入使得生成的boxes更具有代表性,为后面的检测任务提供了便利。
性能比较
7. Direct location prediction(直接位置预测)
那么,作者在使用anchor boxes时发现的第二个问题就是:模型不稳定,尤其是在早期迭代的时候。大部分的不稳定现象出现在预测box的(x,y)坐标上了。在区域建议网络中,预测(x,y)以及tx,ty使用的是如下公式
x, y
这个公式的理解为:当预测tx=1,就会把box向右边移动一定距离(具体为anchor box的宽度),预测tx=-1,就会把box向左边移动相同的距离。
这个公式没有任何限制,使得无论在什么位置进行预测,任何anchor boxes可以在图像中任意一点结束。模型随机初始化后,需要花很长一段时间才能稳定预测敏感的物体位置。
在此,作者就没有采用预测直接的offset的方法,而使用了预测相对于grid cell的坐标位置的办法,作者又把ground truth限制在了0到1之间,利用logistic回归函数来进行这一限制。
现在,神经网络在特征图(13 *13 )的每个cell上预测5个bounding boxes(聚类得出的值),同时每一个bounding box预测5个坐标值,分别为tx,ty,tw,th,to。如果这个cell距离图像左上角的边距为(cx,cy)以及该cell对应的box维度(bounding box prior)的长和宽分别为(pw,ph),那么预测值可以表示为:
预测值
定位预测值被归一化后,参数就更容易得到学习,模型就更稳定。作者使用Dimension Clusters和Direct location prediction这两项anchor boxes改进方法,mAP获得了5%的提升。
Bounding box
8. Fine gained features
上述网络上的修改使YOLO最终在13 * 13的特征图上进行预测,虽然这足以胜任大尺度物体的检测,但是用上细粒度特征的话,这可能对小尺度的物体检测有帮助。Faser R-CNN和SSD都在不同层次的特征图上产生区域建议(SSD直接就可看得出来这一点),获得了多尺度的适应性。这里使用了一种不同的方法,简单添加了一个转移层( passthrough layer),这一层要把浅层特征图(分辨率为26 * 26,是底层分辨率4倍)连接到深层特征图。
残差学习
这个转移层也就是把高低两种分辨率的特征图做了一次连结,连接方式是叠加特征到不同的通道而不是空间位置,类似于Resnet中的identity mappings(对Resnet这一机制几乎不懂,等看懂了再行补充)。这个方法把26 * 26 * 512的特征图连接到了13 * 13 * 2048的特征图,这个特征图与原来的特征相连接。YOLO的检测器使用的就是经过扩张的特征图,它可以拥有更好的细粒度特征,使得模型的性能获得了1%的提升。
9. Multi-Scale Training
原来的YOLO网络使用固定的448 * 448的图片作为输入,现在加入anchor boxes后,输入变成了416 * 416。目前的网络只用到了卷积层和池化层,那么就可以进行动态调整(意思是可检测任意大小图片)。作者希望YOLOv2具有不同尺寸图片的鲁棒性,因此在训练的时候也考虑了这一点。
不同于固定输入网络的图片尺寸的方法,作者在几次迭代后就会微调网络。每经过10次训练(10 epoch),就会随机选择新的图片尺寸。YOLO网络使用的降采样参数为32,那么就使用32的倍数进行尺度池化{320,352,…,608}。最终最小的尺寸为320 * 320,最大的尺寸为608 * 608。接着按照输入尺寸调整网络进行训练。(网络只用到了卷积层和池化层,没有全连接层,所以可以进行动态调整(检测任意大小图片))
这种机制使得网络可以更好地预测不同尺寸的图片,意味着同一个网络可以进行不同分辨率的检测任务,在小尺寸图片上YOLOv2运行更快,在速度和精度上达到了平衡。
在小尺寸图片检测中,YOLOv2成绩很好,输入为228 * 228的时候,帧率达到90FPS,mAP几乎和Faster R-CNN的水准相同。使得其在低性能GPU、高帧率视频、多路视频场景中更加适用。
三、运行YOLO V2
1. YOLO V2
下载darknet神经网络框架,darknet是用C写的轻量级深度学习框架:
windows版本darknet: https://github.com/AlexeyAB/darknet
git clone https://github.com/pjreddie/darknet
cd darknet
make
下载预训练的权重文件, 大小为195MB:
wget https://pjreddie.com/media/files/yolo.weights
开始进行检测:
./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg
输出如下结果:
算法结果
predictions
在我的CPU上跑需要19.7s,作者在Taitan X上只用了0.016s,如下图:
GPU结果
另外,可以通过-thresh调整阈值,默认得分大于0.25才认为是目标,如下将阈值设为0:
./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg -thresh 0
2. Tiny YOLO V2
Tiny YOLO准确率不如YOLO,但快了许多:
下载权重文件, 大小61MB:
wget https://pjreddie.com/media/files/tiny-yolo-voc.weights
检测:
./darknet detector test cfg/voc.data cfg/tiny-yolo-voc.cfg tiny-yolo-voc.weights data/dog.jpg
结果如下:
检测结果
predictions
可以看到预测的结果没有YOLO准确,但时间只需要2.3s。
3. 实时检测
如果安装了CUDA和OpenCV,可以通过摄像头实时进行目标检测:
./darknet detector demo cfg/coco.data cfg/yolo.cfg yolo.weights
也可以对视频文件进行检测:
./darknet detector demo cfg/coco.data cfg/yolo.cfg yolo.weights <video file>
4. YOLO用来做人脸检测
需要根据你的应用场景来判断是否合适。比如yolov1一个grid只能输出1个目标物体,那么如果你的场景会有很多人或者画面中人较小以致于很多人头部落入一个grid,那么使用yolov1会有很多漏检测。而且v1的localization的精准性并不高,所以如果对定位精准性要求高的 也不太适合。
四、tensorflow实现
五、目标检测评估
precision = overlap / detection box
recall = overlap / ground truth box
IOU = overlap / union
评估标准
使用map:
./darknet detector map cfg/voc.data cfg/yolo-voc.cfg yolo-voc.weights
detections_count = 124124, unique_truth_count = 12032
class_id = 0, name = aeroplane, ap = 77.08 %
class_id = 1, name = bicycle, ap = 81.11 %
class_id = 2, name = bird, ap = 75.97 %
class_id = 3, name = boat, ap = 64.66 %
class_id = 4, name = bottle, ap = 48.74 %
class_id = 5, name = bus, ap = 82.53 %
class_id = 6, name = car, ap = 83.36 %
class_id = 7, name = cat, ap = 87.65 %
class_id = 8, name = chair, ap = 58.95 %
class_id = 9, name = cow, ap = 81.82 %
class_id = 10, name = diningtable, ap = 75.22 %
class_id = 11, name = dog, ap = 86.32 %
class_id = 12, name = horse, ap = 86.38 %
class_id = 13, name = motorbike, ap = 84.21 %
class_id = 14, name = person, ap = 76.48 %
class_id = 15, name = pottedplant, ap = 51.42 %
class_id = 16, name = sheep, ap = 78.77 %
class_id = 17, name = sofa, ap = 77.10 %
class_id = 18, name = train, ap = 85.40 %
class_id = 19, name = tvmonitor, ap = 74.72 %
for thresh = 0.24, precision = 0.68, recall = 0.79, F1-score = 0.73
for thresh = 0.24, TP = 9459, FP = 4450, FN = 2573, average IoU = 52.58 %mean average precision (mAP) = 0.758959, or 75.90 %
Total Detection Time: 132.000000 Seconds
使用reval_voc_py3.py结果:
./darknet detector valid cfg/voc.data cfg/yolo-voc.cfg yolo-voc.weights
python3 scripts/reval_voc_py3.py --year 2007 --classes data/voc.names --image_set test --voc_dir /home/guru_ge/dataset/voc/VOCdevkit/ results
Mean AP = 0.7602
Results:
0.773
0.813
0.759
0.654
0.490
0.825
0.841
0.876
0.592
0.814
0.751
0.863
0.863
0.843
0.767
0.528
0.781
0.770
0.853
0.747
0.760
Referece