Spatial pyramid pooling in deep convolutional networks for visual recognition網絡
做者: Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sunide
引用: He, Kaiming, et al. "Spatial pyramid pooling in deep convolutional networks for visual recognition." IEEE transactions on pattern analysis and machine intelligence,37(9) (2015): 1904-1916.學習
引用次數: 399+120(Google Scholar, By 2016/11/24).測試
項目地址:spa
1 介紹.net
這是何凱明大神2015年在PAMI上發表的論文,在2014年時候已經在ECCV會議上發表過. blog
原AlexNet中(如圖1所示),conv5生成的特徵maps數目爲256個,大小爲13*13,後面緊接着是max-pooling層(pool5層),而後是fc6,fc7的全鏈接層.對於AlexNet而言,輸入圖像的大小爲224*224,實驗的時候不管你圖像的大小是多大,都要resize到這個設定的值,這樣才能保證後面的一致性.可是這樣作有個問題就是有些圖像可能與224*224相差很大,強行resize到這個尺寸會有問題,緣由有兩個: (1)這個值(224*224)的設定是人爲的,不必定是最好的;(2)將圖像強行resize到這個尺寸可能會破壞圖像本來的結構.因而就有了如今這篇文章.繼承
圖1 AlexNet網絡的結構圖get
2 SPP-net網絡結構it
2.1 SPP-net思路介紹
OK,那咱們就不對每張輸入圖像都進行resize,這樣保持了圖像的原有結構,這是個優勢! 可是這樣也會帶來問題,輸入圖像什麼大小的都有,這樣不一樣尺寸的圖像前向傳播到pool5層以後(將要進入全鏈接層時),輸出的向量的維度不相同.全鏈接層的神經元節點數目是固定的,若是pool5以後輸出的向量維度不肯定,況會使得網絡沒有辦法訓練.圖像大小雖然不一樣,可是不影響卷積層和池化層,影響的就是全鏈接層與最後一個池化層之間的鏈接,因此咱們若是想解決這個問題,就要在pool5這裏下功夫(由於它的下一層就是全鏈接層,若是這一層能對任何尺寸圖像都能輸出固定長度的特徵向量,那全鏈接層參數不須要改變,其餘的啥也都不須要改變)
圖2 SPP-net結構
爲了解決這個問題,做者提出了使用SPP層來代替網絡最後的池化層pool5,使得對於任意尺寸的conv5特徵圖(輸入圖像尺寸的不一樣表如今conv5特徵maps大小的不一樣)通過它以後都能獲得固定長度的輸出.下面咱們來看看是怎麼作到的.
其實作法很簡單: 輸入圖像的尺寸不一樣,致使conv5輸出的map尺寸也不一樣,好比224x224的輸出圖像的conv5輸出map尺寸爲13x13,180x180尺寸的輸入圖像的conv5輸出map尺寸爲10x10,如何在13x13的map和10x10的map上進行池化,使得池化後獲得的向量維度相同呢? 首先:設置3種bin(3種只是舉例,你能夠設置任意多種),分別是1x1,2x2,4x4,對於1x1的bin,不管對14x14仍是10x10,池化後的輸出數據維度都是1(它們不一樣的是前者的池化核大小爲14x14,後者爲10x10),對於2x2的bin,池化後輸出數據維度都是4(它們不一樣的也是池化核),對於4x4的bin,池化後輸出數據的維度都是16(它們不一樣的也是池化核大小),因此不管你conv5後的map大小是多少,在一張map上池化後獲得的向量維度都是1+4+16=21,這就獲得了咱們的目的:對不一樣大小的輸入圖像獲得定長輸出!!!
雖然對不一樣尺寸的輸入圖像,多級池化後的輸出向量維度是相同的,可是池化的時候對不一樣的圖像採用的池化核大小和步長倒是要自適應改變的,這點很重要,不然沒法進行下去,下面來說述如何根據map尺寸來計算池化核大小與步長來知足要求:
bin的size(在一張map上等距劃分的網格的數目)能夠設置爲n*n: 1*1,2*2,3*3,4*4,...
conv5的map大小爲a*a,好比13*13,map數目爲256個
這樣:
(1) n=1 --> win=ceil(a/n)=ceil(13/1)=13,str=floor(13/1)=13 --> 輸出256*1*1維度的向量
(2) n=2 --> win=ceil(a/n)=ceil(13/2)=7,str=floor(13/2)=6 --> 輸出256*2*2維度的向量
(3) n=3 --> win=ceil(a/n)=ceil(13/3)=5,str=floor(13/3)=4 --> 輸出256*3*3維度的向量
(3) n=4 --> win=ceil(a/n)=ceil(13/4)=4,str=floor(13/4)=3 --> 輸出256*4*4維度的向量
其中: ceil(1/3)=1; ceil(2/3)=1; floor(1/3)=0; floor(2/3)=0;
下圖展現了一個三級的金字塔池化(3x3,2x2,1x1),sizeX爲池化核大小,stride爲池化時的步長;
能夠設置多種bin,每一個bin的大小能夠設置爲1x1或2x2或3x3或4x4,...,
2.2 多尺寸輸入圖像狀況下的訓練
面對多尺寸問題時,採用交替訓練的方式,好比第一個epoch採用224x224大小的訓練圖像對Net1進行訓練,第二個epoch的時候改用180x180大小的圖像對Net2進行訓練! 依次類推.這裏要問,問什麼會有兩個Net? 其實它們能夠看作是一個,二者的差異很小,Net2的初始權重會使用上一次epoch獲得的Net1的權重(一樣,再下一次迭代Net1也要使用上次epoch獲得的Net2的權重做爲初始權重),這些權重包括SPP以前的那些卷積層的kernel權重值,以及SPP以後的全鏈接層的權重值!那麼Net1和Net2有什麼區別呢? 仍是有點小小的區別的,假設金字塔級數設置爲3級,就有3種bin,分別是1x1,2x2,4x4,那麼有:
(1) 當224x224大小的圖像進來後,conv5以後的map大小爲13x13,這時程序會根據這個map大小以及設置的三種bin來計算每種bin下對應的卷積核大小和步長,假設寫成(sizeX,stride),那麼對於這種圖像尺寸,計算出來的池化卷積核大小和步長對就是(13,13),(7,6),(5,4),用這三個對conv5層的卷積maps進行三種池化,獲得輸出向量長度爲256*(1*1+2*2+4*4)=5376(其中256爲conv5後獲得的map數目);
(2) 當180x180大小的圖像進來後,conv5以後的map大小爲10x10,這時程序會根據這個map大小以及設置的三種bin來計算每種bin下對應的卷積核大小和步長,假設寫成(sizeX,stride),那麼對於這種圖像尺寸,計算出來的池化卷積核大小和步長對就是(10,10),(5,5),(4,3),用這三個對conv5層的卷積maps進行三種池化,獲得輸出向量長度爲256*(1*1+2*2+4*4)=5376(其中256爲conv5後獲得的map數目);
每次迭代的時候用一種不一樣大小的輸入圖像,Net1和Net2惟一的不一樣就是SPP層的三個池化核的尺寸和步長的不一樣,其餘的都是繼承了上次迭代的權重參數做爲初始參數,因爲池化核自己是不帶學習參數的,所以這種方式對訓練沒有影響(仍是按照通常的方式進行訓練).實際訓練時,其實也只是訓練一個網絡,只是在SPP層的時候,要根據當前迭代時的輸入圖像大小實時調整三種池化核尺寸和步長罷了.
2.3 SPP-net用於目標檢測
SPP-net還能夠用於目標檢測,具體見原文中的第四章.
2.3.1 SPP-net訓練集構造
輸入樣本: 20個目標的訓練圖像(對於VOC數據集而言)
正樣本: 採用的是圖像上待檢測目標的GT boxes.
負樣本: 用Selective Search的方法在每張圖像上生成2000個候選區域,考量每一個候選區域與GT box之間的IoU,IoU最多爲30%的區域標定爲負樣本.同時,若是兩個負樣本之間的IoU超過了70%,則要把其中的一個去掉(很像Selective Search論文裏面的作法)
對網絡進行微調:
對CNN網絡進行微調的時候,僅僅對SPP-net後面的全鏈接層進行微調,微調時候的正樣本爲: IoU≥0.5的候選區域; 負樣本爲: IoU介於[0.1,0.5]之間的候選區域;每一個mini-batch裏面的正負樣本比例爲1:3,共訓練了250K個mini-batches.
我這裏爲何把訓練集分割三部分,這個下面會講到!
2.3.2 模型訓練和測試過程
訓練SPP-net
輸入20個類別的訓練圖像(以VOC爲例,爲輸入樣本) --> 每張圖像都resize到min(w,h)=s (resize以後圖像的最短邊等於s) --> 前向傳播,獲得conv5後的卷積maps爲256*13*13(假設) --> 將正樣本和負樣本的候選區域都映射到conv5的特徵maps上 --> 提取每一個映射後區域的多級池化特徵 --> 送入全鏈接層, 再接Softmax --> 反向傳播,迭代屢次進行訓練,獲得一個SPP-net.
訓練多個二分類SVM
在conv5的特徵maps上,全部正樣本和負樣本都映射過來了 --> 的每一類的特徵 --> 訓練20個二分類SVM
參考文獻:
[1] RCNN學習筆記(3): From RCNN to SPP-net: http://blog.csdn.net/smf0504/article/details/52744971