1. 程式人生 > >空間金字塔池化SPP改進RCNN的重要思想

空間金字塔池化SPP改進RCNN的重要思想

本文的背景是論文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》,是對RCNN的region proposal要進行大量繁雜計算的重要改進。

空間金字塔池化SPP改進RCNN的重要思想

 

一、R-CNN中region proposal的缺陷

R-CNN的候選框是通過selective search方法得到的,一張圖片大概有2k左右個region proposals,然後通過crop/warp進行處理,將每個region proposal送入CNN中進行卷積特徵的提取。

R-CNN中,要求輸入固定大小的圖片,這些圖片經過裁切(Crop)或者經過變形縮放(Warp),都在一定程度上導致圖片資訊的丟失和變形,限制了識別精確度。兩種方式如下所示。

空間金字塔池化SPP改進RCNN的重要思想

 

無論是crop還是warp,都無法保證不失真:

- crop:物體可能會被截斷,尤其是長寬比大的圖片

- warp:物體被拉伸,失去"原形",尤其是長寬比大的圖片

這兩方面的事實導致以下兩個缺陷:

  • 訓練時間非常慢,因為一張圖片產生2k左右的region proposals,都會進入CNN中進行訓練;
  • 識別準確率很低,因為產生的region proposals都會通過crop/warp操作,resize到同一大小送入CNN中進行訓練,這樣會造成圖片資訊的缺失或者變形失真,會降低圖片識別的正確率。

二、SPP空間金字塔池化的重要思想

本文提出了空間金字塔池化

Spatial Pyramid Pooling layer) 來解決這一問題,使用這種方式,可以讓網路輸入任意的圖片,而且還會生成固定大小的輸出。這樣,整體的結構和之前R-CNN有所不同。

對於第一個問題,我們能不能將一張圖片整體送入CNN中進行特徵提取,然後將一張圖片的多個region proposals對映到最後的特徵層上,形成每個region proposal的feature maps,進而加速特徵的提取;

對於第二個問題,我們能不能不resize,直接用不同大小的region proposals的feature maps?

實際上,卷積層是不需要輸入固定大小的圖片的,並且還可以生成任意大小的特徵圖,只是全連線層需要固定大小的輸入。因此,固定長度的約束僅限於全連線層。

分析如下:

CNN大體包含3部分,卷積、池化、全連線。

卷積:卷積操作對圖片輸入的大小會有要求嗎?比如一個5*5的卷積核,輸入的圖片是30*81的大小,可以得到(26,77)大小的圖片,並不會影響卷積操作。輸入600*500,它還是照樣可以進行卷積,也就是卷積對圖片輸入大小沒有要求。任意大小的圖片進入,都可以進行卷積。

池化:池化對圖片大小會有要求嗎?比如我池化大小為(2,2)我輸入一張30*40的,那麼經過池化後可以得到15*20的圖片。輸入一張53*22大小的圖片,經過池化後,我可以得到26*11大小的圖片。因此池化這一步也沒對圖片大小有要求。輸入任意大小的圖片,都可以進行池化。

全連線層:既然池化和卷積都對輸入圖片大小沒有要求,那麼就只有全連線層對圖片結果有要求了。因為全連線層連線權值矩陣的大小W,經過網路訓練後,大小就固定了。比如我們從卷積到全連層,輸入和輸出的大小,分別是50、30,那麼權值矩陣50×30大小的矩陣了。因此空間金字塔池化,要解決的就是從卷積層到全連線層之間的一個過度。

也就是說,在最後一個卷積層與第一個全連線層(fc)之間需要訓練一個大小固定的二維陣列,這樣可以得到的特徵更完整一些,提高了定位與識別的準確率。如下圖所求:

空間金字塔池化SPP改進RCNN的重要思想

 

三、SPP的具體實現過程

SPP為的就是解決上述的問題,做到的效果為:不管輸入的圖片是什麼尺度,都能夠正確的傳入網路.

空間金字塔池化SPP改進RCNN的重要思想

 

具體方案如下圖所示:

不管最後一個卷積層得到的特徵圖(feature maps)的大小,都可將其轉化為了(4*4+2*2+1*1)*256的全連線層,也就是這些特徵圖的大小不同,但通道是相同的,那麼如何將不同大小的特徵圖進行spp 呢?

假設輸入的大小為a*a*c,然後呢,這些特徵圖分別被分成了[1*1,2*2,4*4]大小的塊,期望的輸出為1*1*c,2*2*c,4*4*c,變形為(1*1+2*2+4*4)*c的二維陣列,這全部是通過池化操作實現的,不過池化層的size和stride是不同的,具體有如下:

輸入為[a,a],輸出為[n,n],那麼pool_size= n/a ⌉ ,stride=⌊ n/a⌋ ,這樣我們就將其轉化為了n*n*c的矩陣,例如13*13、10*10要轉化為4*4的大小,那麼採用[p_s=4,,s=3],[p_s=3,s=2]的池化操作後便可以得到。

如果原圖輸入是227x227,對於conv5出來後的輸出,是13x13x256的,可以理解成有256個這樣的filter,每個filter對應一張13x13的啟用圖。

如果像上圖那樣將啟用圖池化成4x4 2x2 1x1三張子圖,做max pooling後,出來的特徵就是固定長度的(16+4+1)x256那麼多的維度了.如果原圖的輸入不是227x227,出來的特徵依然是(16+4+1)x256;直覺地說,可以理解成將原來固定大小為(3x3)視窗的pool5改成了自適應視窗大小,視窗的大小和啟用成比例,保證了經過pooling後出來的feature的長度是一致的.

如果要金字塔的某一層輸出n x n個特徵,只需要用視窗大小為:(w/n,h/n)進行池化即可。

當我們有很多層網路的時候,網路輸入的是一張任意大小的圖片,這個時候我們可以一直進行卷積、池化,直到即將與全連線層連線的時候,就要使用金字塔池化,使得任意大小的特徵圖都能夠轉換成固定大小的特徵向量,這就是空間金字塔池化的奧妙之處!