深度学习-目标检测(R-FCN)

1、R-FCN初探算法


1. R-FCN与传统二阶段网络的异同点

 

    图1 R-FCN与传统二阶段网络的异同点

  相同点:首先,二者二阶段的检测框架(全卷积子网络+RoI-wise subnetwork); 其次二者最终输出的结果都是相应的类别和对应的BBox;

  不一样点:如上图所示,咱们能够看到和Faster R-CNN相比,R-FCN具备更深的共享卷积网络层,这样能够得到更加抽象的特征;同时,它没有RoI-wise subnetwork,不像Faster R-CNN的feature map左右都有对应的网络层,它是真正的全卷积网络架构;从图中的表格能够看出Faster R-CNN的共享卷积子网络是91层,RoI-wise子网络是10层,而R-FCN只有共享卷积子网络,深度为101层。与R-CNN相比,最大的不一样就是直接得到整幅图像的feature map,再提取对应的ROI,而不是直接在不一样的ROI上面得到相应的feature map。

 2. 分类网络的位置不敏感性和检测网络的位置敏感性

  博主以我的理解解释一下“分类网络的位置不敏感性”与“检测网络的位置敏感性”网络


            

 

    图2 分类网络的位置不敏感性和检测网络的位置敏感性
 

  分类网络的位置不敏感性:对于分类任务而言,我但愿个人网络有一个很好地分类性能,随着某个目标在图片中不断的移动,个人网络仍然能够准确的将你区分为对应的类别。如上图所示,无论小猫在图片中如何移动,个人分类网络都想要准确的将你分类为猫。即个人网络有很好地区分能力。实验代表,深的全卷积网络可以具有这个特性,如ResNet-101等。

  检测网络的位置敏感性:对于检测任务而言,我但愿个人网络有一个好的检测性能,能够准确的输出目标所在的位置值。随着某个目标的移动,个人网络但愿可以和它一块儿移动,仍然可以准确的检测到它,即我对目标位置的移动很敏感。我须要计算对应的误差值,我须要计算个人预测和GT的重合率等。可是,深的全卷积网路不具有这样的一个特征。

  所以,分类网络的位置不敏感性和检测网络的位置敏感性的一个矛盾问题,而咱们的目标检测中不只要分类也要定位,那么如何解决这个问题呢,R-FCN提出了Position-sensitive score maps来解决这个问题。

3. R-FCN网络的背景

  Faster R-CNN系列的网络均可以分红2个部分:ROI Pooling以前的共享全卷积网络和ROI Pooling以后的ROI-wise子网络(用来对每一个ROI进行特征提出,并进行回归和分类)。第1部分就是直接用普通分类网络的卷积层,用来提取共享特征,而后利用ROI Pooling在最后一层网络造成的feature map上面提取针对各个RoIs的特征向量,而后将全部RoIs的特征向量都交给第2部分来处理(即所谓的分类和回归),而第二部分通常都是一些全链接层,在最后有2个并行的loss函数:softmax和smoothL1,分别用来对每个RoI进行分类和回归,这样就能够获得每一个RoI的真实类别和较为精确的坐标信息啦(x, y, w, h)。

  须要注意的是第1部分一般使用的都是像VGG、GoogleNet、ResNet之类的基础分类网络,这些网络的计算都是全部RoIs共享的,在一张图片上面进行测试的时候只须要进行一次前向计算便可。而对于第2部分的RoI-wise subnetwork,它却不是全部RoIs共享的,主要的缘由是由于这一部分的做用是“对每一个RoI进行分类和回归”,因此不能进行共享计算。那么问题就处在这里,首先第1部分的网络具备“位置不敏感性”,而若是咱们将一个分类网络如ResNet的全部卷积层都放置在第1部分用来提取特征,而第2部分则只剩下全链接层,这样的目标检测网络是位置不敏感的(translation-invariance),因此其检测精度会较低,并且这样作也会浪费掉分类网络强大的分类能力(does not match the network's superior classification accuracy)。而ResNet论文中为了解决这个问题,作出了一点让步,即将RoI Pooling层再也不放置在ResNet-101网络的最后一层卷积层以后而是放置在了“卷积层之间”,这样RoI Pooling Layer以前和以后都有卷积层,而且RoI Pooling Layer以后的卷积层不是共享计算的,它们是针对每一个RoI进行特征提取的,因此这种网络设计,其RoI Pooling层以后就具备了位置敏感性(translation-variance),可是这样作会牺牲测试速度,由于全部的RoIs都须要通过若干层卷积计算,这样会致使测试速度很慢。R-FCN就是针对这个问题提出了本身的解决方案,在速度和精度之间进行折中。

2、R-FCN架构分析

1. R-FCN算法步骤架构



     图3 R-FCN结构图

  如图所示,先来分析一下R-FCN算法的整个运行步骤,使得咱们对整个算法有一个宏观的理解:
    1) 选择一张须要处理的图片,并对这张图片进行相应的预处理操做;框架

    2) 将预处理后的图片送入一个预训练好的分类网络中(这里使用了ResNet-101网络的Conv4以前的网络),固定其对应的网络参数;
    3) 在预训练网络的最后一个卷积层得到的feature map上存在3个分支,第1个分支就是在该feature map上面进行RPN操做,得到相应的ROI;第2个分支就是在该feature map   上得到一个K*K*(C+1)维的位置敏感得分映射(position-sensitive score map),用来进行分类;第3个分支就是在该feature map上得到一个4*K*K维的位置敏感得分映射,用  来进行回归;
    4) 在K*K*(C+1)维的位置敏感得分映射和4*K*K维的位置敏感得分映射上面分别执行位置敏感的ROI池化操做(Position-Sensitive Rol Pooling),这里使用的是平均池化操   做,得到对应的类别和位置信息。

  这样,咱们就能够在测试图片中得到咱们想要的类别信息和位置信息啦。

