SPP-net解读转发

写在前面

  按照原论文的顺序解析起来会更容易理解,不是对原论文的机械翻译,只是我对原论文的浅显理解,如有不当,请批评指正。R-CNN使用CNN作为特征提取器,首次使得目标检测跨入深度学习的阶段。但是R-CNN对于每一个建议框都需要首先将图片放缩到固定的尺寸(224*224),然后为每个修正后的建议框提取CNN特征。容易看出来这里面存在一些性能瓶颈:

  • 速度瓶颈:重复为每个建议框提取特征是极其耗时的,每张图片大约经过2K次完整的CNN计算得到最终的结果。
  • 性能瓶颈:对于所有的建议框放缩到固定的尺寸会导致我们不希望看到的几何形变,而且由于速度瓶颈的存在,不可能采用多尺度或者是大量的数据增强去训练模型。

论文:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

Abstract

  在此之前的CNNs都需要定长的输入,这样才能生成定长的特征向量。但是这就需要将训练图片裁剪、变形成同一尺寸,这个预处理步骤可能会损失识别精度。为了避免这个硬性需求,这篇论文提出了一种新的池化方式,“空间金字塔池化”。使用空间金字塔池化的网络被称为SPP-net,这种网络对于任意尺寸的输入都能产生定长的输出。容易看出来金字塔池化对于物体的形变鲁棒。在SPP-net中我们计算整张图片的feature map一次就够了,然后池化arbitrary regions对应的特征,池化后的特征是定长的,这种方法避免了重复计算feature map,处理测试图片时,SPP-net比R-CNN快24—102倍,两者精度不分伯仲。

Introduction

  目前的CNNs都需要定长的输入。将任意尺寸的图片变成定长的图片无非需要经过两次操作:crop、warp,这两种预处理方式的弊端也很明显。

  • crop:croped region可能并没有包含整个物体,那么就会损失一部分信息,对region的得分会产生影响。
  • warp:可能会带来不想要的集合distortion【变形、失真、扭曲】。

  识别精度就有可能因为没有完全包含以及形变产生影响。另外,当目标的尺寸改变时,先前的模型可能就不能用了。下图分别是crop、warp的操作过程:
              这里写图片描述
  为什么CNNs会要求定长的输入呢?
                                        CNN = Conv + FC
  我们知道Conv层不需要定长的输入,它能产生任意尺寸的feature maps。FC层需要定长的输入,因为对定长的限制来自于FC层,而FC往往存在于网络的深层。空间金字塔池化就存在于Conv后、FC前,它将任意尺寸的feature maps池化为定长的特征向量,然后送到需要定长输入的FC层。池化的具体做法,后面详细介绍,下图分别是传统的CNN和含有空间金字塔池化层的网络结构。
              这里写图片描述

Deep networks with Spaatial Pyramid Pooling

Convolutional Layers and Feature Maps

  以比较流行的7层网络AlexNet为例。前面5层是卷积层,跟着它们的是池化层,后面2层是全连接层,紧跟着的是N-way的softmax层,N是输出的类别数。
  上面说的CNNs需要定长的输入,而这仅仅是全连接层所需要的。卷积层可以接受任意尺寸的输入,他们的输出的尺寸可以说是正比于输入的尺寸,这些输出也被称为feature maps,这些maps是强度和空间位置的响应。论文中有讲到不同的feature maps的强响应处检测不同的形状,如等,细节可看论文。

The Spatial Pyramid Pooling Layer

  为了将Conv5的任意尺寸的输出变成FC可以接受的定长的尺寸,首先将pool5去掉,换成空间金字塔池化层。具体的池化操作如下图所示:
              这里写图片描述
  Conv5的输出是256个feature maps,每张图片的所有maps是同样大小的,但是不同图片的maps尺寸不一样,所以是任意尺寸的。对单个map做全局池化(最大池化或者平均池化,这个暂且不管),那么就得到单个数据的输出,256个maps,就会有256个输出数据。那么如果我想让每张图片池化成4个数据的输出,该怎么做呢?只需要将map均分成4份,对每一份做池化操作,那么单个map就会产生4个数据的输出向量,256个maps,就会有256*4个输出数据。如果我想让每张图片产生16个数据的输出向量,怎么做呢?。。。。将上面所有的输出组合到一起,就会产生(1×256+4×256+16×256)(1×256+4×256+16×256)维的特征向量。

