原論文地址:

Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

本文結構

  1. SSPNet的動機
  2. SPP Layer的實現
  3. SPP有啥好處
  4. SPPNet用於圖像分類
  5. SPPNet用於物體檢測

一、SSPNet的動機

一般而言,對於一個CNN模型,可以將其分為兩個部分:

  1. 前面包含卷積層、激活函數層、池化層的特徵提取網路,下稱CNN_Pre
  2. 後面的全連接網路,下稱CNN_Post

許多CNN模型都對輸入的圖片大小有要求,實際上CNN_Pre對輸入的圖片沒有要求,可以簡單認為其將圖片縮小了固定的倍數,而CNN_Post對輸入的維度有要求,簡而言之,限制輸入CNN模型的圖片尺寸是為了遷就CNN_Post。

而本文的立意就在於,找到一種合適的方式,無論CNN_Pre輸出的feature maps尺寸是怎樣,都能輸出固定的維度傳給CNN_Post。如下圖,而給出的方案即SPP:空間金字塔池化

二、SPP Layer的實現

Pytorch 實現參考:

github.com/GitHberChen/

import math
import torch
from torch import nn
# https://github.com/yueruchen/sppnet-pytorch/blob/master/spp_layer.py

def spatial_pyramid_pool(self, previous_conv, num_sample, previous_conv_size, out_pool_size):

previous_conv: a tensor vector of previous convolution layer
num_sample: an int number of image in the batch
previous_conv_size: an int vector [height, width] of the matrix features size of previous convolution layer
out_pool_size: a int vector of expected output size of max pooling layer

returns: a tensor vector with shape [1 x n] is the concentration of multi-level pooling

# print(previous_conv.size())
for i in range(len(out_pool_size)):
# print(previous_conv_size)
h_wid = int(math.ceil(previous_conv_size[0] / out_pool_size[i]))
w_wid = int(math.ceil(previous_conv_size[1] / out_pool_size[i]))
h_pad = (h_wid * out_pool_size[i] - previous_conv_size[0] + 1) / 2
w_pad = (w_wid * out_pool_size[i] - previous_conv_size[1] + 1) / 2
maxpool = nn.MaxPool2d((h_wid, w_wid), stride=(h_wid, w_wid), padding=(h_pad, w_pad))
x = maxpool(previous_conv)
if (i == 0):
spp = x.view(num_sample, -1)
# print("spp size:",spp.size())
else:
# print("size:",spp.size())
spp = torch.cat((spp, x.view(num_sample, -1)), 1)
return spp

SPP的本質就是多層maxpool,只不過為了對於不同尺寸大小 a	imes a 的featur map 生成固定大小 n	imes n 的的輸出,那麼 pool_{n	imes n} 的滑窗win大小,以及步長str都要作自適應的調整:

win = ceil(a/n) \ str=floor(a/n)

ceil、floor分別表示上取整、下取整。

然後多個不同固定輸出尺寸的 Pool 組合在一起就構成了SPP Layer,在論文中就用了 pool_{5	imes 5}pool_{4	imes 4}pool_{3	imes 3}pool_{2	imes 2}pool_{1	imes 1}的組合,對於尺寸為 (c,a,a) 的feature maps,該組合的輸出為 (c,50)

三、SPP有啥好處?

對於不同尺寸的CNN_Pre輸出能夠輸出固定大小的向量當然是其最大的好處,除此之外SPP的優點還有:

  1. 可以提取不同尺寸的空間特徵信息,可以提升模型對於空間佈局和物體變性的魯棒性。
  2. 可以避免將圖片resize、crop成固定大小輸入模型的弊端。

resize、crop有啥弊端呢?一方面是resize會導致圖片中的物體尺寸變形,比如下面這個勞拉;另一方面,crop會導致圖片不同位置的信息出現頻率不均衡,例如圖片中間的部分會比角落的部分會被CNN看到更多次。

四、SPPNet用於圖像分類

將SPP層添加到原有的CNN模型中可以提高其模型表現,有趣的是,最大的提升出現在表現最好的網路Overfeat-7上,提升為top-1 的準確率提升1.65%,由於SPP層輸出不變的特性,訓練時可以採用不同尺寸的圖片,如果在 224	imes 224 的基礎上增加 180	imes 180 的尺寸進行訓練,top-1 準確率會進一步提升0.68%,但如果訓練時平均地從180~224選擇尺寸進行訓練,Overfeat-7的top-1/top-5 error 為 30.06%/10.96%,不如224	imes 224+180	imes 180下的訓練結果,原因可能是測試用圖是224解析度的,而平均地從180~224選擇尺寸稀釋了224的比例。

另外,作者還用ZFNet使用no SPP 36	imes 256 的全連接和pool_{4	imes 4}pool_{3	imes 3}pool_{2	imes 2}pool_{1	imes 1}組合的SPP輸出 30	imes 256 的維度給全連接層進行對比,有SPP層的ZFNet表現更好,證明瞭SPP-ZFNet並非靠更多的參數取勝,而是靠其本身的特性取勝。

五、SPPNet用於物體檢測

SPPNet用於物體檢測只需對圖像(每種尺寸下)做一次特徵提取,比當時的 R-CNN 快了很多,具體演算法流程如下:

  1. 使用selective search 生成2000個Proposal區域。
  2. 將圖片resize 成 s=min(w,h)in{480,576,688,864,1200} ,每種尺寸使用CNN做一次特徵提取。
  3. 對於每個Proposal找到Proposal區域大小最接近 224	imes 224 的那個尺寸,找到feature maps上對應的區域,坐上角坐標 x_{lt}=floor(x/S)+1 ,右下角坐標 x _{rb}=ceil(x/S)-1 ,其中 x 為Proposal於圖像上的像素坐標,S為feature maps 的最終Stride大小,floor、ceil分別為下取整、上取整。找到對應區域後,使用 pool_{6	imes 6}pool_{3	imes 3}pool_{2	imes 2}pool_{1	imes 1}對該區域的feature map 進行特徵提取,得到 50	imes Channel 維的特徵向量。
  4. 每一個類別都使用訓練好的二值分類SVM對這個特徵向量進行判定,or 使用全連接層+(class_num+1)路softmax進行類別判定。
  5. 邊框回歸,NMS。

具體的SVM、全連接層微調訓練細節可見原論文的4.1章,此不贅述。

SPPNet用於物體檢測的效果還是不錯的,在取得相當於R-CNN的準度的同時,速度最高提升了102x,具體對比如下列圖表:

最後,有沒有覺得SPP和Fast R-CNN的ROI Pooling有些類似?沒錯,他們是一脈相承的。

Uno Whoiam:Fast R-CNN: 變快了,也變強了 || 5分鐘看懂CV頂刊論文

PS:

廣告時間啦~理工生如何提高人文素養軟實力?快關注微信公眾號:
歡迎掃碼關注~

推薦閱讀:

相關文章