2. Position-Sensitive Score Map解析

  图3是R-FCN的网络结构图,其主要设计思想就是“位置敏感得分映射(position-sensitive score map)”。如今咱们来解释一下其设计思路。若是一个RoI中含有一个类别C的物体,咱们将该RoI划分为K*K 个区域,其分别表示该物体的各个部位,好比假设该RoI中含有的目标是人,K=3,那么就将“人”划分红了9个子区域,咱们将RoI划分为K*K个子区域是但愿这个RoI在其中的每个子区域都应该含有该类别C的物体的各个部位,当全部的子区域都含有各自对应的该物体的相应部位后,那么分类器才会将该RoI判断为该类别。也就是说物体的各个部位和RoI的这些子区域是“一一映射”的对应关系。

  OK,如今咱们知道了一个RoI必须是K*K个子区域都含有该物体的相应部位,咱们才能判断该RoI属于该物体,若是该物体的不少部位都没有出如今相应的子区域中,那么就该RoI判断为背景类别。那么如今的问题就是网络如何判断一个RoI的 K*K个子区域都含有相应部位呢?

  这其实就是position-sensitive score map设计的核心思想了。R-FCN会在共享卷积层的最后一层网络上接上一个卷积层,而该卷积层就是位置敏感得分映射,该score map的含义以下所述,首先它就是一层卷积层,它的height和width和共享卷积层的同样(即具备一样的感觉野),可是它的通道个数为K*K*(C+1) 。其中C表示物体类别种数,再加上1个背景类别,因此共有(C+1)类,而每一个类别被分红 K*K个score maps。如今咱们只针对其中的一个类别来进行说明,假设咱们的目标属于人这个类别,那么其有 K*K 个score maps,每个score map表示原始图像中的哪些位置含有人的某个部位,该score map会在含有对应的人体的某个部位的位置有高的响应值也就是说每个score map都是用来描述人体的其中一个部位出如今该score map的何处,而在出现的地方就有高响应值”。既然是这样,那么咱们只要将RoI的各个子区域对应到属于人的每个score map上而后获取它的响应值就行了。可是要注意的是,因为一个score map都是只属于一个类别的一个部位的,因此RoI的第 i个子区域必定要到第i张score map上去寻找对应区域的响应值,由于RoI的第i个子区域须要的部位和第i张score map关注的部位是对应的。那么如今该RoI的K*K个子区域都已经分别在属于人的K*K个score maps上找到其响应值了,那么若是这些响应值都很高,那么就证实该RoI是人呀。固然这有点不严谨,由于咱们只是在属于人的 K*K个score maps上找响应值,咱们尚未到属于其它类别的score maps上找响应值呢,万一该RoI的各个子区域在属于其它类别的上的score maps的响应值也很高,那么该RoI就也有可能属于其它类别呢?是吧,若是2个类别的物体自己就长的很像呢?这就会涉及到一个比较的问题,那个类别的响应值高,我就将它判断为哪一类目标。它们的响应值一样高这个状况发生的概率很小,咱们不作讨论。

  OK,这就是position-sensitive score map的所有思想了,应该很容易理解了吧。

