RCNN学习笔记(2)-SPPnet

来源:互联网 发布:java iocp 编辑:程序博客网 时间:2024/06/12 18:51

reference link:https://zhuanlan.zhihu.com/p/24774302
reference link:http://blog.csdn.net/u011534057/article/details/51219959

一张图图片会有~2k个候选框,每一个都要单独输入CNN做卷积等操作很费时。SPP-net提出:能否在feature
map上提取ROI特征,这样就只需要在整幅图像上做一次卷积。
这里写图片描述
图片来自 https://zhuanlan.zhihu.com/p/24774302


流程

1、Selection Search 得到候选区域
2、CNN提取ROI特征
3、SVM类别判断
4、位置修正
注:所有ROI 的特征直接在feature map上提取,极大的提高了卷积操作提高了效率。


空间池化金字塔SPP

核心思想:通过对feature map进行相应尺度的pooling,使得能pooling出4×4, 2×2, 1×1的feature map,再将这些feature map concat成列向量与下一层全链接层相连。这样就消除了输入尺度不一致的影响。

这里写图片描述
文章在一开始的时候就说明了目前深度网络存在的弊端:如果固定网络输入的话,要么选择crop策略,要么选择warp策略,crop就是从一个大图扣出网络输入大小的patch(比如227×227),而warp则是把一个bounding box的内容resize成227×227 。无论是那种策略,都能很明显看出有影响网络训练的不利因素,比如crop就有可能crop出object的一个部分,而无法准确训练出类别,而warp则会改变object的正常宽高比,使得训练效果变差。
所以,我们提出了要打破输入大小的约束。

首先介绍一下SPP的优点
1)任意尺寸输入,固定大小输出
2)层多
3)可以对仍以尺度提取的特征进行池化

R-CNN提取特征比较耗时,主要是因为,RCNN需要对每个区域进行学习,而SPPNet 只要对图像进行一次卷积,之后使用SPPNet在特征图上提取特征。

网络流程
图像输入->卷积层1->池化1->…卷积层n->池化n->全连接层

问题一: ROI在特征图上对应的特征区域的维度不满足全连接层的输入要求怎么办
引发这个问题的主要原因是,全连接层的输入维度是固定的,导致池化n的输出必须是与之匹配的格式,继而导致图像输入的尺寸必须是固定的。
解决的思路:
方案1-让不同尺寸的图像可以最终通过 池化n 产生固定的输出维度;
方案2-让全连接层可以接受非固定的输入维度;

而方案1,就是SPPnet的思想,它在池化n处,使用了特殊的池化手段:空间金字塔池化,是的不同尺寸的图像可以使得池化n 产生固定的输出维度。
//注意:方案2 的本质就是全连接层转换为全卷积,作用效果等效为在原始图像做滑动窗口。
这里写图片描述

输入的尺寸在[180,224]之间,假设最后一个卷积层输出的大小为a×a,若给定金字塔层有n×n个bins,进行滑动窗池化,窗口长度为 win=⌈a/n⌉ (⌈⌉ 向上取整符 ⌊⌋向下取整符号 ) 步长为str⌊a/n⌋,使用一个网络完成一个完整的epoch的训练,之后切换到另一个网络。
例:如果原图输入为224×224 对于conv5的输出是13×13×256的,可以理解为有256个这样的filter,每个filter对应13×13的reponse map;
如果像上图那样将reponse map分成4x4 2x2 1x1三张子图,做max pooling后,出来的特征就是固定长度的(16+4+1)x256那么多的维度了。如果原图的输入不是224x224,出来的特征依然是(16+4+1)x256;

也就是说当我们输入任意大小的图片(w,h),最后都得到的都是21个神经元(4x4+2x2+1x1)

这里写图片描述
如图所示:

  1. 第一张图片,我们把完整的图片分成16块,每一块大小(w/4,h/4);
  2. 第二张图片,划分成4块,每一块(w/2,h/2);
  3. 第三张图片,把整张图像作为一块

空间金字塔最大池化的过程,其实就是从这21个图片块中,分别计算每个块的最大值,从而得到一个输出神经元。

     最后把一张任意大小的图片转换成了一个固定大小的**21维特征**(当然你可以设计其它维数的输出,增加金字塔的层数,或者改变划分网格的大小)。    当我们有很多层网络的时候,当网络输入的是一张任意大小的图片,这个时候我们可以一直进行卷积、池化,直到网络的倒数几层的时候,也就是我们即将与全连接层连接的时候,就要使用金字塔池化,使得任意大小的特征图都能够转换成固定大小的特征向量,这就是空间金字塔池化的奥义(多尺度特征提取出固定大小的特征向量)

来自:Alanyannick的 见解
http://blog.csdn.net/u011534057/article/details/51219959

pad】大家都知道,现在默许的无论是卷积还是pooling(无stride),都会加相应的pad,来使得卷积后的尺寸与卷积前相同,当然这种做法还个好处就是使得边缘不会只被卷积一次就消失了

这里写图片描述
大神画的图, 蓝色的区域是原图,而红色区域就是加上的pad区域。紫色为卷积核。

      而卷积或pooling增加stride的话就相当与原图先进行卷积或池化,再进行sampling,这还是能一一对应的,就这样原图的某个区域就可以通过除以网络的所有stride来映射到conv5后去区域。

      终于把这里讲出来了,大家如果直接按照函数的一一对应关系去理解,很容易理解为什么原图的区域除以所有的stride就是映射到conv5的区域。这样子就可以在原图上的一些操作放在conv5上进行,这样可以减小任务复杂度。

【但是】

      “不过,我并不是太认可这种映射机制,这种映射只能是点到点的关系,不过我觉得从原图的某个区域R映射到conv5的区域r,应该r对R敏感,换句话说,应该r感受野应该与R有交集。这样子的话,示意图如下:
这里写图片描述
      蓝色为 conv 的神经元感受野,红色则是原图感兴趣的区域,而黑框 才是要映射到conv5的区域;
      使用SPP进行检测,先用提候选proposals方法(selective search)选出候选框,不过不像RCNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,因为候选框的大小尺度不同,映射到conv5后仍不同,所以需要再通过SPP层提取到相同维度的特征,再进行分类和回归,后面的思路和方法与RCNN一致。
      实际上这样子做的话就比原先的快很多了,因为之前RCNN也提出了这个原因就是深度网络所需要的感受野是非常大的,这样子的话需要每次将感兴趣区域放大到网络的尺度才能卷积到conv5层。这样计算量就会很大,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。
      当然即使是这么完美的算法,也是有它的瑕疵的,可能Kaiming He大神太投入 SPP的功效了,使得整个流程框架并没有变得更加完美。首先在训练方面,SPP没有发挥出它的优势,依旧用了传统的训练方法,这使得计算量依旧很大,而且分类和bounding box的回归问题也可以联合学习,使得整体框架更加完美。这些Kaiming He都给忽略了,这样也就有了第二篇神作 Fast RCNN。

原创粉丝点击