论文笔记:目标检测算法(R-CNN,Fast R-CNN,Faster R-CNN,FPN,YOLOv1-v3)
R-CNN(Region-based CNN)
- motivation:之前的视觉任务大多数考虑使用SIFT和HOG特征,而近年来CNN和ImageNet的出现使得图像分类问题取得重大突破,那么这方面的成功能否迁移到PASCAL VOC的目标检测任务上呢?基于这个问题,论文提出了R-CNN。
- 基本步骤:如下图所示,第一步输入图像。第二步使用生成region proposals的方法(有很多,论文使用的是seletivce search,ImageNet2013检测任务的冠军UVA也使用了该算法)提取约2000个候选区域。由于CNN固定输入大小所以第二步和第三步之间需要做一个warped region。第三步将2000个候选区域分别输入到CNN(AlexNet)计算2000个特征向量,第四步将各个特征向量(4096维,相比于之前常用的方法UVA减小了2个量级,4k vs 360k)输入到(类特定的)各个线性SVM中分类(比如VOC的20个类别就有20个SVM)。对于特定类的SVM,由于有2000个候选区域,所以有2000个结果,使用非极大值抑制来获得得分较高的一些候选区。
- CNN的训练:使用的CNN在ImageNet2012分类数据集上做了预训练。微调时把最后的1000类改为N+1类,对于VOC而言N为20,对于ImageNet2013检测数据集而言N为200,以IOU大于等于0.5为正样本,其它为负样本,学习率0.001,每次SGD迭代(128的batch size)中用了32个正窗口(所以类上)和96个背景窗口。
- SVM的训练:以0.3作为IOU阈值来选取正负样本。由于负样本太多,采用hard negative mining的方法在负样本中选取有代表性的负样本。
- R-CNN BB:为了提高定位表现,额外使用了一个bounding box regression。用第五个池化层的特征输入到SVM获取得分,然后(根据最大IOU)构建候选区域和真实区域的数据集,训练一个回归器,可以对候选区域的位置修正。
- 结果比较之VOC:在VOC 2007上调参,在VOC 2010-12上进行预测。CNN在VOC 2012训练集上做微调,SVM在VOC 2012的训练验证集上进行训练。超越了其它算法。
- 结果比较之ImageNet2013:OverFeat是ImageNet2013定位任务的冠军,对于检测任务在赛后也获得了第一的成绩(24.3%的mAP),是ImageNet2013检测数据集(200类)上表现最好的检测算法(当时),而R-CNN用在ImageNet2013的检测数据集上获得了31.4%的mAP。
Fast R-CNN
- R-CNN的三个缺点:多阶段(训练CNN,训练SVM,训练bb回归器);训练时空间和时间代价高(对于SVM和bb回归器需要把每张图像的每个候选区特征通过CNN提取出来存到磁盘);预测阶段很慢(因为要对每张图像的每个候选区域提取特征)。
- SPPnet的改进:R-CNN预测慢是因为对于每个候选区域要过一次CNN而不共享计算,而SPPnet则是使用共享计算来加速。如下第一个图所示,SPP输入整张图,计算一个feature map,在feature map上找到候选区对应的一个子图,然后对子图做一个金字塔池化得到一个固定长度的特征向量(下图中得到的是4x4+2x2+1个特征)。 尽管如此,SPPnet仍然有多阶段以及特征写入磁盘的缺点,而且因为SPPnet的特征是从conv5的feature map上池化而来的,所以只fine-tuning金字塔池化层之后的层(这限制了深层网络的准确性)。
- motivation:Fast R-CNN修正了R-CNN和SPPnet(Spatial pyramid pooling)的缺点,提升了速度和准确率。它是一个单阶段的算法,使用了multi-task loss,可以对整个网络进行更新,而且不需要把特征存到磁盘上。
- 主要步骤:如下第二个图所示,输入为一整张图以及一系列的(selective search生成的)候选区域(映射到conv5的feature map上得到ROI),ROI意为Region of Interest。像SPPnet一样对ROI进行池化,只不过这里是单水平的金字塔池化(如下第一个图是三水平),比如分成7x7个子图对每个子图取最大得到长度为49个ROI特征。池化后经过FC,然后分成两个分支,一个分支用softmax做分类,一个分支用bb回归器做定位,使用multi-task loss进行训练。
- mini-batch sampling:R-CNN和SPPnet在微调训练时每个batch是从128张图像中分别取一个RoI。而Fast取N个图像,每个图像取R/N个ROI(论文中使用N=2,R=128),这样来自同一个图像的ROI在前向和后向过程中就可以共享内存和计算,提高了效率。采样时25%的ROI是从IOU为0.5以上的侯选框选的,剩余的ROI是从IOU为[0.1, 0.5)中的侯选框选的。
- SGD超参:softamx和bb回归器的全连接层使用0均值,0.01和0.001的标准差的高斯分布进行初始化。bias为0。所有层的权重学习率为1倍的全局学习率,偏置为2倍的全局学习率,全局学习率为0.001。对于VOC07或者、VOC12的训练,30k次迭代,然后学习率减为0.0001然后训练另外10k次迭代。momentum为0.9,weight decay为0.0005。
- 截断的SVD:将庞大的全连接层压缩为截断的SVD可以提高检测速度。
- 应该微调哪些层:消融学习(ablation study)中,固定前面的卷积,只微调后面的全连接层(像SPPnet那样)发现mAP下降,说明微调前面的卷积层是重要的。那么是不是说所有的卷积层都应该被微调呢,不是, 通过实验发现conv1对mAP影响不大,对于VGG16,发现只需要更新conv3_1以及以后的层。
- 其它实验和讨论:通过实验,发现单尺度可以获得和多尺度差不多的结果,所以论文的实验都是使用单尺度。通过实验,发现更多训练数据可以提高mAP。通过实验,发现softmax比SVM好一点点,差距不大。通过实验,发现随着候选区数量的增加,mAP先增后降,说明不是越多越好。将Fast运行在COCO数据集上建立一个初步baseline。
Faster R-CNN
- motivation:Fast R-CNN的瓶颈在于生成候选区域(Selective Search的)的方法非常耗时,Faster提出把生成候选区域也放到卷积网络来做(网络称为RPN,Region Proposal Networks),将RPN和检测网络(Fast R-CNN)结合成一个网络进行统一的训练和检测,这样可以共享卷积操作,减小计算时间。实验也表明了Faster可以提高检测表现。
- 主要步骤:如下第一个图所示,在原来网络的最后一层卷积层加入一个RPN来生成ROI,然后根据feature map和ROI进行ROI池化,后面和Fast一样再接全连接,softmax和回归器。
- RPN结构:设计如下第二个图,RPN在最后一个卷积层上以nxn的窗口滑动进行卷积(论文中n为3,所对应的感受野是很大的),每个窗口(一小块3x3的区域)被映射成低维特征(ZFnet-256d,VGG-512d),然后分为两路接两个1x1卷积得到分类层和回归层。其中k表示事先设计的k个anchor(论文中k为9,3种scale和3种宽高比组合),分类层的2k个单元中的2表示是或不是,回归层的4k个单元中的4表示目标对应的坐标位置。最后会根据这两个层计算一个损失进行训练。
- 训练RPN:训练时,和某个grouth truth的IoU值最高的anchor视为正样本,和任意ground truth的IoU超过0.7的anchor也视为正样本。和所有ground truth的IoU低于0.3的视为负样本,其它的忽略,超出原图边界的anchor也忽略(如果测试阶段得到这种anchor,则clip到边界)。一个mini-batch(256)为一张图像的多个anchor,正负比例为1比1。共享卷积层遵循R-CNN的实践进行ImageNet分类的预训练来对参数初始化,对ZFnet调整整个网络,对VGG微调conv3_1以上的层。其它新增层(RPN)用(0,0.01)的高斯分布初始化参数。前60k次mini-batch使用0.001的学习率,后20k次mini-batch使用0.0001的学习率,在VOC数据集上。momentum为0.9,weight decay为0.0005。
- RPN和检测网络(Fast R-CNN)的训练:论文采用的是交替训练的方式,第一步按上述步骤训练RPN。第二步用RPN产生的候选区域训练检测网络,检测网络也进行了预训练,到这一步,二者不共享前面的公共卷积层。第三步用检测网络的参数初始化RPN前面的公共卷积层,微调RPN,此时RPN和检测网络共享前面的卷积层。第四步,微调检测网络的后半部分(固定公共卷积层)。另外,RPN产生的区域可能高度重叠,根据RPN的分类分数,使用非极大值抑制(0.7的IOU阈值)来减小候选区域数量。
FPN(Feature Pyramid Networks)
- motivation:对不同尺度的物体进行识别是图像任务的一项基本挑战,之前的做法有如下图(a)(b)(c)三种,这些做法都有各自的缺点,于是本文提出图(d)中的做法,即FPN。
- 图(a)特征化的图像金字塔:很天然的想法就是将图像做成不同的scale,然后不同scale的图像生成对应的不同scale的特征,实际上所有在 ImageNet 和 COCO检测任务上取得最好成绩的方法都使用了这种方法进行了多尺度预测(比如像SPP那样预测的时候对多个尺度进行空间金字塔池化)。然而要做这种多尺度训练(很占内存)是不可行的,如果要用也只是用在多尺度预测上,即使是用在预测上也会减慢很多时间,也造成了训练和测试的不一致。
- 图(b)单个特征图:由于CNN对尺度改变的鲁棒性(相对传统的手工特征),可以使用单尺度图像来进行训练,为了更快,最近的检测系统都采用这种方法(SPP,Fast和Faster)。
- 图(c)层次化的金字塔特征:直接重用CNN中不同层上的多尺度特征图,SSD采用了类似的思想,为了避免利用太低层的特征,SSD从偏后的层开始提取特征。但是这样丢失了利用高分辨率的底层特征,而这样的特征对于预测小物体是很重要的。
- 图(d)FPN:于是本文提出了FPN,它可以和(b)(c)一样快,但是更准确。具体如下第二个图所示,高层feature map上采样,然后和前层(做1x1卷积后的feature map)做element-wise。通过这种bottom-up与top-down结合的方法可以获得较强的语义特征,提高检测的性能。
- 应用:论文把FPN应用到RPN,Fast和Faster上,提升了检测效果。
Yolo(You Only Look Once)v1
- motivation:与R-CNN系列算法(产生候选区域,分类,回归修正)不同,yolo直接用一个单独的卷积网络输入图像,输出bb(bounding box)和分类概率。
- 优点:第一是更快(不需要像R-CNN系列那样复杂的步骤)。第二是站在全局的角度(可以看到整张图像)去预测,可以产生更小的背景误差。第三是能学到泛化能力强的特征(实验表明)。
- 缺点:第一是施加了很强的空间限制,导致系统能预测的目标数量有限,而且对靠的很近的物体和很小的物体的检测效果不好。第二是难以泛化到新的不常见的长宽比物体。第三是损失函数对小bb和大bb的误差同等对待,小误差对大bb来说没什么,但是对小bb来说影响很大,yolo的主要错误就是来源于定位错误。还有一点是准确率无法达到state-of-art的水平。
- 主要思想:如下图所示,将输入图像划分为SxS的格子,目标(物体)的中心落在哪个格子内,就由哪个格子负责。每个格子检测B个bb和C个类别的条件概率。每个bb包含5个值(x, y, w, h, 置信度),其中x和y相对于格子归一化到0到1,w和h相对于整张图像归一化为0到1,置信度定义为\(Pr(Object)*IOU_{pred}^{truth}\),我们希望“如果没有物体则置信度为0,如果有物体,Pr为1,置信度表示为IOU"。C个类别的条件概率为\(Pr(Class_i | Object)\)。测试阶段用条件概率乘上置信度,得到一个类相关的置信度。所以最后输出层的单元数字应该为SxSx(Bx5+C),论文中S为7,B为2,C为20类(VOC数据集),所以输出是一个7x7x30的tensor。另外,对于一个大物体,可能出现多个格子对它负责预测,这个时候使用非极大值抑制处理。
- 训练:网络结构参考GoogleNet做了修改。在ImageNet上做了1000类分类的预训练,然后增加卷积层和全连接层,把224的输入改成448(检测需要更细粒度的视觉信息)。输出层使用线性激活,其它层使用leaky relu。在VOC07和12的训练集和验证集上训练了135个epochs,在VOC12测试时也使用(加入)了VOC07的测试集进行训练。batch size 为64,momentum为0.9,weight decay为0.0005。学习率在第一个epoch从0.001缓慢升到0.01,如果一开始使用高学习率会由于不稳定的梯度导致模型不收敛。然后0.01训练75个epochs,0.001训练30个epochs,0.0001训练最后30个epochs。为了防止过拟合使用了dropout(第一个连接层之后,0.5)和数据增强。
- 损失函数:如下(论文中给出的)式子所示。损失函数把定位误差和分类误差平等对待可能不太好,而且一张图像可能很多格子是没有物体的,使得置信度几乎为0,这压制了确实有物体的格子的梯度,使得模型不稳定。所以需要减小不含物体的bb的置信度带来的损失(给予一个0.5的权重\(\lambda_{noobj}\)),增加bb坐标带来的损失(给予一个5的权重\(\lambda_{coord}\))。损失函数把大bb和小bb平等对待也不太好,为了一定程度上弥补这个问题,对于宽度和高度,使用它们的平方根来代替它们本身。
- 其它:关于yolo之前在ng深度学习课程中有所了解,具体笔记见:ng-深度学习-课程笔记-目标检测。
\[\lambda_{coord}\sum_{i=0}^{S^2}\sum_{j=0}^{B}\mathbb{1}_{ij}^{obj}[(x_i-\hat{x}_i)^2+(y_i-\hat{y}_i)^2] + \\
\lambda_{coord}\sum_{i=0}^{S^2}\sum_{j=0}^{B}\mathbb{1}_{ij}^{obj}[(\sqrt{w_i}-\sqrt{\hat{w}_i})^2+(\sqrt{h_i}-\sqrt{\hat{h}_i})^2] + \\
\sum_{i=0}^{S^2}\sum_{j=0}^{B}\mathbb{1}_{ij}^{obj}(C_i - \hat{C}_i)^2+ \lambda_{noobj}\sum_{i=0}^{S^2}\sum_{j=0}^{B}\mathbb{1}_{ij}^{noobj}(C_i - \hat{C}_i)^2 + \\
\sum_{i=0}^{S^2}\mathbb{1}_{i}^{obj}\sum_{c \in classes}(p_i(c)-\hat{p}_i(c))^2\]
Yolov2
- yolov2:从yolov1到yolov2增加了一系列设定来改善yolo,如下第一个图所示。
- hi-res classifier:表示在正式训练检测网络(448x448)之前先使用448x448输入图像的分类网络进行预训练(在这之前已经在ImageNet上进行224输入图像的预训练)。
- convolutional和anchor boxes:表示借鉴Faster的做法,去掉回归层之前的全连接和池化,在最后一层卷积层上进行anchor box的预测,此举虽然降低了mAP,但是提高了recall(81到88)。在v1中类别是分配到格子的,所以是最后tensor大小是SxSx(Bx5+C),C是类别。而v2中每个格子设计多个anchor box(表示每个格子分配多少个bb),类别分配到了格子的bb中,所以最后tensor大小是SxSxBx(5+C)。
- new network:表示使用新的网络结构作为检测的基础网络,借鉴了VGG和NIN,提出了Darknet-19。
- dimension prior:表示使用k-means聚类来设计anchor的形状。
- location prediction:表示不预测offset(Faster中anchor的预测方式),而是沿用yolov1直接预测相对格子的归一化坐标。
- passthrough:表示将最后一层feature map(13x13)和上一层(26x26)调整后的feature map进行concat,因为对于小目标通过层层卷积后可能就不见了,所以连接一下上一层的特征图。
- multi-scale:表示的是多尺度训练。
- hi-res detector:表示使用更高分辨率的输入图像。
- yolo9000:yolo9000以yolov2为主网络,通过联合优化分类和检测的方法,同时训练两个数据集(WordTree结合了ImageNet和COCO的数据集),使得系统能够检测超过9000类的物体,其中WordTree如下第二个图所示。
Yolov3
- bb预测:对于每个bb的objectness score使用逻辑回归。当bb是某个ground truth的最大IOU时则应该预测为1。假如bb并不是最高的,只是(跟ground truth的)IOU大于某个阈值,则忽略预测,跟Faster一样。和Faster不一样的是,对于ground truth只分配一个bb。如果一个bb没有被分配到ground truth就没有坐标损失和分类损失,只有objectness损失。
- 类预测:每个bb的分类预测使用独立逻辑回归以及binary cross-entropy而不使用softmax。这样有助于迁移到更复杂的领域(比如Open Image Dataset中存在重叠标签,比如女人和人),而softmax假定了一个box只属于某一个类。
- 跨尺度预测:借鉴FPN(feature pyramid network)的做法,从三个不同尺度上提取特征,主要就是把前层的feature map拉过来做上采样然后concat。COCO的实验中,每个尺度预测3个boxes所以tensor为NxNx[3x(5+80)],80表示类别。
- 特征提取:在Darknet-19基础上加入了残差结构,提出了Darknet-53。
参考文献
- R-CNN(2014 CVPR):Rich feature hierarchies for accurate object detection and semantic segmentation(模型源码-caffe(matlab)实现)
- Fast R-CNN(2015 ICCV):Fast R-CNN(模型源码-caffe实现)
- Faster R-CNN(2015 NIPS):Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks(模型源码-caffe实现)
- FPN(2017 CVPR):Feature Pyramid Networks for Object Detection(模型源码-caffe实现)
- Yolov1(2016 CVPR):You Only Look Once: Unified, Real-Time Object Detection(模型源码-darknet(C和cuda))
- Yolov2(2017 CVPR):YOLO9000: Better, Faster, Stronger(模型源码-darknet(C和cuda))
- Yolov3:YOLOv3: An Incremental Improvement(模型源码-darknet(C和cuda)实现)