已有的得卷积神经网络框架的输入基本都是一个固定尺寸的图片(若使用了global pooling,则不需要)。但是基本上用来分类的图片的尺寸跟模型需要的输入都是不同的,因此需要对图片进行放缩。更重要的,当图片的长宽不同时,对图片的缩放会使得图片发生扭曲变形,这会对模型识别准确率产生影响。而本文中提出的SPPnet则是为了解决这一问题的,其可接受不同(任意)大小的图片作为输入进行预测。
依旧从四个方面来梳理一下文章的思路:
1、论文研究目的,即为了解决什么问题?
已有的CNN模型大都需要一个固定尺寸的图片作为输入,而我们的图片大小是各不相同的,这导致输入图片之前需要对图片进行缩放,缩放可能导致图片扭曲变形,这将会影响模型的识别准确率。本文即是为了解决如何能够使得模型能够接受任意大小的图片作为输入。2、解决方法?
本文通过提出一个空间金字塔池化层(Spatial Pyramid Pooling)来解决输入图片尺寸不同的问题。通过在现有模型中加入一个SPP层可使得模型接受任意大小的图片输入。3、效果如何?
无论是在分类还是在目标检测领域都达到了顶尖的检测结果。4、有何问题以及展望?
文中未提,个人认为主要还是Fast R-CNN中提出的SPPnet在反向传播微调卷积层时候的低效问题吧,第二个就是SPPnet用于目标检测时同样的还是与R-CNN类似的使用了多段的系统,即SPPnet用来提取特征,而分类则是使用SVM。
下面我们来简单介绍下本文提出的空间金字塔池化(Spatial Pyramid Pooling),以下简称SPP。
在前面我们已经提到为什么提出SPP层?因为现有的网络模型需要固定的输入,而我们现实中得到的图片基本上输入大小都是与模型要求输入不一致的,这就需要对图片进行放缩,而放缩时对图片的扭曲变形会对模型精度造成影响。
但是其实这里的模型需要固定输入并不是指模型网络的每一层都需要一个固定的输入。一般而言,卷积模型通常分为两部分——卷积层和全连接层(这里不考虑将全连接层替换为global pooling),前面卷积层通过滑窗的方式来进行运算提取特征,其对图片大小是没有要求的,但是后面的全连接层确是固定的,他只能接受一个固定大小的输入。而一张图片经过多层卷积加池化层,其会经过多次放缩(且放缩倍数固定),最终得到的feature map与原图大小的比例是固定的,因此对于不同大小的图片,其得到的feature map大小也不同,最后展开后得到features 也不同,无法与后面全连接层需要的features数量匹配上,这时就会出错,无法运行,因此需要固定大小的图片输入。
对于不同大小的输入图片,经过多层卷积加池化后得到的feature map大小也不同,对于这些大小不同的feature map,该如何操作来使得这些不同大小feature map展开后得到一个固定大小的向量呢?本文通过提出一个SPP层来解决输入尺寸不同导致最后得到的feature map大小不同的问题。SPP层结构如下图所示:如上图所示,通过SPP层后得到了3个大小不同的feature map(4x4,2x2和1x1),这就是其金字塔池化的含义——得到不同大小的feature map。其中1x1的feature map可以看作是global pooling的结果。已知这三个不同大小的feature map的来源feature map大小是相同的,那么问题来了。这里主要有两个问题:(1)同一个大小的feature map如何池化得到不同feature map;(2)不同图片尺寸经过多层卷积+池化的得到不同大小的feature map如何经过SPP处理后始终得到相同大小三个feature map。这两个问题也是这篇文章的核心。
对于第一个问题,同一个feature map经过SPP处理得到3个不同大小的feature map(值得注意的是,这里的SPP得到的多个feature map的大小并不是一定的,不同网络或者不同训练采用不同的SPP的feature map可以训练得到不同的模型),对于每个网络都可以使用不同的,可以通过三次不同大小的池化filter来得到,譬如对于一个13x13的feature map,可以通过如下图所示的三个pooling得到:第一个池化使用的filter=5x5,stride=4,得到大小为3x3的feature map;第二个池化层使用的filter=7x7,stride=6x6,得到的feature map大小为2x2;第三个池化层就是一个全局池化,得到一个1x1的feature map。
对于第二个问题,其实就是不同大小的feature map如何经过池化得到相同大小的feature map。这里需要一个可变的池化filter大小,即对于不同的输入feature map,使用不同大小的池化filter,以得到相同的feature map。那么这个不同大小的pooling的参数如何得来呢?文中给出了计算方法,假设最后一层卷积层的输出为axa, 经spp后输出的feature map大小为nxn,则其pooling filter = a/n(这里采用上取整),stride = a/n (这里采用的下取整)。譬如上面13x13的feature map经过filter=5x5,stride=4x4的池化后得到了3x3的feature map,而对于18x18的feature map我们可以通过filter=6x6,stride=6x6的pooling得到同样大小的3x3的feature map。也就是说每个spp pooling的参数都不是固定的,他是根据输入和输出feature map来进行相应变化的。
对于目标检测问题,我们需要将预先提取出来的图像上的区域候选框坐标给映射到feature map上,假设在原图上的坐标为(x, y), feature map上的对应的坐标为(x', y'),则他们的映射关系如下:其中,S表示前面所有卷积池化层的步长的乘积,也就是整体的放缩倍数。
对于训练,文中提到的不同尺寸的图片的训练方法是不同尺寸的图片在不同epoch交替运行,譬如第一个epoch使用224x224的图片,第二个epoch使用298x298的图片,如此交替运行。
此外,还有一点是,文中将其与R-CNN进行比较,由于其一次能将整个图片作为输入,然后将候选框区域坐标映射到feature map上,因此对于一张图片的所有候选框其可以共享卷积运算,运行速度会比R-CNN快很多,这也是fast R-CNN借鉴SPPnet的地方,但是SPPnet仍然使用的是SVM作为分类器,卷积网络只是用来提取特征,使用的仍然是多步系统(Selective search找出候选区域,CNN提取特征,SVM分类)。fast R-CNN借鉴了SPPnet的共享卷积计算的优点,提出了一个ROI pooling而非SPP,但是ROI pooling与SPP不同,ROI pooling不是多尺度池化,他是一个固定输出的池化层,与SPP相同的是ROI pooling的pooling 参数也是根据输入feature map的大小计算出来的(因为不同候选区域的feature map大小不同)。
最后,做一个简单的总结,SPPnet通过提出一个空间金字塔池化层(SPP)来解决不同尺度的图片输入问题,在分类和目标检测上都达到了很好地效果。但是他在目标检测上的一个问题是不好对卷积层进行反向传播微调。虽然在目标检测问题上,他没有解决多级系统的问题,但是他给后面的fast R-CNN提供了重要的思路,fast R-CNN中的ROI pooling即是借鉴于此。
参考:
Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition.
网友评论