博客搬家,新博客地址:
https://imlogm.github.io/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/rcnn/摘要:物体检测(object detection)是计算机视觉非常重要的一个领域。在深度学习出现之前,传统方法始终无法处理好物体检测问题,在深度学习方法引入之后,物体检测领域发生了翻天覆地的变化。最著名的是RCNN系列,另外还有YOLO、SSD。这篇文章首先介绍RCNN系列。
关键字:深度学习, 物体检测, RCNN
物体检测(object detection)是计算机视觉非常重要的一个领域。在深度学习出现之前,传统方法始终无法处理好物体检测问题,在深度学习方法引入之后,物体检测领域发生了翻天覆地的变化。最著名的是RCNN系列,另外还有YOLO、SSD。这篇文章首先介绍RCNN系列。
网上关于RCNN系列介绍的文章非常多,比如基于深度学习的目标检测技术演进:R-CNN、Fast R-CNN、Faster R-CNN-冠军的试练的博客就用非常简洁明了的语言介绍了整个系列的诞生和演变过程。
如果你不在意具体的实现细节的话,上面链接中的文章就已经足够了。下面贴出的文章将更加深入实现细节,我会在每篇文章之后写上自己阅读时想到的问题,也许你们也会与我有同样的问题。
RCNN-将CNN引入目标检测的开山之作-晓雷的文章
RCNN的过程分4个阶段:
1. 候选区域提出阶段(Proposal):采用selective-search方法,从一幅图像生成1K~2K个候选区域;
2. 特征提取:对每个候选区域,使用CNN进行特征提取;
3. 分类:每个候选区域的特征放入分类器SVM,得到该候选区域的分类结果;
4. 回归:候选区域的特征放入回归器,得到bbox的修正量。
下面是我在阅读时想到的一些问题。
由于RCNN特征提取阶段采用的是AlexNet,其最后两层是全连接层fc6和fc7,所以必须保证输入的图片尺寸相同。
而候选区域所产生的结果尺寸是不相同的。为此,论文中作者采用了多种方式对图片进行放缩(各向同性、各向异性、加padding),最后经过对比实验确定各向异性加padding的放缩方式效果最好。各向同性、各向异性、加padding的具体效果可以看上面链接中的文章。
论文中,单个SVM实现的是二分类,分类器阶段由多个SVM组合而成。比如总共有20种不同的物体(加1种背景),那么分类阶段必须要有21个SVM:第1个SVM的输出是该候选区域属于分类1的概率;第2个SVM的输出是该候选区域属于分类2的概率;……;第21个SVM的输出是该候选区域属于背景的概率。
对21个SVM的输出结果进行排序,哪个输出最大,候选区域就属于哪一类。比如,对于某个候选区域,第21个SVM的输出最大,那么就将该候选区域标为背景。
分类器的输入是特征提取器AlexNet的fc6的输出结果,回归器的输入是特征提取器AlexNet的pool5的输出结果。
之所以这样取输入,是因为,分类器不依赖坐标信息,所以取fc6全连接层的结果是没有问题的。但是回归器依赖坐标信息(要输出坐标的修正量),必须取坐标信息还没有丢失前的层。而fc6全连接层已经丢失了坐标信息。
正负样本是必须要考虑的问题。论文的做法是每个batch所采样的正负样本比为1:3。当然这个比例是可以变化的,这个系列的后续改进就把正负样本比变为了1:1。
如果之前没有接触过类似问题的话,是比较容易想当然地认为训练特征提取器、分类器、回归器时,就是把候选区域生成阶段的所有候选区域都放入训练。这样的思路是错的。一张图片中,背景占了绝大多数地方,这样就导致训练用的正样本远远少于负样本,对训练不利。
正确的做法是对所有候选区域进行随机采样,要求采样的结果中正样本有x张,负样本y张,且保证x与y在数值上相近。(对于一些问题,不大容易做到x:y = 1:1,但至少x与y应该在同一数量级下)
RCNN的网络架构,注定了它不能像其他网络那样进行端到端(end-to-end)的训练。
前面提到RCNN分为4个阶段:Proposal阶段、特征提取阶段、分类阶段、回归阶段。这4个阶段都是相互独立训练的。
首先,特征提取器是AlexNet,将它的最后一层fc7进行改造,使得fc7能够输出分类结果。Proposal阶段对每张图片产生了1k~2k个候选区域,把这些图片依照正负样本比例喂给特征提取器,特征提取器fc7输出的分类结果与标签结果进行比对,完成特征提取器的训练。特征提取器的训练完成后,fc7层的使命也完成了,后面的分类器和回归器只会用到fc6、pool5的输出。
然后,Proposal和特征提取器已经训练完毕了。把它们的结果fc6,输入到分类器SVM中,SVM输出与标签结果比对,完成SVM的训练。
最后,回归器的训练也和SVM类似,只不过回归器取的是pool5的结果。
为什么不能同时进行上面3步的训练?因为特征提取器是CNN,分类器是SVM,回归器是脊回归器,不属于同一体系,无法共同训练。甚至在测试时,也需要把每一阶段的结果先保存到磁盘,再喂入下一阶段。这是非常麻烦的一件事。
聪明的你可能已经想到了:CNN不就能完成分类器和回归器的任务嘛?为什么不只用CNN?这就是RCNN系列后续做的改进之一,我们在下面会讲到。但由于某些原因,在RCNN这篇论文发表时,采用的是特征提取、分类器、回归器相互独立的结构。
是的,很慢。Proposal阶段会产生1k~2k个候选区域,每个候选区域都独立提取特征的话,那相当于每幅图片都要进行1k~2k次CNN。(当然由于有正负样本采样,实际并没有有这么多)
有没有什么好方法?聪明的你应该能想到:既然候选区域都是图片的一部分,那么先对整张图片进行特征提取,然后根据每个候选区域在原图上的位置选择相应的特征不就行了。
这种方式正是RCNN系列的后续改进之一,只不过在实现上要动点脑筋。(这种方式得到的每个区域的特征数目是不同的,如何把不同特征数目变为相同数目?)
Fast R-CNN-晓雷的文章
理解了RCNN就能很快理解Fast-RCNN了。来讲讲Fast-RCNN相对于RCNN的改进之处。
首先,正如我们在2.5节提到的,Fast-RCNN将特征提取器、分类器、回归器合在了一起,都用CNN实现。
其次,正如我们在2.6节提到的,Fast-RCNN对整张图片进行特征提取,再根据候选区域在原图中的位置挑选特征。针对特征数目不同的问题,Fast-RCNN加入了ROI层,使得经过ROI层后,特征的数目相同。
ROI层的出现与SPPNet有密不可分的联系,请参见:SPPNet-引入空间金字塔池化改进RCNN-晓雷的文章
将特征提取器、分类器、回归器合并,使得训练过程不需要再将每阶段结果保存磁盘单独训练,可以一次性完成训练,加快了训练速度。这是Fast之一。
对整张图片进行特征提取,用ROI层处理候选区域的特征,使得原本每一个候选区域都要做一次特征提取,变为了现在一整张图片做一次特征提取。训练速度(8.8倍)和测试速度(146倍)都大大加快,这是Fast之二。
分类器应该都能想到,用的softmax代替SVM。
回归器求出(x,y,w,h)4个量,分别代表定位框左上角的坐标xy、宽度w、高度h,损失函数用的是Smooth-L1。
发展到Fast-RCNN,后续3个阶段都是CNN完成的了,只剩下Proposal阶段还没有用CNN方式解决。Proposal阶段的结果还是需要先保存到磁盘,再喂入后续阶段,有点违和。
RCNN系列后续的改进,将把Proposal阶段也用CNN实现,真正做到端到端(end-to-end)。
Faster R-CNN-晓雷的文章
Faster-RCNN引入了RPN网络(region proposal network)来代替selective-search。这使得整个网络实现了端到端。
上面链接里的文章讲的挺详细的:整张图片经过特征提取,得到FeatureMap;将FeatureMap中的每一点按照视野域找到原图中对应的位置,称为Anchor;每个Anchor生成不同大小不同长宽比的多个候选区域。
回忆下selective-search的候选区域生成方式,它是按照颜色和纹理不断合并得到候选区域的,候选区域的产生没有规律,而RPN是每个Anchor都有对应的固定数量的候选区域,规律很明显。
理论上说,selective-search生成候选区域的方式更符合我们的直觉,而实验结果,在Faster-RCNN中RPN并不比selective-search差
容易想到,现在RPN网络可以与其他3个阶段共用同一个特征提取结果了,省掉了selective-search的时间。而事实上,selective-search是非常慢的,所以叫Faster。
Mask-RCNN技术解析-linolzhang的专栏
到Faster-RCNN时,RCNN系列对物体检测问题已经非常拿手了。Mask-RCNN则是将RCNN扩展到语义分割领域。
Faster-RCNN网络的最后分别是分类网络和回归网络两条路并行,Mask-RCNN则是再加一条Mask网络与它们并行。
Mask网络的实现是FCN网络,这也是语义分割领域中非常经典的网络结构。
由于Mask网络的加入,Mask-RCNN不仅能处理物体检测问题,还能处理语义分割问题。
首先是ROI层变为了ROIAlign,目的是一样的。那为什么要加入ROIAlign呢?这是因为ROI层会有对齐问题,对齐问题在分类和框选时影响不大,但在语义分割需要严格依赖每个像素点的坐标时,影响会很大。ROIAlign能够解决对齐问题。
然后是特征提取网络改为了ResNet101+FPN,ResNet我在之前的博客中有细讲;FPN建议对语义分割或者关键点定位感兴趣的同学了解下,FPN是这两个领域中非常经典的结构。