Training the Network

  理论上来讲,上面说的网络结构可以用标准后向传播来计算,而不用考虑输入图片的尺寸,但是实际中GPU更喜欢定长的输入,那么我们如何在保留空间金字塔池化的基础上高效的利用GPU呢?

Single-size training

  我们首先考虑有定长输入的网络,比如224*224,它是从图片中crop得到,crop的目的是data augmentation。从Conv5出来的feature maps的大小为a*a(eg,13*13),我们想让每层金字塔产生n*n的输出,可以用滑动窗口池化来实现这个池化操作,窗口的大小windows=a/n(向上取整),步长stride=a/n向下取整,对于一个含有L层的金字塔,我们实现L个这样的层,接下来的FC层的输入fc6将是这L个输出的叠加。

Multi-size training

  我们的网络被期望用在费定长的输入尺寸上,我们不妨考虑两种尺寸:180*180、224*224;这个180*180并不是从原图像上crop得到,我们将224*224 resize 成180*180,所以这两种尺寸的图像仅在分辨率上不同,而在内容/布局(content / layout)上都是相同的,对于接受180*180作为输入的情况,我们实现另一个定长输入【180*180】的网络,Conv5后的feature map为 a*a = 10*10,用win = a/n(上),str = a/n(下)实现每一个金字塔池化层,这个180-network的输出长度与224-network是一样的。并且两者在每一层的参数了是相同的。
  为了减小两个网络转化时的突兀,我们以epoch为单位,也就是在一个网络上训练一个epoch,然后在另一个网络上训练一个epoch。这两个网络的所有权重都是共享的,这样最后训练出来的网络对180*180、224*224的输入图片都能有效的检测。

SPP-net for Object Detection

  R-CNN模型首先需要用选择性搜索算法生成~2000张建议框,这些建议框是原图像的各个子图像。上面我们也说了SPP-net的检测速度之所以比R-CNN快这么多,是因为SPP-net只需要计算一次feature map,而且这个feature map是原图像的,那么各个建议框的feature map怎么计算呢?其实很简单,建议框是从原图像上抠出来的吧,扣的位置我们是知道的吧,那么在原图像的feature map的对应位置抠出来的不就是建议框的feature map了吗,当然这个变换有个尺度因子,这是因为通常原图像的feature map通常比原图像小了几倍。具体怎么做呢?

  • 主要是弄清楚如何:Mapping a region proposal to Feature Maps.
  • 思路:将region proposal的corner point 映射到Feature Maps中的pixel.

  每个Conv层,如果滤波器尺寸是 P,那么每条边填充 P/2,目的是卷积前后尺寸一样,池化后刚好减半。看下面这个图吧。
这里写图片描述

解释分析

1,SPP-net的优点

  • 相比R-CNN只需要计算一次feature map,节省了计算开销。
  • 任意尺寸的输入,固定大小的输出。用任意尺寸的图片做训练,增加了scale-invariance,减小了过拟合发生。对于一个接受任意尺寸输入的网络,我们可以将它想象成多个网络,每个网络接受定长的输入,每个epoch仅训练一个网络,下一个epoch转向另一个网络,所有的网络共享参数。收敛速度和传统的单网络差不多。
  • 使用multi-level spatial bins,对目标的形变鲁棒。

2,SPP-net存在的不足

  和R-CNN一样,SPP也需要训练CNN提取特征,然后训练SVM分类这些特征。需要巨大的存储空间,并且分开训练也很复杂。而且选择性搜索的方法提取特征是在CPU上进行的,相对于GPU来说还是比较慢的。针对这些问题的改进,我们将在Fast R-CNN、Faster R-CNN中介绍。

写在前面

猜你喜欢

转载自blog.csdn.net/weixin_43489950/article/details/89146342