3. Position-Sensitive Rol Pooling解析

  上面咱们只是简单的讲解了一下ROl的K*K个子区域在各个类别的score maps上找到其每一个子区域的响应值,咱们并无详细的解释这个“找到”是如何找的?这就是位置敏感Rol池化操做(Position-sensitive RoI pooling),其字面意思是池化操做是位置敏感的,下来咱们对它进行解释说明。

  如图3所示,经过RPN提取出来的RoI区域,其是包含了x,y,w,h的4个值,也就是说不一样的RoI区域可以对应到score map的不一样位置上,而每一个RoI会被划分红K*K个bins(也就是子区域。每一个子区域bin的长宽分别是 h/k 和 w/k ),每一个bin都对应到score map上的某一个区域。既然该RoI的每一个bin都对应到score map上的某一个子区域,那么池化操做就是在该bin对应的score map上的子区域执行且执行的是平均池化。咱们在前面已经讲了,第i个bin应该在第i个score map上寻找响应值,那么也就是在第i个score map上的第i个bin对应的位置上进行平均池化操做。因为咱们有(C+1)个类别,因此每一个类别都要进行相同方式的池化操做。
  图3已经很明显的画出了池化的方式,对于每一个类别,它都有K*K个score maps,那么按照上述的池化方式,ROI能够针对该类别能够得到K*K个值,那么一共有(C+1)个类别,那么每一个RoI就能够获得K*K*(C+1)个值,就是上图的特征图。那么对于每一个类别,该类别的K*K个值都表示该RoI属于该类别的响应值,那么将这K*K个数相加就获得该类别的score,那么一共有(C+1)个scores,那么在这(C+1)个数上面使用简单的softmax函数就能够获得各个类别的几率了(注意,这里不须要使softmax分类器了,只须要使用简答的softmax函数,由于这里就是经过简单的比大小来判断最终的类别的)。

4. Position-Sensitive Regression解析

  前面的position-sensitive score map和Position-sensitive RoI pooling获得的值是用来分类的,那么天然须要相应的操做获得对应的值来进行回归操做。按照position-sensitive score map和Position-sensitive RoI pooling思路,其会让每个RoI获得(C+1)个数做为每一个类别的score,那么如今每一个RoI还须要 4个数做为回归偏移量,也就是x,y,w,h的偏移量,因此仿照分类设计的思想,咱们还须要一个相似于position-sensitive score map的用于回归的score map。那么应该如何设置这个score map呢,论文中给出了说明:即在ResNet的共享卷积层的最后一层上面链接一个与position-sensitive score map并行的score maps,该score maps用来进行regression操做,咱们将其命名为regression score map,而该regression score map的维度应当是 4*K*K ,而后通过Position-sensitive RoI pooling操做后,每个RoI就能获得4个值做为该RoI的x,y,w,h的偏移量了,其思路和分类彻底相同。

 

