SPP-Net论文链接: https://arxiv.org/pdf/1406.4729.pdf
官方代码: https://github.com/ShaoqingRen/SPP_net
大神的论文翻译: http://www.dengfanxin.cn/?p=403
大神代码链接1: https://github.com/yhenon/keras-spp
大神代码链接2: https://github.com/peace195/sppnet
浅学一下SPP吧。
背景
在CNN已经在视觉检测领域表现出明显的性能提升的时候,CNN网络却有一个地方困扰着研究者和一些使用者,那就是当时的CNN网络只能以固定大小的图片进行输入(比如224×224),这限制了输入图像的长宽比和缩放尺度。
那可能就会有人提出建议,在前面加上一些手段,如裁剪和变形等,使得图片输入可以任意,但是最终进入网络的大小固定不就好了蛮。建议很好,下次不许再建议了。让我们深入了解理解一些为什么这种方法不行。
原因:
1、裁剪会导致信息的丢失;
2、变形会导致位置信息的扭曲;
上面具体的例子论文中给出了下面两个很直观的图片;
虽然图片这样裁剪和变形显得有点激进,可能真实的会比这样好点,但是证明了,这样做会很大程度上影响精度,另外,一个预先定义好的尺寸在物体是缩放可变的时候就不适用了。
谈完了裁剪和变形对于改变CNN固定输入不行的情况下,我们很自然的想到,那CNN为什么又是非要固定输入呢?
嗨害,那是因为后面全连接层的权值矩阵是固定大小的(这个权值矩阵里面的值可以随着训练发生变化,但是权值矩阵的大小是不可以的哦),导致全连接的输入也是固定的(因为全连接嘛,可以理解为一个权值对应一个输入)。
事实上,全连接层之前的卷积层并不需要固定的图像尺寸,他可以产生任意尺寸的特征图。问题的关键是,它输入到全连接层的特征图需要固定大小,这就导致卷积层的输入也要固定大小了(卷积层是可以卷任意大小的输入,意思是对啥样的输入都能卷一卷,但是输入影响输出呀,一百八十斤的英国大力士也敢碰一碰,就是结果不一样呗)
综上所述, CNN固定尺寸的问题来源于全连接层,也是网络的最后阶段,传统的裁剪和变形也不行。我们需要一种新的算法改进这种情况,哒哒,空间金字塔池化( spatial pyramid pooling,SPP)出现了。
SPP算法原理
浅结一下
一句话先来总结一下算法的原理:SPP层对特征进行池化,并产生固定长度的输出,这个输出再喂给全连接层。
白话文为:SPP可以接受任意大小的输入的特征图,但是SPP的输出统统的给你变成一样大小的特征图。
具体做法
输入一个任意大小的特征图,SPP将特征图均匀的分成不同大小的均分块,也就是用不同大小的n*n的块来对输入的特征图进行提取,具体的做法论文给出了如下的图:
图中分别使用
1
∗
1
1*1
1∗1、
2
∗
2
2*2
2∗2、
4
∗
4
4*4
4∗4块来对输入特征进行提取,也可以理解为分别将输入的特征图分成
1
∗
1
1*1
1∗1、
2
∗
2
2*2
2∗2、
4
∗
4
4*4
4∗4的不同大小的块,但是每一块最终的描述子都是一样大小的,将这些分割好的块,再拼接在一起,就形成了全连接层的输入。图上采用的为
1
∗
1
1*1
1∗1、
2
∗
2
2*2
2∗2、
4
∗
4
4*4
4∗4的不同大小的块提取,那么最终拼接在一起的大小为
1
∗
1
+
2
∗
2
+
4
∗
4
=
21
1*1+2*2+4*4=21
1∗1+2∗2+4∗4=21,在此情况下啊,无论你输入的特征图的多大的,经过SPP之后输出的特征大小都是固定的,假定你就使用
1
∗
1
1*1
1∗1、
2
∗
2
2*2
2∗2、
4
∗
4
4*4
4∗4的不同大小的块提取,那么任何大小的特征图输入进来,输出的大小都是
21
21
21.当然我们这里说的是通道数为
1
1
1的情况下,真实情况下,还要乘上输入的通道数。
SPP算法的优点
1)SPP能在输入尺寸任意的情况下产生固定大小的输出,而在SPP出现之前在深度网络中的使用的较为先进滑窗池化(sliding window pooling)则不能;
2)SPP使用了多级别的空间箱(bin),也就是使用不同大小的块对特征图进行提起,而滑窗池化则只用了一个窗口尺寸。多级池化对于物体的变形十分鲁棒;
3)由于其对输入的灵活性,SPP可以池化从各种尺度抽取出来的特征。
SPP的代码实现
具体的代码实现可以参考上面的链接哦