R-CNN 要求把每个 region proposal 做变换到标准的 224*224 大小,这是因为 CNN 中最后的全连接层需要固定的输入大小。SPP-net 可以消除这个限制。它使用了一个叫做 spatial pyramid pooling 空间金字塔池化的策略。同时,原先的 R-CNN 由于之前所述的那个要求,只能对每一个 region 去做 CNN 提取特征,现在则可以先对原图预处理经过 CNN 得到特征图,再在特征图上提取对应 region 的特征过 SPP 层,这样可以大幅提升效率。
网络结构·
卷积层·
首先还是正常的卷积用于提取特征。按照往常习惯用 5 层卷积层,其中有些卷积层之后也跟着池化层。得到我们的 feature maps
SPP Layer·
feature map 的大小是跟输入图片的大小相关的。SPP 层需要把不同大小的 feature map 转化到相同大小的向量。这一层替换掉了原先五层卷积层网络中的最后一层卷积层后面跟着的池化层。普通的池化层是对每个固定大小的块做池化,比如取该块内的最大值。这样,池化层之后得到的东西的大小是跟输入相关的。现在我们让池化之后的大小固定,改变池化时每个块的大小。
设最后一层卷积层的 channel 数量为 k,现在我们一共分 M 个池化块,则 SPP 层之后就会得到一个 kM 大小的向量。

如图中所示,用不同块数的池化,将得到的结果拼到一起。对于固定块数的池化,比如 4 块的池化,我们可以计算出每一块的大小。
网络的训练·
首先在单一尺度的输入上训练。SPP-net 就是先在 224*224 的标准尺寸的输入上训练。
然后考虑加入尺度。SPP-net 考虑的是 180*180 和 224*224 这两种尺度。首先使用缩放,将 224*224 的尺寸变换为 180*180,然后通过调整池化块的大小,让这两个尺寸的 SPP 层的输出是相同的 size。这样,之后可以使用相同的参数。也可以理解为共享参数的两个固定尺寸的网络。
实际训练中是两个尺寸来回切换,每个 epoch 使用其中一个,共享网络参数。
测试阶段则可以直接用各种尺寸的输入进行测试。
SPP-net 用于物体检测·
只在整张图像上抽取一次特征。然后在每个特征图的候选窗口上应用空间金字塔池化,形成这个窗口的一个固定长度表示。
检测算法流程·
首先使用 selective search 产生 2k 个 region proposal,然后缩放图像以满足 min(w,h)=s
从整张图像中提取 feature map
对于每个 region,用一个四级的 SPP layer: 1×1,2×2,3×3,6×6,一共 50 块池化块。这样得到一个 12800 维的表示。传给全连接层,然后对于每个类训练一个二分类的 SVM。
通过多尺度的特征提取,可以改进:
将图像缩放成不同大小,对每一个计算对应的特征图。对于每一个 region,我们选择一个池化尺度,让缩放后的像素数量接近 224×224。