轉載自:目標檢測:SPP-net 地址 https://blog.csdn.net/tinyzhao/article/details/53717136
上文說到R-CNN的最大瓶頸是2k個候選區域都要經過一次CNN,速度非常慢。Kaiming He大神最先對此作出改進,提出了SPP-net,最大的改進是只需要將原圖輸入一次,就可以得到每個候選區域的特征。
概述
在R-CNN中,候選區域需要進過變形縮放,以此適應CNN輸入,那么能不能修改網絡結構,使得任意大小的圖片都能輸入到CNN中呢?作者提出了spatial pyramid pooling結構來適應任何大小的圖片輸入。
網絡結構
為什么CNN需要固定輸入大小?卷積層和池化層的輸出尺寸都是和輸入尺寸相關的,它們的輸入是不需要固定圖片尺寸的,真正需要固定尺寸的是最后的全連接層。
由於FC層的存在,普通的CNN通過固定輸入圖片的大小來使得全連接層輸入固定。作者不這樣思考,既然卷積層可以適應任何尺寸,那么只需要在卷積層的最后加入某種結構,使得后面全連接層得到的輸入為固定長度就可以了。這個結構就是spatial pyramid pooling layer:
在最后的卷積層和全連接層之間加入SPP層。具體做法是,在conv5層得到的特征圖是256層,每層都做一次spatial pyramid pooling。先把每個特征圖分割成多個不同尺寸的網格,比如網格分別為4*4、2*2、1*1,然后每個網格做max pooling,這樣256層特征圖就形成了16*256,4*256,1*256維特征,他們連起來就形成了一個固定長度的特征向量,將這個向量輸入到后面的全連接層。
訓練
這樣的網絡怎么訓練呢?對於圖片分類任務而言,如果圖片大小固定,那么SPP層每個金字塔的大小是可以提前計算的,根據conv5的尺寸計算出每次池化的步長和窗口大小。如果圖片大小不固定呢,將圖片變為不同的尺寸224*224和180*180,因為池化層是沒有參數的,步長和窗口大小是提前計算得到的,兩種尺寸的網絡是共享了所有的參數。使用兩種尺寸圖片輪流訓練網絡,更新參數。作者發現多尺寸和單尺寸收斂速度是差不多的。兩種尺寸是訓練時候的策略,在測試的時候,不管什么尺寸的輸入,直接使用訓練好的參數計算。
檢測
上面說的都是分類問題,下面說SPP在檢測問題中的應用。
對卷積層可視化發現:輸入圖片的某個位置的特征反應在特征圖上也是在相同位置。基於這一事實,對某個ROI區域的特征提取只需要在特征圖上的相應位置提取就可以了。
一張任意尺寸的圖片,在最后的卷積層conv5可以得到特征圖。根據Region proposal步驟可以得到很多候選區域,這個候選區域可以在特征圖上找到相同位置對應的窗口,然后使用SPP,每個窗口都可以得到一個固定長度的輸出。將這個輸出輸入到全連接層里面。這樣,圖片只需要經過一次CNN,候選區域特征直接從整張圖片特征圖上提取。在訓練這個特征提取網絡的時候,使用分類任務得到的網絡,固定前面的卷積層,只微調后面的全連接層。
在檢測的后面模塊,仍然和R-CNN一樣,使用SVM和邊框回歸。SVM的特征輸入是FC層,邊框回歸特征使用SPP層。
總結
SPP-net對R-CNN最大的改進就是特征提取步驟做了修改,其他模塊仍然和R-CNN一樣。特征提取不再需要每個候選區域都經過CNN,只需要將整張圖片輸入到CNN就可以了,ROI特征直接從特征圖獲取。和R-CNN相比,速度提高了百倍。
SPP-net缺點也很明顯,CNN中的conv層在微調時是不能繼續訓練的。它仍然是R-CNN的框架,離我們需要的端到端的檢測還差很多。既然端到端如此困難,那就先統一后面的幾個模塊吧,把SVM和邊框回歸去掉,由CNN直接得到類別和邊框可不可以?於是就有了Fast R-CNN。