精华内容
下载资源
问答
  • 一文读懂目标检测:R-CNNFast R-CNN、Faster R-CNN、YOLO、SSD   前言 之前我所在的公司七月在线开设的深度学习等一系列课程经常会讲目标检测,包括R-CNNFast R-CNN、Faster R-CNN,但一直没有比较好的...

    一文读懂目标检测:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD

     

    前言

    之前我所在的公司七月在线开设的深度学习等一系列课程经常会讲目标检测,包括R-CNN、Fast R-CNN、Faster R-CNN,但一直没有比较好的机会深入(但当你对目标检测有个基本的了解之后,再看这些课程你会收益很大)。但目标检测这个领域实在是太火了,经常会看到一些写的不错的通俗易懂的资料,加之之前在京东上掏了一本书看了看,就这样耳濡目染中,还是开始研究了。

    今年五一,从保定回京,怕高速路上堵 没坐大巴,高铁又没抢上,只好选择哐当哐当好几年没坐过的绿皮车,关键还不断晚点。在车站,用手机做个热点,修改题库,顺便终于搞清R-CNN、fast R-CNN、faster R-CNN的核心区别。有心中热爱 何惧任何啥。

    为纪念这心中热爱,故成此文。

     

    一、目标检测常见算法

    object detection,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别。所以,object detection要解决的问题就是物体在哪里以及是什么的整个流程问题。


    然而,这个问题可不是那么容易解决的,物体的尺寸变化范围很大,摆放物体的角度,姿态不定,而且可以出现在图片的任何地方,更何况物体还可以是多个类别。

    目前学术和工业界出现的目标检测算法分成3类:
    1. 传统的目标检测算法:Cascade + HOG/DPM + Haar/SVM以及上述方法的诸多改进、优化;

    2. 候选区域/窗 + 深度学习分类:通过提取候选区域,并对相应区域进行以深度学习方法为主的分类的方案,如:
    R-CNN(Selective Search + CNN + SVM)
    SPP-net(ROI Pooling)
    Fast R-CNN(Selective Search + CNN + ROI)
    Faster R-CNN(RPN + CNN + ROI)
    R-FCN

     

    等系列方法;

    3. 基于深度学习的回归方法:YOLO/SSD/DenseBox 等方法;以及最近出现的结合RNN算法的RRC detection;结合DPM的Deformable CNN等

    传统目标检测流程:
    1)区域选择(穷举策略:采用滑动窗口,且设置不同的大小,不同的长宽比对图像进行遍历,时间复杂度高)
    2)特征提取(SIFT、HOG等;形态多样性、光照变化多样性、背景多样性使得特征鲁棒性差)
    3)分类器分类(主要有SVM、Adaboost等)

     

     

     

     

    二、传统的目标检测算法

    2.1 从图像识别的任务说起

    这里有一个图像任务:既要把图中的物体识别出来,又要用方框框出它的位置。

    这个任务本质上就是这两个问题:一:图像识别,二:定位。

    图像识别(classification)
    输入:图片
    输出:物体的类别
    评估方法:准确率


    定位(localization)
    输入:图片
    输出:方框在图片中的位置(x,y,w,h)
    评估方法:检测评价函数 intersection-over-union(关于什么是IOU,请参看七月在线APP题库大题查看深度学习分类下第55题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2138) 


    卷积神经网络CNN已经帮我们完成了图像识别(判定是猫还是狗)的任务了,我们只需要添加一些额外的功能来完成定位任务即可。

    定位的问题的解决思路有哪些?
    思路一:看做回归问题
    看做回归问题,我们需要预测出(x,y,w,h)四个参数的值,从而得出方框的位置。


    步骤1:
      • 先解决简单问题, 搭一个识别图像的神经网络
      • 在AlexNet VGG GoogleLenet上fine-tuning一下(关于什么是微调fine-tuning,请参看:https://www.julyedu.com/question/big/kp_id/26/ques_id/2137)


     
    步骤2:
      • 在上述神经网络的尾部展开(也就说CNN前面保持不变,我们对CNN的结尾处作出改进:加了两个头:“分类头”和“回归头”)
      • 成为classification + regression模式


    步骤3:
      • Regression那个部分用欧氏距离损失
      • 使用SGD训练

    步骤4:
      • 预测阶段把2个头部拼上
      • 完成不同的功能

    这里需要进行两次fine-tuning
    第一次在ALexNet上做,第二次将头部改成regression head,前面不变,做一次fine-tuning

    Regression的部分加在哪?
    有两种处理方法:
      • 加在最后一个卷积层后面(如VGG)
      • 加在最后一个全连接层后面(如R-CNN)

    regression太难做了,应想方设法转换为classification问题。
    regression的训练参数收敛的时间要长得多,所以上面的网络采取了用classification的网络来计算出网络共同部分的连接权值。

    思路二:取图像窗口
      • 还是刚才的classification + regression思路
      • 咱们取不同的大小的“框”
      • 让框出现在不同的位置,得出这个框的判定得分
      • 取得分最高的那个框

    左上角的黑框:得分0.5


    右上角的黑框:得分0.75


    左下角的黑框:得分0.6


    右下角的黑框:得分0.8


    根据得分的高低,我们选择了右下角的黑框作为目标位置的预测。
    注:有的时候也会选择得分最高的两个框,然后取两框的交集作为最终的位置预测。

    疑惑:框要取多大?
    取不同的框,依次从左上角扫到右下角。非常粗暴啊。

    总结一下思路:
    对一张图片,用各种大小的框(遍历整张图片)将图片截取出来,输入到CNN,然后CNN会输出这个框的得分(classification)以及这个框图片对应的x,y,h,w(regression)。


    这方法实在太耗时间了,做个优化。
    原来网络是这样的:


    优化成这样:把全连接层改为卷积层,这样可以提提速。

     

    2.2 物体检测(Object Detection)

    当图像有很多物体怎么办的?难度可是一下暴增啊。

    那任务就变成了:多物体识别+定位多个物体
    那把这个任务看做分类问题?


    看成分类问题有何不妥?
      • 你需要找很多位置, 给很多个不同大小的框
      • 你还需要对框内的图像分类
      • 当然, 如果你的GPU很强大, 恩, 那加油做吧…

    所以,传统目标检测的主要问题是:
    1)基于滑动窗口的区域选择策略没有针对性,时间复杂度高,窗口冗余
    2)手工设计的特征对于多样性的变化没有很好的鲁棒性

    看做classification, 有没有办法优化下?我可不想试那么多框那么多位置啊!

     

    三、候选区域/窗 + 深度学习分类

    3.1 R-CNN横空出世

    有人想到一个好方法:预先找出图中目标可能出现的位置,即候选区域(Region Proposal)。利用图像中的纹理、边缘、颜色等信息,可以保证在选取较少窗口(几千甚至几百)的情况下保持较高的召回率(Recall)。

    所以,问题就转变成找出可能含有物体的区域/框(也就是候选区域/框,比如选2000个候选框),这些框之间是可以互相重叠互相包含的,这样我们就可以避免暴力枚举的所有框了。


    大牛们发明好多选定候选框Region Proposal的方法,比如Selective Search和EdgeBoxes。那提取候选框用到的算法“选择性搜索”到底怎么选出这些候选框的呢?具体可以看一下PAMI2015的“What makes for effective detection proposals?”

    以下是各种选定候选框的方法的性能对比。


    有了候选区域,剩下的工作实际就是对候选区域进行图像分类的工作(特征提取+分类)。对于图像分类,不得不提的是2012年ImageNet大规模视觉识别挑战赛(ILSVRC)上,机器学习泰斗Geoffrey Hinton教授带领学生Krizhevsky使用卷积神经网络将ILSVRC分类任务的Top-5 error降低到了15.3%,而使用传统方法的第二名top-5 error高达 26.2%。此后,卷积神经网络CNN占据了图像分类任务的绝对统治地位。

    2014年,RBG(Ross B. Girshick)使用Region Proposal + CNN代替传统目标检测使用的滑动窗口+手工设计特征,设计了R-CNN框架,使得目标检测取得巨大突破,并开启了基于深度学习目标检测的热潮。

    R-CNN的简要步骤如下
    (1) 输入测试图像
    (2) 利用选择性搜索Selective Search算法在图像中从下到上提取2000个左右的可能包含物体的候选区域Region Proposal
    (3) 因为取出的区域大小各自不同,所以需要将每个Region Proposal缩放(warp)成统一的227x227的大小并输入到CNN,将CNN的fc7层的输出作为特征
    (4) 将每个Region Proposal提取到的CNN特征输入到SVM进行分类

    具体步骤则如下
    步骤一:训练(或者下载)一个分类模型(比如AlexNet)


    步骤二:对该模型做fine-tuning
      • 将分类数从1000改为20,比如20个物体类别 + 1个背景
      • 去掉最后一个全连接层


    步骤三:特征提取
      • 提取图像的所有候选框(选择性搜索Selective Search)
      • 对于每一个区域:修正区域大小以适合CNN的输入,做一次前向运算,将第五个池化层的输出(就是对候选框提取到的特征)存到硬盘



    步骤四:训练一个SVM分类器(二分类)来判断这个候选框里物体的类别
    每个类别对应一个SVM,判断是不是属于这个类别,是就是positive,反之nagative。

    比如下图,就是狗分类的SVM


    步骤五:使用回归器精细修正候选框位置:对于每一个类,训练一个线性回归模型去判定这个框是否框得完美。


    细心的同学可能看出来了问题,R-CNN虽然不再像传统方法那样穷举,但R-CNN流程的第一步中对原始图片通过Selective Search提取的候选框region proposal多达2000个左右,而这2000个候选框每个框都需要进行CNN提特征+SVM分类,计算量很大,导致R-CNN检测速度很慢,一张图都需要47s。



    有没有方法提速呢?答案是有的,这2000个region proposal不都是图像的一部分吗,那么我们完全可以对图像提一次卷积层特征,然后只需要将region proposal在原图的位置映射到卷积层特征图上,这样对于一张图像我们只需要提一次卷积层特征,然后将每个region proposal的卷积层特征输入到全连接层做后续操作。

    但现在的问题是每个region proposal的尺度不一样,而全连接层输入必须是固定的长度,所以直接这样输入全连接层肯定是不行的。SPP Net恰好可以解决这个问题。
     

    3.2 SPP Net

    SPP:Spatial Pyramid Pooling(空间金字塔池化)

    SPP-Net是出自2015年发表在IEEE上的论文-《Spatial Pyramid Pooling in Deep ConvolutionalNetworks for Visual Recognition》。

    众所周知,CNN一般都含有卷积部分和全连接部分,其中,卷积层不需要固定尺寸的图像,而全连接层是需要固定大小的输入。


    所以当全连接层面对各种尺寸的输入数据时,就需要对输入数据进行crop(crop就是从一个大图扣出网络输入大小的patch,比如227×227),或warp(把一个边界框bounding box的内容resize成227×227)等一系列操作以统一图片的尺寸大小,比如224*224(ImageNet)、32*32(LenNet)、96*96等。

    所以才如你在上文中看到的,在R-CNN中,“因为取出的区域大小各自不同,所以需要将每个Region Proposal缩放(warp)成统一的227x227的大小并输入到CNN”。

    但warp/crop这种预处理,导致的问题要么被拉伸变形、要么物体不全,限制了识别精确度。没太明白?说句人话就是,一张16:9比例的图片你硬是要Resize成1:1的图片,你说图片失真不?

    SPP Net的作者Kaiming He等人逆向思考,既然由于全连接FC层的存在,普通的CNN需要通过固定输入图片的大小来使得全连接层的输入固定。那借鉴卷积层可以适应任何尺寸,为何不能在卷积层的最后加入某种结构,使得后面全连接层得到的输入变成固定的呢?

    这个“化腐朽为神奇”的结构就是spatial pyramid pooling layer。下图便是R-CNN和SPP Net检测流程的比较:



    它的特点有两个:
    1.结合空间金字塔方法实现CNNs的多尺度输入。
    SPP Net的第一个贡献就是在最后一个卷积层后,接入了金字塔池化层,保证传到下一层全连接层的输入固定。
    换句话说,在普通的CNN机构中,输入图像的尺寸往往是固定的(比如224*224像素),输出则是一个固定维数的向量。SPP Net在普通的CNN结构中加入了ROI池化层(ROI Pooling),使得网络的输入图像可以是任意尺寸的,输出则不变,同样是一个固定维数的向量。

    简言之,CNN原本只能固定输入、固定输出,CNN加上SSP之后,便能任意输入、固定输出。神奇吧?

    ROI池化层一般跟在卷积层后面,此时网络的输入可以是任意尺度的,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出则是固定维数的向量,然后给到全连接FC层。

    2.只对原图提取一次卷积特征
    在R-CNN中,每个候选框先resize到统一大小,然后分别作为CNN的输入,这样是很低效的。
    而SPP Net根据这个缺点做了优化:只对原图进行一次卷积计算,便得到整张图的卷积特征feature map,然后找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层,完成特征提取工作。

    如此这般,R-CNN要对每个区域计算卷积,而SPPNet只需要计算一次卷积,从而节省了大量的计算时间,比R-CNN有一百倍左右的提速。

     

    3.3 Fast R-CNN

    SPP Net真是个好方法,R-CNN的进阶版Fast R-CNN就是在R-CNN的基础上采纳了SPP Net方法,对R-CNN作了改进,使得性能进一步提高。

    R-CNN与Fast R-CNN的区别有哪些呢?
    先说R-CNN的缺点:即使使用了Selective Search等预处理步骤来提取潜在的bounding box作为输入,但是R-CNN仍会有严重的速度瓶颈,原因也很明显,就是计算机对所有region进行特征提取时会有重复计算,Fast-RCNN正是为了解决这个问题诞生的。

     

    与R-CNN框架图对比,可以发现主要有两处不同:一是最后一个卷积层后加了一个ROI pooling layer,二是损失函数使用了多任务损失函数(multi-task loss),将边框回归Bounding Box Regression直接加入到CNN网络中训练(关于什么是边框回归,请参看七月在线APP题库大题查看深度学习分类下第56题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2139)。

    (1) ROI pooling layer实际上是SPP-NET的一个精简版,SPP-NET对每个proposal使用了不同大小的金字塔映射,而ROI pooling layer只需要下采样到一个7x7的特征图。对于VGG16网络conv5_3有512个特征图,这样所有region proposal对应了一个7*7*512维度的特征向量作为全连接层的输入。

    换言之,这个网络层可以把不同大小的输入映射到一个固定尺度的特征向量,而我们知道,conv、pooling、relu等操作都不需要固定size的输入,因此,在原始图片上执行这些操作后,虽然输入图片size不同导致得到的feature map尺寸也不同,不能直接接到一个全连接层进行分类,但是可以加入这个神奇的ROI Pooling层,对每个region都提取一个固定维度的特征表示,再通过正常的softmax进行类型识别。

    (2) R-CNN训练过程分为了三个阶段,而Fast R-CNN直接使用softmax替代SVM分类,同时利用多任务损失函数边框回归也加入到了网络中,这样整个的训练过程是端到端的(除去Region Proposal提取阶段)。

    也就是说,之前R-CNN的处理流程是先提proposal,然后CNN提取特征,之后用SVM分类器,最后再做bbox regression,而在Fast R-CNN中,作者巧妙的把bbox regression放进了神经网络内部,与region分类和并成为了一个multi-task模型,实际实验也证明,这两个任务能够共享卷积特征,并相互促进。

    所以,Fast-RCNN很重要的一个贡献是成功的让人们看到了Region Proposal + CNN这一框架实时检测的希望,原来多类检测真的可以在保证准确率的同时提升处理速度,也为后来的Faster R-CNN做下了铺垫。

    画一画重点:
    R-CNN有一些相当大的缺点(把这些缺点都改掉了,就成了Fast R-CNN)。
    大缺点:由于每一个候选框都要独自经过CNN,这使得花费的时间非常多。
    解决:共享卷积层,现在不是每一个候选框都当做输入进入CNN了,而是输入一张完整的图片,在第五个卷积层再得到每个候选框的特征

    原来的方法:许多候选框(比如两千个)-->CNN-->得到每个候选框的特征-->分类+回归
    现在的方法:一张完整图片-->CNN-->得到每张候选框的特征-->分类+回归

    所以容易看见,Fast R-CNN相对于R-CNN的提速原因就在于:不过不像R-CNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。

    在性能上提升也是相当明显的:

     

    3.4 Faster R-CNN

    Fast R-CNN存在的问题:存在瓶颈:选择性搜索,找出所有的候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?

    解决:加入一个提取边缘的神经网络,也就说找到候选框的工作也交给神经网络来做了。

    所以,rgbd在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同时引入anchor box应对目标形状的变化问题(anchor就是位置和大小固定的box,可以理解成事先设置好的固定的proposal)。

    具体做法:
      • 将RPN放在最后一个卷积层的后面
      • RPN直接训练得到候选区域


    RPN简介:
      • 在feature map上滑动窗口
      • 建一个神经网络用于物体分类+框位置的回归
      • 滑动窗口的位置提供了物体的大体位置信息
      • 框的回归提供了框更精确的位置


    一种网络,四个损失函数;
      • RPN calssification(anchor good.bad)
      • RPN regression(anchor->propoasal)
      • Fast R-CNN classification(over classes)
      • Fast R-CNN regression(proposal ->box)

    速度对比

    Faster R-CNN的主要贡献就是设计了提取候选区域的网络RPN,代替了费时的选择性搜索selective search,使得检测速度大幅提高。

    最后总结一下各大算法的步骤:
    RCNN
    1.在图像中确定约1000-2000个候选框 (使用选择性搜索Selective Search)
    2.每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取 
    3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 
    4.对于属于某一类别的候选框,用回归器进一步调整其位置

    Fast R-CNN
    1.在图像中确定约1000-2000个候选框 (使用选择性搜索Selective Search)
    2.对整张图片输进CNN,得到feature map
    3.找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层
    4.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 
    5.对于属于某一类别的候选框,用回归器进一步调整其位置

    Faster R-CNN
    1.对整张图片输进CNN,得到feature map
    2.卷积特征输入到RPN,得到候选框的特征信息
    3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 
    4.对于属于某一类别的候选框,用回归器进一步调整其位置

    简言之,即如本文开头所列
    R-CNN(Selective Search + CNN + SVM)
    SPP-net(ROI Pooling)
    Fast R-CNN(Selective Search + CNN + ROI)
    Faster R-CNN(RPN + CNN + ROI)

    总的来说,从R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN一路走来,基于深度学习目标检测的流程变得越来越精简,精度越来越高,速度也越来越快。可以说基于Region Proposal的R-CNN系列目标检测方法是当前目标检测技术领域最主要的一个分支。

     

    四、基于深度学习的回归方法

    4.1 YOLO (CVPR2016, oral)

    (You Only Look Once: Unified, Real-Time Object Detection)

    Faster R-CNN的方法目前是主流的目标检测方法,但是速度上并不能满足实时的要求。YOLO一类的方法慢慢显现出其重要性,这类方法使用了回归的思想,利用整张图作为网络的输入,直接在图像的多个位置上回归出这个位置的目标边框,以及目标所属的类别。
     

    我们直接看上面YOLO的目标检测的流程图:

    (1) 给个一个输入图像,首先将图像划分成7*7的网格
    (2) 对于每个网格,我们都预测2个边框(包括每个边框是目标的置信度以及每个边框区域在多个类别上的概率)
    (3) 根据上一步可以预测出7*7*2个目标窗口,然后根据阈值去除可能性比较低的目标窗口,最后NMS去除冗余窗口即可(关于什么是非极大值抑制NMS,请参看七月在线APP题库大题查看深度学习分类下第58题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2141)。

    可以看到整个过程非常简单,不再需要中间的Region Proposal找目标,直接回归便完成了位置和类别的判定。


    小结:YOLO将目标检测任务转换成一个回归问题,大大加快了检测的速度,使得YOLO可以每秒处理45张图像。而且由于每个网络预测目标窗口时使用的是全图信息,使得false positive比例大幅降低(充分的上下文信息)。

    但是YOLO也存在问题:没有了Region Proposal机制,只使用7*7的网格回归会使得目标不能非常精准的定位,这也导致了YOLO的检测精度并不是很高。
     

    4.2 SSD 

    (SSD: Single Shot MultiBox Detector)

    上面分析了YOLO存在的问题,使用整图特征在7*7的粗糙网格内回归对目标的定位并不是很精准。那是不是可以结合Region Proposal的思想实现精准一些的定位?SSD结合YOLO的回归思想以及Faster R-CNN的anchor机制做到了这点。



    上图是SSD的一个框架图,首先SSD获取目标位置和类别的方法跟YOLO一样,都是使用回归,但是YOLO预测某个位置使用的是全图的特征,SSD预测某个位置使用的是这个位置周围的特征(感觉更合理一些)。

    那么如何建立某个位置和其特征的对应关系呢?可能你已经想到了,使用Faster R-CNN的anchor机制。如SSD的框架图所示,假如某一层特征图(图b)大小是8*8,那么就使用3*3的滑窗提取每个位置的特征,然后这个特征回归得到目标的坐标信息和类别信息(图c)。

    不同于Faster R-CNN,这个anchor是在多个feature map上,这样可以利用多层的特征并且自然的达到多尺度(不同层的feature map 3*3滑窗感受野不同)。
     

    小结:SSD结合了YOLO中的回归思想和Faster R-CNN中的anchor机制,使用全图各个位置的多尺度区域特征进行回归,既保持了YOLO速度快的特性,也保证了窗口预测的跟Faster R-CNN一样比较精准。SSD在VOC2007上mAP可以达到72.1%,速度在GPU上达到58帧每秒。

     

    主要参考及扩展阅读

    1 https://www.cnblogs.com/skyfsm/p/6806246.html,by @Madcola
    2 https://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=502841131&idx=1&sn=bb3e8e6aeee2ee1f4d3f22459062b814#rd
    3 https://zhuanlan.zhihu.com/p/27546796
    4 https://blog.csdn.net/v1_vivian/article/details/73275259
    5 https://blog.csdn.net/tinyzhao/article/details/53717136
    6 Spatial Pyramid Pooling in Deep Convolutional
    Networks for Visual Recognition,by Kaiming He等人
    7 https://zhuanlan.zhihu.com/p/24774302
    8 知乎专栏作者何之源新书《21个项目玩转深度学习——基于TensorFlow的实践详解》
    9 YOLO:https://blog.csdn.net/tangwei2014/article/details/50915317,https://zhuanlan.zhihu.com/p/24916786

    展开全文
  • Mask R-CNN是ICCV 2017的best paper,彰显了机器学习计算机视觉领域在2017年的最新成果。在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型...

       Mask R-CNN是ICCV 2017的best paper,彰显了机器学习计算机视觉领域在2017年的最新成果。在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型。Mask R-CNN就是典型的代表。本篇大作的一作是何凯明,在该篇论文发表的时候,何凯明已经去了FaceBook。我们先来看一下,Mask R-CNN取得了何等的成果。



       大家可以看到,在实例分割Mask R-CNN框架中,还是主要完成了三件事情:

       1) 目标检测,直接在结果图上绘制了目标框(bounding box)。

       2) 目标分类,对于每一个目标,需要找到对应的类别(class),区分到底是人,是车,还是其他类别。

       3) 像素级目标分割,在每个目标中,需要在像素层面区分,什么是前景,什么是背景。

       可是,在解析Mask R-CNN之前,笔者不得不告诉大家一个事实,Mask R-CNN是继承于Faster R-CNN (2016)的,Mask R-CNN只是在Faster R-CNN上面加了一个Mask Prediction Branch (Mask 预测分支),并且改良了ROI Pooling,提出了ROI Align。从统计数据来看,"Faster R-CNN"在Mask R-CNN论文的前三章中出现了二十余次,因此,如果不了解Ross Girshick和何凯明之前的工作,是很难弄懂Mask R-CNN的。所以,笔者在解析Mask R-CNN之前,先给大家分析一下Faster R-CNN。

       在给大家解析Faster R-CNN之前,笔者又要告诉大家,Faster R-CNN是继承于Fast R-CNN (2015),Fast R-CNN继承于R-CNN (2014)。因此,索性破釜沉舟,在本篇博文中,笔者就按照R-CNN, Fast R-CNN,Faster R-CNN再到Mask R-CNN的发展顺序全部解析。

       首先时间回到了2014年,在2014年,正是深度学习如火如荼的发展的第三年。在CVPR 2014年中Ross Girshick提出的R-CNN中,使用到了卷积神经网络来进行目标检测。下面笔者就来概述一下R-CNN是如何采用卷积神经网络进行目标检测的工作。


       首先模型输入为一张图片,然后在图片上提出了约2000个待检测区域,然后这2000个待检测区域一个一个地(串联方式)通过卷积神经网络提取特征,然后这些被提取的特征通过一个支持向量机(SVM)进行分类,得到物体的类别,并通过一个bounding box regression调整目标包围框的大小。下面,笔者简要概述一下R-CNN是怎么实现以上步骤的。

       首先在第一步提取2000个待检测区域的时候,是通过一个2012年提出的方法,叫做selective search。简单来说就是通过一些传统图像处理方法将图像分成若干块,然后通过一个SVM将属于同一目标的若干块拿出来。selective search的核心是一个SVM,架构如下所示:


       然后在第二步进行特征提取的时候,Ross直接借助了当时深度学习的最新成果AlexNet (2012)。那么,该网络是如何训练的呢?是直接在ImageNet上面训练的,也就是说,使用图像分类数据集训练了一个仅仅用于提取特征的网络。

       在第三步进行对目标的时候,使用了一个支持向量机(SVM),在训练这个支持向量机的时候,结合目标的标签(类别)与包围框的大小进行训练,因此,该支持向量机也是被单独训练的。

       在2014年R-CNN横空出世的时候,颠覆了以往的目标检测方案,精度大大提升。对于R-CNN的贡献,可以主要分为两个方面:

       1) 使用了卷积神经网络进行特征提取

       2) 使用bounding box regression进行目标包围框的修正

       但是,我们来看一下,R-CNN有什么问题:

       1) 耗时的selective search,对一帧图像,需要花费2s。

       2) 耗时的串行式CNN前向传播,对于每一个RoI,都需要经过一个AlexNet提特征,为所有的RoI提特征大约花费47s。

       3) 三个模块是分别训练的,并且在训练的时候,对于存储空间的消耗很大。

       那么,面对这种情势,Ross在2015年提出的Fast R-CNN进行了改进,下面我们来概述一下Fast R-CNN的解决方案:


       首先还是采用selective search提取2000个候选框,然后,使用一个神经网络对全图进行特征提取。接着,使用一个RoI Pooling Layer在全图特征上摘取每一个RoI对应的特征,再通过全连接层(FC Layer)进行分类与包围框的修正。Fast R-CNN的贡献可以主要分为两个方面:

       1) 取代R-CNN的串行特征提取方式,直接采用一个神经网络对全图提取特征(这也是为什么需要RoI Pooling的原因)。

       2) 除了selective search,其他部分都可以合在一起训练。

       可是,Fast R-CNN也有缺点,体现在耗时的selective search还是依旧存在。那么,如何改良这个缺陷呢?发表于2016年的Faster R-CNN进行了如下创新:

       取代selective search,直接通过一个Region Proposal Network (RPN)生成待检测区域,这么做,在生成RoI区域的时候,时间也就从2s缩减到了10ms。我们来看一下Faster R-CNN是怎么做的。


       首先使用共享的卷积层为全图提取特征,然后将得到的feature maps送入RPN,RPN生成待检测框(指定RoI的位置)并对RoI的包围框进行第一次修正。之后就是Fast R-CNN的架构了,RoI Pooling Layer根据RPN的输出在feature map上面选取每个RoI对应的特征,并将维度置为定值。最后,使用全连接层(FC Layer)对框进行分类,并且进行目标包围框的第二次修正。尤其注意的是,Faster R-CNN真正实现了端到端的训练(end-to-end training)

       要理解Mask R-CNN,只有先理解Faster R-CNN。因此,笔者根据Faster R-CNN的架构(Faster R-CNN的ZF model的train.prototxt),画了一个结构图,如下所示:


       如上图所示,Faster R-CNN的结构主要分为三大部分,第一部分是共享的卷积层-backbone,第二部分是候选区域生成网络-RPN,第三部分是对候选区域进行分类的网络-classifier。其中,RPN与classifier部分均对目标框有修正。classifier部分是原原本本继承的Fast R-CNN结构。我们下面来简单看看Faster R-CNN的各个模块。

       首先来看看RPN的工作原理:


       简单地说,RPN依靠一个在共享特征图上滑动的窗口,为每个位置生成9种预先设置好长宽比与面积的目标框(文中叫做anchor)。这9种初始anchor包含三种面积(128×128,256×256,512×512),每种面积又包含三种长宽比(1:1,1:2,2:1)。示意图如下所示:


       由于共享特征图的大小约为40×60,RPN生成的初始anchor的总数约为20000个(40×60×9)。对于生成的anchor,RPN要做的事情有两个,第一个是判断anchor到底是前景还是背景,意思就是判断这个anchor到底有没有覆盖目标,第二个是为属于前景的anchor进行第一次坐标修正。对于前一个问题,Faster R-CNN的做法是使用SoftmaxLoss直接训练,在训练的时候排除掉了超越图像边界的anchor;对于后一个问题,采用SmoothL1Loss进行训练。那么,RPN怎么实现呢?这个问题通过RPN的本质很好求解,RPN的本质是一个树状结构,树干是一个3×3的卷积层,树枝是两个1×1的卷积层,第一个1×1的卷积层解决了前后景的输出,第二个1×1的卷积层解决了边框修正的输出。来看看在代码中是怎么做的:


       从如上代码中可以看到,对于RPN输出的特征图中的每一个点,一个1×1的卷积层输出了18个值,因为是每一个点对应9个anchor,每个anchor有一个前景分数和一个背景分数,所以9×2=18。另一个1×1的卷积层输出了36个值,因为是每一个点对应9个anchor,每个anchor对应了4个修正坐标的值,所以9×4=36。那么,要得到这些值,RPN网络需要训练。在训练的时候,就需要对应的标签。那么,如何判定一个anchor是前景还是背景呢?文中做出了如下定义:如果一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。类似地,如果这个anchor与ground truth的IoU在0.3以下,那么这个anchor就算背景(negative)。在作者进行RPN网络训练的时候,只使用了上述两类anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。在训练anchor属于前景与背景的时候,是在一张图中,随机抽取了128个前景anchor与128个背景anchor。

       在上一段中描述了前景与背景分类的训练方法,本段描述anchor边框修正的训练方法。边框修正主要由4个值完成,tx,ty,th,tw。这四个值的意思是修正后的框在anchor的x和y方向上做出平移(由tx和ty决定),并且长宽各自放大一定的倍数(由th和ty决定)。那么,如何训练网络参数得到这四个值呢?Fast R-CNN给出了答案,采用SmoothL1loss进行训练,具体可以描述为:


       到这里有个问题,就是不是对于所有的anchor,都需要进行anchor包围框修正的参数训练,只是对positive的anchors有这一步。因此,在训练RPN的时候,只有对128个随机抽取的positive anchors有这一步训练。因此,训练RPN的损失函数可以写成:


       在这里Lreg就是上面的Lloc,λ被设置为10,Ncls为256,Nreg为2400。这样设置的话,RPN的两部分loss值能保持平衡。

       到这里RPN就解析完毕了,下面我们来看看后面的classifier,但是在介绍classifier之前,我们先来看看RoI Pooling到底做了什么?

       首先第一个问题是为什么需要RoI Pooling?答案是在Fast R-CNN中,特征被共享卷积层一次性提取。因此,对于每个RoI而言,需要从共享卷积层上摘取对应的特征,并且送入全连接层进行分类。因此,RoI Pooling主要做了两件事,第一件是为每个RoI选取对应的特征,第二件事是为了满足全连接层的输入需求,将每个RoI对应的特征的维度转化成某个定值。RoI Pooling示意图如下所示:


       如上图所示,对于每一个RoI,RoI Pooling Layer将其对应的特征从共享卷积层上拿出来,并转化成一样的大小(6×6)。

       在RoI Pooling Layer之后,就是Fast R-CNN的分类器和RoI边框修正训练。分类器主要是分这个提取的RoI具体是什么类别(人,车,马等等),一共C+1类(包含一类背景)。RoI边框修正和RPN中的anchor边框修正原理一样,同样也是SmoothL1 Loss,值得注意的是,RoI边框修正也是对于非背景的RoI进行修正,对于类别标签为背景的RoI,则不进行RoI边框修正的参数训练。对于分类器和RoI边框修正的训练,可以公式描述如下:


       上式中u>=1表示RoI边框修正是对于非背景的RoI而言的,实验中,上式的λ取1。

       在训练分类器和RoI边框修正时,步骤如下所示:

       1) 首先通过RPN生成约20000个anchor(40×60×9)。

       2) 对20000个anchor进行第一次边框修正,得到修订边框后的proposal。

       3) 对超过图像边界的proposal的边进行clip,使得该proposal不超过图像范围。

       4) 忽略掉长或者宽太小的proposal。

       5) 将所有proposal按照前景分数从高到低排序,选取前12000个proposal。

       6) 使用阈值为0.7的NMS算法排除掉重叠的proposal。

       7) 针对上一步剩下的proposal,选取前2000个proposal进行分类和第二次边框修正。

       总的来说,Faster R-CNN的loss分两大块,第一大块是训练RPN的loss(包含一个SoftmaxLoss和SmoothL1Loss),第二大块是训练Fast R-CNN中分类器的loss(包含一个SoftmaxLoss和SmoothL1Loss),Faster R-CNN的总的loss函数描述如下:


       然后,对于Faster R-CNN的训练方式有三种,可以被描述如下:

       1) RPN和Fast R-CNN交替训练,这种方式也是作者采用的方式。

       2) 近似联合RPN和Fast R-CNN的训练,在训练时忽略掉了RoI边框修正的误差,也就是说只对anchor做了边框修订,这也是为什么叫"近似联合"的原因。

       3) 联合RPN和Fast R-CNN的训练。

       对于作者采用的交替训练的方式,步骤如下:

       1) 使用在ImageNet上预训练的模型初始化共享卷积层并训练RPN

       2) 使用上一步得到的RPN参数生成RoI proposal。再使用ImageNet上预训练的模型初始化共享卷积层,训练Fast R-CNN部分(分类器和RoI边框修订)。

       3) 将训练后的共享卷积层参数固定,同时将Fast R-CNN的参数固定,训练RPN。(从这一步开始,共享卷积层的参数真正被两大块网络共享)

       4) 同样将共享卷积层参数固定,并将RPN的参数固定,训练Fast R-CNN部分。

       Faster R-CNN的测试流程和训练流程挺相似,描述如下:

       1) 首先通过RPN生成约20000个anchor(40×60×9)通过RPN

       2) 对20000个anchor进行第一次边框修正,得到修订边框后的proposal。

       3) 对超过图像边界的proposal的边进行clip,使得该proposal不超过图像范围。

       4) 忽略掉长或者宽太小的proposal。

       5) 将所有proposal按照前景分数从高到低排序,选取前6000个proposal。

       6) 使用阈值为0.7的NMS算法排除掉重叠的proposal。

       7) 针对上一步剩下的proposal,选取前300个proposal进行分类和第二次边框修正。

       到这里,Faster R-CNN就介绍完毕了。接下来到了Mask R-CNN,我们来看看RoI Pooling出了什么问题:

       问题1:从输入图上的RoI到特征图上的RoI feature,RoI Pooling是直接通过四舍五入取整得到的结果。

       这一点可以在代码中印证:


       可以看到直接用round取的值,这样会带来什么坏处呢?就是RoI Pooling过后的得到的输出可能和原图像上的RoI对不上,如下图所示:


       右图中蓝色部分表示包含了轿车主体的的信息的方格,RoI Pooling Layer的四舍五入取整操作导致其进行了偏移。

       问题2:再将每个RoI对应的特征转化为固定大小的维度时,又采用了取整操作。在这里笔者举例讲解一下RoI Pooling的操作:


       在从RoI得到对应的特征图时,进行了问题1描述的取整,在得到特征图后,如何得到一个6×6的全连接层的输入呢?RoI Pooling这样做:将RoI对应的特征图分成6×6块,然后直接从每块中找到最大值。在上图中的例子中,比如原图上的的RoI大小是280×480,得到对应的特征图是18×30。将特征图分成6块,每块大小是3×5,然后在每一块中分别选择最大值放入6×6的对应区域中。在将特征图分块的时候,又用到了取整,这点同样可以在代码中得到佐证:


       这种取整操作(在Mask R-CNN中被称为quantization)对RoI分类影响不大,可是对逐像素的预测目标是有害的,因为对每个RoI取得的特征并没有与RoI对齐。因此,Mask R-CNN对RoI Pooling做了改进并提出了RoI Align。

       RoI Align的主要创新点是,针对问题1,不再进行取整操作。针对问题2,使用双线性插值来更精确地找到每个块对应的特征。总的来说,RoI Align的作用主要就是剔除了RoI Pooling的取整操作,并且使得为每个RoI取得的特征能够更好地对齐原图上的RoI区域。

       下图阐述了Mask R-CNN的Mask branch:


       在Mask R-CNN中的RoI Align之后有一个"head"部分,主要作用是将RoI Align的输出维度扩大,这样在预测Mask时会更加精确。在Mask Branch的训练环节,作者没有采用FCN式的SoftmaxLoss,反而是输出了K个Mask预测图(为每一个类都输出一张),并采用average binary cross-entropy loss训练,当然在训练Mask branch的时候,输出的K个特征图中,也只是对应ground truth类别的那一个特征图对Mask loss有贡献。

       Mask R-CNN的训练损失函数可以描述为:


       在上式中,Lbox和Lmask都是对positive RoI才会起作用的。

       在Mask R-CNN中,相较于Faster R-CNN还有些略微的调整,比如positive RoI被定义成了与Ground truth的IoU大于0.5的(Faster R-CNN中是0.7)。太过于细节的东西本篇博文不再赘述,详情参见Mask R-CNN中的Implementation Details。

       到这里再将Mask R-CNN和FCIS做个比较,首先两者的相同点是均继承了Faster R-CNN的RPN部分不同点是对于FCIS,预测mask和分类是共享的参数。而Mask R-CNN则是各玩各的,两个任务各自有各自的可训练参数。对于这一点,Mask R-CNN论文里还专门作了比较,显示对于预测mask和分类如果使用共享的特征图对于某些重叠目标可能会出现问题。


       Mask R-CNN的实验取得了很好的效果,达到甚至超过了state-of-the-art的水平。不过训练代价也是相当大的,需要8块GPU联合训练。


       Mask R-CNN的实验非常详细,还做了很多对比实验,比如说改换网络深度,在训练mask branch时的误差种类,将RoI Align同RoI Pooling和RoI Warping进行比较,改变预测mask的方式(FCN和全连接层)等,详情请参见Mask R-CNN的实验部分。





       到这里Mask R-CNN介绍就接近尾声了,笔者还想说一些自己的思考与感想:

       1) 可继承工作的充分体现。大家看到Mask R-CNN的结构相当复杂,实际上是继承了大量之前的工作。首先bounding box regression在2014年的R-CNN中就出现过。Mask R-CNN的主要创新点RoI Align改良于RoI Pooling,而RoI Pooling是在2015年的Fast R-CNN中提出的。对于RPN的应用,更是直接继承了2016年的Faster R-CNN。值得一提的是,上述的每一篇文章,都是颠覆目标检测领域计算架构的杰出作品。

       2)集成的工作。还是那句老话,到了2017-2018年,随着深度学习的高速发展,单任务模型已经逐渐被抛弃。取而代之的是更集成,更综合,更强大的多任务模型。Mask R-CNN就是其中的代表。

       3)引领潮流。再次向何凯明和Ross Girshick致敬,他们的实力引领了目标检测领域的发展,因此无论他们在哪,无论是在微软还是FaceBook,他们的idea和作品都被非常多的人应用或者继承。

       欢迎阅读笔者后续博客,各位读者朋友的支持与鼓励是我最大的动力!


    written by jiong

    鸿爪踏雪泥,还是来得及。

    展开全文
  • Fast R-CNN

    2020-10-20 19:59:23
    Fast R-CNN2.1 整体流程2.2 RoI pooling层和SPP层的区别:2.3 多任务损失函数3. 实验4. 贡献 论文:Fast R-CNN 来源:ICCV 2015 1. Motivation 2. Fast R-CNN 2.1 整体流程 产生候选区域:使用Selective Search找...

    论文:Fast R-CNN
    来源:ICCV 2015

    1. Motivation

    • Fast R-CNN旨在实现端到端训练。

    2. Fast R-CNN

    2.1 整体流程

    1. 产生候选区域:使用Selective Search找出输入图片中可能存在目标的侯选区域region proposals
    2. CNN提取特征:使用一个CNN对整张图像进行特征提取
    3. 区域映射:将候选区域大小映射到特征层上
    4. RoI pooling:将尺寸不同的RoI特征图pool至相同的固定大小,展平后再经过几层FC层,得到RoI特征向量。
    5. softax多分类及边界框回归:用全连接层做分类和回归
    6. NMS:剔除重叠建议框,得到该列即该类中得分最高的一些建议框。

    在这里插入图片描述

    注:步骤1,2,3属于SPPnet,步骤4借鉴SPP层,步骤5是Fast R-CNN新提出来的步骤。

    2.2 RoI pooling层和SPP层的区别:

    • RoI pooling层是SPP层的一个特例。SPP层先产生多个大小不同的特征图,再分别将特征图展平后拼接起来得到固定大小的特征向量,而RoI pooling借用SPP层构造池化核的方法,只产生一个固定大小的特征图(e.g. 7×77\times7)。

    2.3 多任务损失函数

    • 对于每一个RoI,网络将输出K+1K+1维的softmax分类概率p=(p0,p1,...,pK)p=(p_0,p_1,...,p_K)和4*K维的边界框偏移量(每一个前景类分别对应一个4维的边界框偏移量tk=(txk,tyk,twk,thk)t^k =(t_x^k,t_y^k,t_w^k,t_h^k)tkt^k的构建与R-CNN和SPPnet一样)。
    • 假设RoI的真实类别为uu,边界框回归的训练标签为v=(vx,vy,vw,vh)v= (v_x,v_y,v_w,v_h),则多任务损失函数为:
      L(p,u,tu,v)=Lcls(p,u)+λ[u1]Lloc(tu,v)L(p,u,t^u,v)=L_{cls}(p,u)+\lambda[u\geq 1]L_{loc}(t^u,v)Lcls(p,u)=log(pu)L_{cls}(p,u)=-log(p_u)在这里插入图片描述
      使用smoothL1损失,是为了减小对异常点的敏感程度。回归问题的偏移量可以是无界的,R-CNN和SPPnet使用L2损失可能会导致梯度爆炸,使用smoothL1则不会。
      参考:https://blog.csdn.net/weixin_41940752/article/details/93159710

    为什么SPPnet无法更新在SPP层之前的卷积层参数,而Fast R-CNN却可以更新在RoI pooling层之前的卷积层参数?这体现了端到端训练的好处。

    • SPPnet的训练步骤与R-CNN一样,先预训练+微调backbone,然后固定backbone,利用backbone提取特征,并训练SVM和边界框回归器。显然在训练SVM和边界框回归器时,SPP层之前的卷积层参数是不变的。
    • Fast R-CNN采用端到端训练后,可以同时更新backbone,分类分支和回归分支的参数。

    2.4 新mini-batch采样策略

    • SPPnet在训练时,采用了RCNN的mini-batch采样策略,即每次都从N=128N=128张图像各选择一个proposal,然后由这128个proposal组成了mini-batch。由于每个RoI的感受野都非常大,通常会覆盖整个输入图像,所以反向传播更新参数的效率是非常低的。
    • Fast R-CNN提出了新的mini-batch采样策略,即每次只从N=2N=2张图像选择proposal,每张图像选择64个proposal,最终组成batch size=128的mini-batch。对少量图像提取多个RoI,减小了特征提取的时间,减小了训练时间(比SPPnet大约快了64倍)

    3. 实验

    (1)多任务训练的效果比分段训练更好吗?
    在这里插入图片描述
    S:AlexNet; M:VGG_CNN_M_1024(which has the same depth as S, but is wider);L:VGG16

    • 每组的第一列:训练和测试都只用分类分支。
    • 每组的第二列:训练时,分类分支和归回分支联合训练;测试时,只用分类分支。
      结论:回归分支也可以提高分类准确度(个人解释是,在存在遮挡时,回归分支可以指引分类分支关注正确的目标区域)
    • 每组的第三列:分段训练:固定第一列训练后得到的模型参数,添加回归分支并进行训练。测试时,同时采用分类分支和回归分支。
      结论:测试时,使用回归分支可以提高目标检测mAP
    • 每组的第四列:训练时,分类分支和归回分支联合训练;测试时,同时采用分类分支和回归分支。
      结论:对比第三、四列,发现多任务训练的效果比分段训练更好。(比第三列好,是因为消除了分类和回归的差异。)

    (2)softmax比SVMs效果更好吗?
    在这里插入图片描述
    实验结论:softmax比SVMs效果稍好一点点,使用softmax的好处是:可以方便实现端到端的训练。

    4. 贡献

    1. 实现了除SS提取region proposal外的端到端训练;
    2. 使用多任务损失,进行多任务联合训练。
    展开全文
  • 一文读懂目标检测:R-CNNFast R-CNN、Faster R-CNN、YOLO、SSD。传统的目标检测算法、候选区域/窗 + 深度学习分类
  • Fast R-CNN论文详解

    万次阅读 多人点赞 2016-09-07 22:07:52
    废话不多说,上车吧,少年paper链接:Fast R-CNN &创新点 规避R-CNN中冗余的特征提取操作,只对整张图像全区域进行一次特征提取; 用RoI pooling层取代最后一层max pooling层,同时引入建议框信息,提取相应建议框...

    废话不多说,上车吧,少年

    paper链接Fast R-CNN


    **
    1. 规避R-CNN中冗余的特征提取操作,只对整张图像全区域进行一次特征提取;

    2. 用RoI pooling层取代最后一层max pooling层,同时引入建议框信息,提取相应建议框特征;

    3. Fast R-CNN网络末尾采用并行的不同的全连接层,可同时输出分类结果和窗口回归结果,实现了end-to-end的多任务训练【建议框提取除外】,也不需要额外的特征存储空间【R-CNN中这部分特征是供SVM和Bounding-box regression进行训练的】;

    4. 采用SVD对Fast R-CNN网络末尾并行的全连接层进行分解,减少计算复杂度,加快检测速度。

    打个广告:目前博主正在字节跳动奋斗,欢迎各位一起来共事
    【内推码】:HVWUV6Y
    【投递地址】:https://job.bytedance.com/
    


    **
    1. R-CNN网络训练、测试速度都很慢:R-CNN网络中,一张图经由selective search算法提取约2k个建议框【这2k个建议框大量重叠】,而所有建议框变形后都要输入AlexNet CNN网络提取特征【即约2k次特征提取】,会出现上述重叠区域多次重复提取特征,提取特征操作冗余;

    2. R-CNN网络训练、测试繁琐:R-CNN网络训练过程分为ILSVRC 2012样本下有监督预训练、PASCAL VOC 2007该特定样本下的微调、20类即20个SVM分类器训练、20类即20个Bounding-box 回归器训练,该训练流程繁琐复杂;同理测试过程也包括提取建议框、提取CNN特征、SVM分类和Bounding-box 回归等步骤,过于繁琐;

    3. R-CNN网络训练需要大量存储空间:20类即20个SVM分类器和20类即20个Bounding-box 回归器在训练过程中需要大量特征作为训练样本,这部分从CNN提取的特征会占用大量存储空间;

    4. R-CNN网络需要对建议框进行形变操作后【形变为227×227 size】再输入CNN网络提取特征,其实像AlexNet CNN等网络在提取特征过程中对图像的大小并无要求,只是在提取完特征进行全连接操作的时候才需要固定特征尺寸【R-CNN中将输入图像形变为227×227可正好满足AlexNet CNN网络最后的特征尺寸要求】,然后才使用SVM分类器分类,R-CNN需要进行形变操作的问题在Fast R-CNN已经不存在,具体见下。



    **

    <font face="微软雅黑"color=#0077ff size=4>。测试过程
    Fast R-CNN的网络结构如下图所示。

    这里写图片描述

    1. 任意size图片输入CNN网络,经过若干卷积层与池化层,得到特征图;

    2. 在任意size图片上采用selective search算法提取约2k个建议框;

    3. 根据原图中建议框到特征图映射关系,在特征图中找到每个建议框对应的特征框【深度和特征图一致】,并在RoI池化层中将每个特征框池化到H×W【VGG-16网络是7×7】的size;

    4. 固定H×W【VGG-16网络是7×7】大小的特征框经过全连接层得到固定大小的特征向量;

    5. 第4步所得特征向量经由各自的全连接层【由SVD分解实现】,分别得到两个输出向量:一个是softmax的分类得分,一个是Bounding-box窗口回归;

    6. 利用窗口得分分别对每一类物体进行非极大值抑制剔除重叠建议框,最终得到每个类别中回归修正后的得分最高的窗口。


    <font face="微软雅黑"color=#0077ff size=4>。解释分析

    1. <font face="微软雅黑"color=#ff0000 size=3>整个测试过程为什么可以只进行一次CNN特征提取操作?
      先看R-CNN网络,它首先采用selective search算法提取约2k个建议框,并对所有建议框都进行了CNN特征提取操作,会出现重叠区域多次重复提取特征,这些操作非常耗时、耗空间。事实上我们并不需要对每个建议框都进行CNN特征提取操作,只需要对原始的整张图片进行1次CNN特征提取操作即可,因为selective search算法提取的建议框属于整张图片,因此对整张图片提取出特征图后,再找出相应建议框在特征图中对应的区域,这样就可以避免冗余的特征提取操作,节省大量时间。

    2. <font face="微软雅黑"color=#ff0000 size=3>为什么要将每个建议框对应的特征框池化到H×W 的size?如何实现?
      问题4中已经指出像AlexNet CNN等网络在提取特征过程中对图像的大小并无要求,只是在提取完特征进行全连接操作的时候才需要固定特征尺寸,利用这一点,Fast R-CNN可输入任意size图片,并在全连接操作前加入RoI池化层,将建议框对应特征图中的特征框池化到H×W 的size,以便满足后续操作对size的要求;

    具体如何实现呢?
    首先假设建议框对应特征图中的特征框大小为h×w,将其划分H×W个子窗口,每个子窗口大小为h/H×w/W,然后对每个子窗口采用max pooling下采样操作,每个子窗口只取一个最大值,则特征框最终池化为H×W的size【特征框各深度同理】,这将各个大小不一的特征框转化为大小统一的数据输入下一层。

    1. <font face="微软雅黑"color=#ff0000 size=3>为什么要采用SVD分解实现Fast R-CNN网络中最后的全连接层?具体如何实现?
      图像分类任务中,用于卷积层计算的时间比用于全连接层计算的时间多,而在目标检测任务中,selective search算法提取的建议框比较多【约2k】,几乎有一半的前向计算时间被花费于全连接层,就Fast R-CNN而言,RoI池化层后的全连接层需要进行约2k次【每个建议框都要计算】,因此在Fast R-CNN中可以采用SVD分解加速全连接层计算;

    具体如何实现呢?
    ① 物体分类和窗口回归都是通过全连接层实现的,假设全连接层输入数据为x,输出数据为y,全连接层参数为W,尺寸为u×v,那么该层全连接计算为:y=Wxy=Wx

    计算复杂度为u×v;

    ② 若将W进行SVD分解,并用前t个特征值近似代替,即:W=UVTU(u,1:t)(1:t,1:t)V(v,1:t)TW=U\sum V^T\approx U(u,1:t)\cdot \sum(1:t,1:t)\cdot V(v,1:t)^T

    那么原来的前向传播分解成两步:y=Wx=U(VT)x=Uzy=Wx=U\cdot(\sum\cdot V^T)\cdot x=U\cdot z

    计算复杂度为u×t+v×t,若t<min(u,v)t<min(u,v),则这种分解会大大减少计算量;

    在实现时,相当于把一个全连接层拆分为两个全连接层,第一个全连接层不含偏置,第二个全连接层含偏置;实验表明,SVD分解全连接层能使mAP只下降0.3%的情况下提升30%的速度,同时该方法也不必再执行额外的微调操作。

    这里写图片描述

    1. <font face="微软雅黑"color=#ff0000 size=3>文中仅采用selective search算法提取约2k个候选区域,那候选区域越多越好吗?
      文中利用selective search算法提取1k~10k中10种数目【1k,2k…】的候选区域进行训练测试,发现随着候选区域个数的增加,mAP成先增加后缓慢下滑的趋势,这表明更多的候选区域会有损精度;与此同时,作者也做了召回率【所谓召回率即候选区域为真的窗口与Ground Truth的比值【IoU大于阈值即为真】】分析实验,发现随着候选区域个数的增加,召回率并没有和mAP成很好的相关性,而是一直不断增加,也就是说更高的召回率并不意味着更高的mAP;

    文中也以selective search算法提取的2k个候选区域为基础,每次增加1000 × {2, 4, 6, 8, 10, 32, 45}个密集box【滑动窗口方法】进行训练测试,发现mAP比只有selective search方法的2k候选区域下降幅度更大,最终达到53%。

    1. <font face="微软雅黑"color=#ff0000 size=3>如何处理尺度不变性问题?即如何使24×24和1080×720的车辆同时在一个训练好的网络中都能正确识别?
      文中提及两种方式处理:brute-force(单一尺度)和image pyramids(多尺度)。单一尺度直接在训练和测试阶段将image定死为某种scale,直接输入网络训练就好,然后期望网络自己能够学习到scale-invariance的表达;多尺度在训练阶段随机从图像金字塔【缩放图片的scale得到,相当于扩充数据集】中采样训练,测试阶段将图像缩放为金字塔中最为相似的尺寸进行测试;

    可以看出,多尺度应该比单一尺度效果好。作者在5.2节对单一尺度和多尺度分别进行了实验,不管哪种方式下都定义图像短边像素为s,单一尺度下s=600【维持长宽比进行缩放】,长边限制为1000像素;多尺度s={480,576,688,864,1200}【维持长宽比进行缩放】,长边限制为2000像素,生成图像金字塔进行训练测试;实验结果表明AlexNet【S for small】、VGG_CNN_M_1024【M for medium】下单一尺度比多尺度mAP差1.2%~1.5%,但测试时间上却快不少,VGG-16【L for large】下仅单一尺度就达到了66.9%的mAP【由于GPU显存限制多尺度无法实现】,该实验证明了深度神经网络善于直接学习尺度不变形,对目标的scale不敏感。
    6. <font face="微软雅黑"color=#ff0000 size=3>为什么不沿用R-CNN中的形式继续采用SVM进行分类?
    为什么R-CNN中采用SVM分类而不直接用CNN网络输出端进行分类已经在R-CNN博客中说明,针对Fast R-CNN,文中分别进行实验并对比了采用SVM和采用softmax的mAP结果,不管AlexNet【S for small】、VGG_CNN_M_1024【M for medium】、VGG-16【L for large】中任意网络,采用softmax的mAP都比采用SVM的mAP高0.1%~0.8%,这是由于softmax在分类过程中引入了类间竞争,分类效果更好;

    Fast R-CNN去掉了SVM这一步,所有的特征都暂存在显存中,就不需要额外的磁盘空间。


    <font face="微软雅黑"color=#0077ff size=4>。训练过程

    1. <font face="微软雅黑"color=#000000 size=3>有监督预训练

      样本 来源
      正样本 ILSVRC 20XX
      负样本 ILSVRC 20XX

      ILSVRC 20XX样本只有类别标签,有1000种物体; 文中采用AlexNet【S for small】、VGG_CNN_M_1024【M for medium】、VGG-16【L for large】这三种网络分别进行训练测试,下面仅以VGG-16举例。
    2. <font face="微软雅黑"color=#000000 size=3>特定样本下的微调

      样本 比例 来源
      正样本 25% 与某类Ground Truth相交IoU∈[0.5,1]的候选框
      负样本 75% 与20类Ground Truth相交IoU中最大值∈[0.1,0.5)的候选框

      PASCAL VOC数据集中既有物体类别标签,也有物体位置标签,有20种物体; 正样本仅表示前景,负样本仅表示背景; 回归操作仅针对正样本进行; 该阶段训练集扩充方式:50%概率水平翻转;

      微调前,需要对有监督预训练后的模型进行3步转化:
      ①RoI池化层取代有监督预训练后的VGG-16网络最后一层池化层;
      ②两个并行层取代上述VGG-16网络的最后一层全连接层和softmax层,并行层之一是新全连接层1+原softmax层1000个分类输出修改为21个分类输出【20种类+背景】,并行层之二是新全连接层2+候选区域窗口回归层,如下图所示;
      ③上述网络由原来单输入:一系列图像修改为双输入:一系列图像和这些图像中的一系列候选区域;

    这里写图片描述

    <font color=#ff0000>SGD超参数选择</font>:
    除了修改增加的层,原有的层参数已经通过预训练方式初始化;
    用于分类的全连接层以均值为0、标准差为0.01的高斯分布初始化,用于回归的全连接层以均值为0、标准差为0.001的高斯分布初始化,偏置都初始化为0;
    针对PASCAL VOC 2007和2012训练集,前30k次迭代全局学习率为0.001,每层权重学习率为1倍,偏置学习率为2倍,后10k次迭代全局学习率更新为0.0001;
    动量设置为0.9,权重衰减设置为0.0005。
    

    <font face="微软雅黑"color=#0077ff size=4>。解释分析

    1. <font face="微软雅黑"color=#ff0000 size=3>Fast R-CNN如何采样进行SGD训练,和R-CNN、SPPnet中SGD采样方式有什么区别和优势?
      R-CNN和SPPnet中采用RoI-centric sampling:从所有图片的所有候选区域中均匀取样,这样每个SGD的mini-batch中包含了不同图像的样本,不同图像之间不能共享卷积计算和内存,运算开销大;
      Fast R-CNN中采用image-centric sampling: mini-batch采用层次采样,即先对图像采样【N个】,再在采样到的图像中对候选区域采样【每个图像中采样R/N个,一个mini-batch共计R个候选区域样本】,同一图像的候选区域卷积共享计算和内存,降低了运算开销;
      image-centric sampling方式采样的候选区域来自于同一图像,相互之间存在相关性,可能会减慢训练收敛的速度,但是作者在实际实验中并没有出现这样的担忧,反而使用N=2,R=128的RoI-centric sampling方式比R-CNN收敛更快。

    这里解释一下为什么SPPnet不能更新spatial pyramid pooling层前面的卷积层,而只能更新后面的全连接层?
    博主没有看过SPPnet的论文,有网友解释说卷积特征是线下计算的,从而无法在微调阶段反向传播误差;另一种解释是,反向传播需要计算每一个RoI感受野的卷积层梯度,通常所有RoI会覆盖整个图像,如果用RoI-centric sampling方式会由于计算too much整幅图像梯度而变得又慢又耗内存。

    1. <font face="微软雅黑"color=#ff0000 size=3>训练数据越多效果越好吗?

      实验 训练集 测试集 mAP
      实验1 VOC 2007训练集 VOC 2007测试集 66.9%
      实验1 VOC 2007+VOC 2012训练集 VOC 2007测试集 70.0%
      实验2 VOC 2012训练集 VOC 2010测试集 66.1%
      实验2 VOC 2007+VOC 2012训练集+VOC2007测试集 VOC 2010测试集 68.8%
      实验3 VOC 2012训练集 VOC 2012测试集 65.7%
      实验3 VOC 2007+VOC 2012训练集+VOC2007测试集 VOC 2012测试集 68.4%

      文中分别在VOC 2007、VOC 2010、VOC 2012测试集上测试,发现训练数据越多,效果确实更好。这里微调时采用100k次迭代,每40k次迭代学习率都缩小10倍。
    2. <font face="微软雅黑"color=#ff0000 size=3>哪些层参数需要被微调?
      SPPnet论文中采用ZFnet【AlexNet的改进版】这样的小网络,其在微调阶段仅对全连接层进行微调,就足以保证较高的精度,作者文中采用VGG-16【L for large】网路,若仅仅只对全连接层进行微调,mAP会从66.9%降低到61.4%, 所以文中也需要对RoI池化层之前的卷积层进行微调;

    那么问题来了?向前微调多少层呢?所有的卷积层都需要微调吗?
    作者经过实验发现仅需要对conv3_1及以后卷积层【即9-13号卷积层】进行微调,才使得mAP、训练速度、训练时GPU占用显存三个量得以权衡;
    作者说明所有AlexNet【S for small】、VGG_CNN_M_1024【M for medium】的实验结果都是从conv2往后微调,所有VGG-16【L for large】的实验结果都是从conv3_1往后微调。

    1. <font face="微软雅黑"color=#ff0000 size=3>Fast R-CNN如何进行多任务训练?多任务训练有效果吗?
      Fast R-CNN网络分类损失和回归损失如下图所示【仅针对一个RoI即一类物体说明】,黄色框表示训练数据,绿色框表示输入目标:

    这里写图片描述

    -cls_score层用于分类,输出K+1维数组p,表示属于K类物体和背景的概率;
    -bbox_predict层用于调整候选区域位置,输出4*K维数组,也就是说对于每个类别都会训练一个单独的回归器;
    -loss_cls层评估分类代价,由真实分类u对应的概率决定:Lcls(p,u)=logpuL_{cls}(p,u)=-logp_u

    -loss_bbox评估回归损失代价,比较真实分类u对应的预测平移缩放参数$tu=(tu_x,tu_y,tu_w,t^u_h) \ 和真实平移缩放参数v=(v_x,v_y,v_w,v_h)\ \ 的差距:Lloc(tu,v)=i{x,y,w,h}smoothL1(tiuvi)L_{loc}(t^u,v)=\sum_{i\in\{x,y,w,h\}}smooth_{L_1}(t_i^u-v_i)$ smoothL1(x)={0.5x2, x<1 x0.5,otherwisesmooth_{L_1}(x)=\begin{cases} 0.5x^2, & \text{ $|x|<1$ } \\ |x|-0.5, & \text{otherwise} \end{cases}

    smooth L1损失函数曲线如下图所示,相比于L2损失函数,其对离群点、异常值不敏感,可控制梯度的量级使训练时不容易跑飞;

    这里写图片描述

    结合分类损失和回归损失,Fast R-CNN微调阶段总的损失函数为:L(p,u,tu,v)=Lcls(p,u)+λ[u1]Lloc(tu,v)L(p,u,t^u,v)=L_{cls}(p,u)+\lambda[u\ge1]L_{loc}(t^u,v) [u1]={1,u>1 0,otherwise[u\ge1]=\begin{cases} 1, & \text{$u>1$ } \\ 0, & \text{otherwise} \end{cases}

    约定u=0为背景分类,那么$[u\ge1] \ \ $函数表示背景候选区域即负样本不参与回归损失,不需要对候选区域进行回归操作;
    λ\lambda 控制分类损失和回归损失的平衡,文中所有实验λ=1\lambda=1

    那多任务训练有效果吗?
    首先不看多任务训练效果,至少比起R-CNN其训练方便、简洁。多任务训练考虑各任务间共享卷积层的相互影响,是有潜在可能提高检测效果的;
    文中通过实验发现AlexNet【S for small】、VGG_CNN_M_1024【M for medium】、VGG-16【L for large】三种网络采用多任务训练比不采用mAP提高了0.8%~1.1%【测试时不采用Bounding-box regression】。


    5. <font face="微软雅黑"color=#ff0000 size=3>RoI池化层如何进行反向求导训练?
    首先看普通max pooling层如何求导,设xix_i为输入层节点,yiy_i为输出层节点,那么损失函数L对输入层节点xix_i的梯度为:Lxi={0,δ(i,j)=false Lyj,δ(i,j)=true\frac{\partial L}{\partial x_i}=\begin{cases} 0, & \text{$\delta(i,j)=false$ } \\ \frac{\partial L}{\partial y_j}, & \text{$\delta(i,j)=true$} \end{cases}

    这里写图片描述

    其中判决函数$\delta(i,j)\quad KaTeX parse error: Expected 'EOF', got '#' at position 41: …选中【<font color=#̲00bbff>\delta(i,j)=false \quad</font></font>】有两种可能:x_i不在y_i范围内,或者x_iKaTeX parse error: Expected 'EOF', got '#' at position 23: …选中【<font color=#̲00bbff>\delta(i,j)=true \quad $ 】则由链式规则可知损失函数L相对xix_i的梯度等于损失函数L相对yiy_i的梯度×(yiy_ixix_i的梯度->恒等于1),故可得上述所示公式;

    对于RoI max pooling层,设xix_i为输入层的节点,yriy_{ri} 为第r个候选区域的第j个输出节点,一个输入节点可能和多个输出节点相关连,如下图所示,输入节点7和两个候选区域输出节点相关连;

    这里写图片描述

    该输入节点7的反向传播如下图所示。对于不同候选区域,节点7都存在梯度,所以反向传播中损失函数L对输入层节点xix_i的梯度为损失函数L对各个有可能的候选区域r【xix_i被候选区域r的第j个输出节点选为最大值 】输出yriy_{ri}梯度的累加,具体如下公式所示:

    这里写图片描述

    Lxi=rj[i=i(r,j)]Lyrj\frac{\partial L}{\partial x_i}=\sum_r\sum_j[i=i^*(r,j)]\frac{\partial L}{\partial y_{rj}}
    [i=i(r,j)]={1,i=i(r,j)1 0,otherwise[i=i^*(r,j)]=\begin{cases} 1, & \text{$i=i^*(r,j)\ge1$ } \\ 0, & \text{otherwise} \end{cases}

    判决函数[i=i(r,j)][i=i^*(r,j)]\quad表示i节点是否被候选区域r的第j个输出节点选为最大值输出,若是,则由链式规则可知损失函数L相对xix_i的梯度等于损失函数L相对yrjy_{rj}的梯度×(yrjy_{rj}xi{x_i}的梯度->恒等于1),上图已然解释该输入节点可能会和不同的yrjy_{rj}有关系,故损失函数L相对xix_i的梯度为求和形式。



    **
    1. PASCAL VOC 2007训练集上,使用VGG-16【L for large】网络Fast R-CNN训练时间为9.5h,同等条件下R-CNN需要84h,快8.8倍;

    2. PASCAL VOC 2007测试集上,使用VGG-16【L for large】网络不采用SVD Fast R-CNN测试时间为0.32s/image【不包括候选区域提取时间】,同等条件下R-CNN需要47.0s/image,快146倍;采用SVD测试时间为0.22s/image【不包括候选区域提取时间】,快213倍;

    3. PASCAL VOC 2007测试集上,使用VGG-16【L for large】网络不采用SVD Fast R-CNN mAP为66.9%,同等条件下R-CNN mAP为66.0%;Fast R-CNN采用SVD mAP为66.6%。



    **
    1. Fast R-CNN中采用selective search算法提取候选区域,而目标检测大多数时间都消耗在这里【selective search算法候选区域提取需要2~3s,而提特征分类只需要0.32s】,这无法满足实时应用需求,而且Fast R-CNN并没有实现真正意义上的端到端训练模式【候选区域是使用selective search算法先提取出来的】;

    那有没有可能使用CNN直接产生候选区域并对其分类呢?Faster R-CNN框架就是符合这样需求的目标检测框架,请看Faster R-CNN博客。

    展开全文
  • 想学习R-CNNFast R-CNN、Faster R-CNN必看的5篇经典论文,详细介绍了算法的原理
  • R-CNNFast R-CNN、Faster R-CNN、SSD、YOLO必看经典论文十篇(强烈推荐)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,514
精华内容 1,005
关键字:

fastr-cnn