5. 为何position-sensitive score map可以在含有某个类别的物体的某个部位的区域上具备高响应值?

  这种有高响应值如今只是做者本身设想的啊,若是网络不知足这一点的话,那么咱们前面的全部分析都不成立啦。如今咱们就大体解释一下为何训练该网络可以让网络最终知足这一点。首先根据网络的loss计算公式,若是一个RoI含有人这个“物体”,那么该RoI经过position-sensitive score map和Position-sensitive RoI pooling获得的(C+1)个值中属于人的那个值必然会在softmax损失函数的驱动下变得尽可能的大,那么如何才能使得属于人的这个值尽可能的大呢?那么咱们须要想一想属于人的这个预测值是怎么来的?通过前面的分析,咱们已经知道它是经过Position-sensitive RoI pooling这种池化操做得到的,那么也就是说使得(C+1)个值中属于人的那个类别C的值尽可能大,必然会使得position-sensitive score map中属于人的那个score map上的RoI对应的位置区域的平均值尽可能大,从而会使得该score map上在该区域上的响应值尽可能大,由于只有该区域的响应值大了,才能使得预测为人的几率大,才会下降softmax的loss,整个训练过程才能进行下去。函数


    图4 位置敏感得分映射表现1性能


    图5 位置敏感得分映射表现2

  如图4和图5所示,咱们一样能够得出以上的结论。如图5所示,咱们输入了一张含有一个小孩的图片,图中黄色的BBox表示咱们的检测到的目标,也就是咱们的一个ROI,接下来是9张位置敏感的得分映射图(在这里使用的是3x3的特征映射),这9张图分别表示对人这个目标的top-left、top-center、... bottom-right不一样区域敏感的得分映射。对应到图中就是将这个ROI分为9个子区域,每个子区域其实大体上对应到了小孩的不一样部位,而不一样的部位通常都会有其独特的特征存在,9个区域敏感得分映射图对不一样的区域比较敏感(所谓的敏感就是说若是这个子区域中存在该目标的某个部位特征时,其才会输出较大的响应值,不然的话会输出较小的响应值)。图5中的9个得分映射对ROI中划分的对应子区域都比较敏感(都有很强的响应值,越白表示响应越大,越黑表示响应越小),即ROI中的9个子区域都有较大的响应值。而后进行位置敏感池化操做,最后进行Vote操做,因为9个区域中基本上都有很高的响应值,最后投票经过,认为这个ROI中的对象是一个person。同理,能够得出图6是一个背景类。(图6的位置敏感ROI池化中有5个区域是黑色的,即表示具备较低的响应值,只有4个区域比较高,即表示具备较高的响应值,根据Vote机制,就将其分类为背景类)。
 

6. Loss计算及其分析学习


  这个Loss就是两阶段目标检测框架经常使用的形式。包括一个分类Loss和一个回归Loss。λ用来平衡二者的重要性。对于任意一个RoI,咱们须要计算它的softmax损失,和当其不属于背景时的回归损失。这很简单,由于每一个RoI都被指定属于某一个GT box或者属于背景,即先选择和GT box具备最大重叠率(IOU)的Rol,而后在剩余的Rol中选择与GT box的重叠率值大于0.5Rol进行匹配操做,最后将剩余的Rol都归为背景类。即每一个Rol都有了对应的标签,咱们就能够根据监督学习经常使用的方法来训练它啦。

7. online hard example mining

  这个方法是目标检测框架中常常会用到的一个tricks,其主要的思路以下所示:首先对RPN得到的候选ROI(正负样本分别进行排序)进行排序操做;而后在含有正样本(目标)的ROI中选择前N个ROI,将正负样本的比例维持在1:3的范围内,基本上保证每次抽取的样本中都会含有必定的正样本,均可以经过训练来提升网络的分类能力。若是不进行此操做的话,极可能会出现抽取的全部样本都是负样本(背景)的状况,这样让网络学习这些负样本,会影响网络的性能。(这彻底是我我的的理解,哈哈哈)

8. Atrous algorithm(Dilated Convolutions或者膨胀卷积)测试

     图6 膨胀卷积

  这个方法一样也是目标检测中经常使用的一个tricks,其最主要的目的是能够在减少卷积步长的同时扩大feature map的大小,即同等状况下,经过这个操做,咱们能够得到一个更大的feature map,而实验代表,大的feature map会提高检测的性能。

9. 为了过滤背景Rols使用的方法

  在测试的时候,为了减小RoIs的数量,做者在RPN提取阶段就对RPN提取的大约2W个proposals进行了过滤,方法以下所示,
    1) 去除超过图像边界的proposals;
    2) 使用基于类别几率且阈值IoU=0.7的NMS过滤;
    3) 按照类别几率选择top-N个proposals;

因此在测试的时候,最后通常只剩下300左右个RoIs,固然这个数量是一个超参数。而且在R-FCN的输出300个预测框以后,仍然要对其使用NMS去除冗余的预测框。


4、总结

总的来说,和Faster R-CNN相比,R-FCN具备更快的运行速度(2.5倍以上),稍微提升了一点检测精度,在速度和准确率之间进行了折中,提出position-sensitive score map来解决检测的位置敏感性问题。算法中的不少细节值得咱们进行深刻的研究和分析,但愿你从中学到了不少有用的东西。spa

相关文章
相关标签/搜索