天天看點

R-FCN學習總結

文章目錄

    • 簡介
    • 網絡結構
      • Position-Sensitive Score Map解析
        • 留坑(懂的老哥希望能不吝賜教)
      • Position-Sensitive Rol Pooling解析
      • Position-Sensitive Regression解析
    • 網絡的訓練
    • 損失函數
    • 其他
    • References

簡介

R-FCN——Object Detection via Region-based Fully Convolutional Networks,這篇文章提出了一種高效簡潔的目标檢測模型 R-FCN(Region-based Fully Convolutional Networks ),作者将全卷積網絡FCN(Fully Convolutional Network)應用于 Faster R-CNN,實作了整個網絡的計算共享,極大的提高了檢測速度,同時精度也可以與 Faster R-CNN相媲美。文章提出一種 position-sensitive score maps 用來平衡平移不變性(translation-invariance )和平移可變性(translation-variance )之間的沖突,模型使用了 全卷積的 ResNet 結構,保證高檢測精度的同時,将檢測速度提高了 2.5~20倍。

注:本文内容大多摘自知乎文章并按照自己了解修改、添加部分内容,灰常感謝各位大佬無私分享!

這篇論文不是太容易讀懂,首先我們要明白兩個概念:(預警,文章略長,請耐心閱讀)

  • 分類網絡的位置不敏感性:簡單來講,對于分類任務而言,我希望我的網絡有一個很好地分類性能,随着某個目标在圖檔中不斷的移動,我的網絡仍然可以準确的将圖檔區分為對應的類别。實驗表明,深的全卷積網絡能夠具備這個特性,如ResNet-101等。
  • 檢測網絡的位置敏感性:簡單來講,對于檢測任務而言,我希望我的網絡有一個好的檢測性能,可以準确的輸出目标所在的位置值。随着某個目标的移動,我們希望網絡的檢測結果能夠和它一起移動,仍然能夠準确的檢測到它,即我對目标位置的移動很敏感。我們需要計算對應的偏內插補點,需要計算預測邊框和GT的重合率等。但是,深的全卷積網路不具備這樣的一個特征。

總之,分類網絡的位置不敏感性和檢測網絡的位置敏感性是一個沖突問題,而我們的目标檢測中不僅要分類也要定位,那麼如何解決這個問題呢,R-FCN提出了Position-sensitive score maps來解決這個問題;

下面我們來說一下R-FCN的設計動機:(摘自知乎)

Faster R-CNN是首個利用CNN來完成proposals預測的,從此之後很多的目标檢測網絡都開始使用Faster R-CNN的思想。而Faster R-CNN系列的網絡都可以分成2個部分:ROI Pooling之前的共享全卷積網絡和ROI Pooling之後的ROI-wise子網絡(用來對每個ROI進行特征提出,并進行回歸和分類)。第1部分就是直接用普通分類網絡的卷積層,用來提取共享特征,然後利用ROI Pooling在最後一層網絡形成的feature map上面提取針對各個RoIs的特征向量,然後将所有RoIs的特征向量都交給第2部分來處理(即所謂的分類和回歸),而第二部分一般都是一些全連接配接層,在最後有2個并行的loss函數:softmax和smoothL1,分别用來對每一個RoI進行分類和回歸,這樣就可以得到每個RoI的真實類别和較為精确的坐标資訊啦(x, y, w, h)。

需要注意的是第1部分通常使用的都是像VGG、GoogleNet、ResNet之類的基礎分類網絡,這些網絡的計算都是所有RoIs共享的,在一張圖檔上面進行測試的時候隻需要進行一次前向計算即可。而對于第2部分的RoI-wise subnetwork,它卻不是所有RoIs共享的,主要的原因是因為這一部分的作用是“對每個RoI進行分類和回歸”,是以不能進行共享計算。 那麼問題就出在這裡,首先第1部分的網絡具有“位置不敏感性”,而如果我們将一個分類網絡比如ResNet的所有卷積層都放置在第1部分用來提取特征,而第2部分則隻剩下全連接配接層,這樣的目标檢測網絡是位置不敏感的translation-invariance,是以其檢測精度會較低,而且這樣做也會浪費掉分類網絡強大的分類能力(does not match the network’s superior classification accuracy)。而ResNet論文中為了解決這個問題,做出了一點讓步,即RoI Pooling層不再放置在ResNet-101網絡的最後一層卷積層之後而是放置在了“卷積層之間”,這樣RoI Pooling Layer之前和之後都有卷積層,并且RoI Pooling Layer之後的卷積層不是共享計算的,它們是針對每個RoI進行特征提取的,是以這種網絡設計,其RoI Pooling層之後就具有了位置敏感性translation-variance,但是這樣做會犧牲測試速度,因為所有的RoIs都需要經過若幹層卷積計算,這樣會導緻測試速度很慢。R-FCN就是針對這個問題提出了自己的解決方案,在速度和精度之間進行折中。

網絡結構

R-FCN的網絡結構圖如下:

R-FCN學習總結

首先,我們來分析一下R-FCN算法的整個運作步驟,使得我們對整個算法有一個宏觀的了解,接下來再對不同的細節進行詳細的分析:

  • 首先,我們選擇一張需要處理的圖檔,并對這張圖檔進行相應的預處理操作;
  • 接着,我們将預處理後的圖檔送入一個預訓練好的分類網絡中(這裡使用了ResNet-101網絡的Conv4之前的網絡),固定其對應的網絡參數;(提特征)
  • 接着,在預訓練網絡的最後一個卷積層獲得的feature map上存在3個分支(全文就圍照這三個分支來講!mark!),第1個分支就是在該feature map上面進行RPN操作,獲得相應的ROI(就是RPN層獲得proposal映射到feature map上的區域);第2個分支就是在該feature map上獲得一個 k ∗ k ∗ ( C + 1 ) k*k*(C+1) k∗k∗(C+1)維的位置敏感得分圖(position-sensitive score map),用來進行分類;第3個分支就是在該feature map上獲得一個 4 ∗ k ∗ k 4*k*k 4∗k∗k維的位置敏感得分圖(position-sensitive score map),用來進行回歸;(後面會詳細講)
  • 最後,在 k ∗ k ∗ ( C + 1 ) k*k*(C+1) k∗k∗(C+1)維的位置敏感得分圖和 4 ∗ k ∗ k 4*k*k 4∗k∗k維的位置敏感得分圖上面分别執行位置敏感的ROI池化操作(Position-Sensitive Rol Pooling,這裡使用的是平均池化操作),獲得對應的類别和位置資訊。

這樣,我們就可以在測試圖檔中獲得我們想要的類别資訊和位置資訊啦。(檢測任務)

Position-Sensitive Score Map解析

上圖是R-FCN的網絡結構圖,其主要設計思想就是“位置敏感得分圖position-sensitive score map”。現在我們來解釋一下其設計思路。如果一個RoI(就是feature map上的一個區域,region of interest)中含有一個類别C的物體,我們将該RoI劃分為 k ∗ k k*k k∗k個區域,其分别表示該物體的各個部位,比如假設該RoI中含有的目标是人, k = 3 k=3 k=3,那麼就将“人”劃分成了9個子區域,top-center區域毫無疑問應該是人的頭部,而bottom-center應該是人的腳部,我們将RoI劃分為K*K個子區域是希望這個RoI在其中的每一個子區域都應該含有該類别C的物體的各個部位,即如果是人,那麼RoI的top-center區域就應該含有人的頭部。當所有的子區域都含有各自對應的該物體的相應部位後,那麼分類器才會将該RoI判斷為該類别。也就是說物體的各個部位和RoI的這些子區域是“一一映射”的對應關系。

OK, 現在我們知道了一個RoI必須滿足 k ∗ k k*k k∗k個子區域都含有該物體的相應部位,我們才能判斷該RoI屬于該物體,如果該物體的很多部位都沒有出現在相應的子區域中,那麼就該RoI判斷為背景類别。 那麼 現在的問題就是網絡如何判斷一個RoI的 k ∗ k k*k k∗k個子區域都含有相應部位呢? 前面我們是假設知道每個子區域是否含有物體的相應部位,那麼我們就能判斷該RoI是屬于該物體還是屬于背景。那麼現在我們的任務就是 判斷RoI子區域是否含有物體的相應部位 。

這其實就是position-sensitive score map設計的核心思想了。R-FCN會在共享卷積層的最後一層網絡上接上一個卷積層,而該卷積層就是位置敏感得分圖position-sensitive score map。該score map的含義如下所述: 首先它就是一層卷積層,它的 h e i g h t height height和 w i d t h width width和共享卷積層的一樣(即具有同樣的感受野),但是它的通道數為 k ∗ k ∗ ( C + 1 ) k*k*(C+1) k∗k∗(C+1)。其中 C C C表示物體類别種數,再加上1個背景類别,是以共有 ( C + 1 ) (C+1) (C+1)類,而每個類别都有 k ∗ k k*k k∗k個score maps。現在我們隻針對其中的一個類别來進行說明,假設我們的目标屬于人這個類别,那麼其有 k ∗ k k*k k∗k 個score maps,每一個score map表示原始圖像中的哪些位置含有人的某個部位,該score map會在含有對應的人體的某個部位的位置有高的響應值,也就是說每一個score map都是用來描述人體的其中一個部位出現在該score map的何處,而在出現的地方就有高響應值”。既然是這樣,那麼我們隻要将RoI的各個子區域對應到屬于人的每一個score map(論文中預設 k ∗ k = 9 k*k = 9 k∗k=9個)上然後擷取它的響應值就好了。但是要注意的是,由于一個score map都是隻屬于一個類别的一個部位的(注意是一個部位,論文預設把物體分為9個部位),是以RoI的第 i個子區域一定要到第i張score map的對應區域去尋找響應值,因為RoI的第i個子區域需要的部位和第i張score map關注的部位是對應的。那麼現在該RoI的 k ∗ k k*k k∗k個子區域都已經分别在屬于人的 k ∗ k k*k k∗k個score maps上找到其響應值了,那麼如果這些響應值都很高,那麼就證明該RoI是人呀。當然這有點不嚴謹,因為我們隻是在屬于人的 k ∗ k k*k k∗k個score maps上找響應值,我們還沒有到屬于其它類别的score maps上找響應值呢,萬一該RoI的各個子區域在屬于其它類别的score maps上的響應值也很高,那麼該RoI就也有可能屬于其它類别呢?這就會涉及到一個比較的問題,哪個類别的響應值高,我就将它判斷為哪一類目标。它們的響應值同樣高(這裡應該指相等)這個情況發生的幾率很小,我們不做讨論。

以上就是position-sensitive score map的全部思想了。(大佬就是大佬呀,再次推薦文章,膜……)

留坑(懂的老哥希望能不吝賜教)

BTW這裡我一直對這句話有一個疑問:“是以RoI的第 i個子區域一定要到第i張score map上去尋找對應區域的響應值,因為RoI的第i個子區域需要的部位和第i張score map關注的部位是對應的”。比如我們還是檢測一個人,将其分為9個部分,對于一個站立的人來說,他的頭部在ROI的第2個部分,那麼就應該去第2張score map的對應區域找響應值;而如果是一個倒立的人,他的頭部會在ROI的第8個部分,那麼就應該去第8張score map的對應區域找響應值;這裡就會出問題了:通常來講第2張score map關注的人的頭部,第8張score map關注的是人的腳部,去第8張score map找人的頭部的響應值應該會出問題吧???可能我了解的有錯,如果沒錯的話,這應該是R-FCN的一個缺陷吧?(留坑,沒怎麼想明白,懂的老哥希望能不吝賜教)

Position-Sensitive Rol Pooling解析

上面我們隻是簡單的講解了一下ROl的 k ∗ k k*k k∗k個子區域在各個類别的score maps上(在相應位置)找到其每個子區域的響應值,我們并沒有詳細的解釋這個“找到”是如何找的?這就是位置敏感Rol池化操作(Position-sensitive RoI pooling),其字面意思是池化操作是位置敏感的,現在就來解釋“池化操作是怎麼個位置敏感法”。

R-FCN學習總結

如上圖所示,通過RPN提取出來的RoI區域,其是包含了 x , y , w , h x,y,w,h x,y,w,h的4個值,也就是說不同的RoI區域能夠對應到score map的不同位置上,而一個RoI會被劃分成 k ∗ k k*k k∗k個bins(也就是子區域。每個子區域bin的高寬分别是 h k \frac{h}{k} kh​ 和 w k \frac{w}{k} kw​ ),每個bin都對應到相應score map上的某一個子區域。既然該RoI的每個bin都對應到相應score map上的某一個子區域,那麼池化操作就是在該bin對應的score map上的子區域執行,且執行的是平均池化。我們在前面已經講了,第i個bin應該在第i個score map的對應區域上尋找響應值,那麼也就是在第i個score map上的“該第i個bin對應的位置”上進行平均池化操作。并且由于我們有 ( C + 1 ) (C+1) (C+1)個類别,是以每個類别都要進行相同方式的池化操作,是以我們會得到一個 ( C + 1 ) (C+1) (C+1)個channel的特征圖,如下圖所示:

R-FCN學習總結

平均池化操作的計算方式如下:(符号的具體含義還是自己看論文吧,太費勁了嘤嘤嘤。。。。。。不過看不懂略過也行,不要緊)

r c ( i , j ∣ Θ ) = ∑ ( x , y ) ∈ bin ⁡ ( i , j ) z i , j , c ( x + x 0 , y + y 0 ∣ Θ ) / n r_{c}(i, j | \Theta)=\sum_{(x, y) \in \operatorname{bin}(i, j)} z_{i, j, c}\left(x+x_{0}, y+y_{0} | \Theta\right) / n rc​(i,j∣Θ)=(x,y)∈bin(i,j)∑​zi,j,c​(x+x0​,y+y0​∣Θ)/n

上圖已經很明顯地畫出了池化的方式:對于每個類别,它都有 k ∗ k k*k k∗k個score maps。那麼按照上述的池化方式,ROI針對某類别可以獲得 k ∗ k k*k k∗k個值,因為一共有 ( C + 1 ) (C+1) (C+1)個類别,是以一個RoI就可以得到 k ∗ k ∗ ( C + 1 ) k*k*(C+1) k∗k∗(C+1)個值,這就是上圖得到的特征圖。那麼對于每個類别,該類别的 k ∗ k k*k k∗k個值都表示該RoI屬于該類别的響應值(表示該類别的 k ∗ k k*k k∗k個部分的響應值),那麼将這 k ∗ k k*k k∗k個數相加就得到該類别的score。按上述方法一共可以得到 ( C + 1 ) (C+1) (C+1)個scores,那麼在這 ( C + 1 ) (C+1) (C+1)個數上面使用簡單的softmax函數就可以得到各個類别的機率了(注意,這裡不需要使softmax分類器了,隻需要使用簡單的softmax函數即可,因為這裡就是通過簡單的比大小來判斷最終的類别的,下面的兩個公式就表示了這個過程)。

r c ( Θ ) = ∑ i , j r c ( i , j ∣ Θ ) r_{c}(\Theta)=\sum_{i, j} r_{c}(i, j | \Theta) rc​(Θ)=i,j∑​rc​(i,j∣Θ)

s c ( Θ ) = e r c ( Θ ) / ∑ c ′ = 0 C e r c ′ ( Θ ) s_{c}(\Theta)=e^{r_{c}(\Theta)} / \sum_{c^{\prime}=0}^{C} e^{r_{c^{\prime}}}(\Theta) sc​(Θ)=erc​(Θ)/c′=0∑C​erc′​(Θ)

Position-Sensitive Regression解析

前面的position-sensitive score map和Position-sensitive RoI pooling得到的值是用來分類的,那麼自然需要相應的操作得到對應的值來進行回歸操作。按照“position-sensitive score map”+“Position-sensitive RoI pooling”的思路,其會讓每一個RoI得到 ( C + 1 ) (C+1) (C+1)個數作為每個類别的score,那麼現在每個RoI還需要 4個數作為“回歸偏移量”,也就是 x , y , w , h x,y,w,h x,y,w,h的偏移量。是以仿照分類設計的思想,我們還需要一個類似于position-sensitive score map的用于回歸的score map。那麼應該如何設定這個score map呢?論文中給出了說明:即在ResNet的共享卷積層的最後一層上面連接配接一個與position-sensitive score map并行的score maps,該score maps用來進行regression操作,我們将其命名為regression score map。該regression score map的次元應當是 k ∗ k ∗ 4 k*k*4 k∗k∗4 ,然後經過Position-sensitive RoI pooling操作後,每一個RoI就能得到4個值作為該RoI的 x , y , w , h x,y,w,h x,y,w,h的偏移量了,其思路和分類完全相同,在此不再贅述。(要自己想清楚呀~)

網絡的訓練

這種有高響應值現在隻是作者自己在yy的啊,如果網絡不滿足這一點的話,那麼前的所有分析都gg了啊。好,現在我們就大緻解釋一下為什麼訓練該網絡能夠讓網絡最終滿足這一點。首先根據網絡的loss公式(loss決定模型的學習方向,損失函數後面會給),如果一個RoI含有人這個物體,那麼該RoI通過“position-sensitive score map”+“position-sensitive RoI pooling”得到的 ( C + 1 ) (C+1) (C+1)個值中的屬于人的那個值必然會在softmax損失函數的要求下“變得盡量的大”,那麼如何才能使得屬于人的這個值盡量的大呢?那麼我們現在就要想想屬于人的這個預測值是怎麼來的? 在前面的分析,我們已經知道它是通過Position-sensitive RoI pooling這種池化操作的來的(這裡我們要明确一點:池化和softmax是沒有學習參數的,是以我們設計loss的時候隻需要關注前面的部分),那麼也就是說使得 ( C + 1 ) (C+1) (C+1)個值中屬于人的那個值盡量大,必然會使得position-sensitive score map中屬于人的那個score map上的“該RoI對應的位置區域的平均值”盡量大,進而也就是該score map上在該區域上的響應值盡量大。因為隻有該區域的響應值大了,才能使得預測為人的機率大,才會降低softmax的loss。(還是那句話,loss決定模型的學習方向,你想讓模型學什麼,你就得設計什麼樣的loss)

PS:不得不說一句,作者思路是真牛13!

隻要設計一個合适的loss,給模型學習的方向(即讓某物體在對應score map上的對應區域的響應值盡量大),這種end-to-end的訓練就會達到這一目的,下面拿論文中的圖示舉例:(相當形象呀,有木有~)

R-FCN學習總結

(這一部分有點啰嗦了,可忽略。)如上圖所示,我們同樣可以得出以上的結論。如Figure 3所示,我們輸入了一張含有一個小孩的圖檔,圖中黃色的BBox表示我們檢測到的目标,也就是我們的一個ROI。接下來是9張位置敏感的得分圖(在這裡使用的是3x3的特征映射),這9張圖分别表示對人這個目标的top-left、top-center、… bottom-right不同區域敏感的得分圖。對應到圖中就是将這個ROI分為9個子區域,每一個子區域其實大緻上對應到了小孩的不同部位,而不同的部位一般都會有其獨特的特征存在。9個區域敏感得分圖分别對人的不同的部位比較敏感(所謂的敏感就是說如果這個子區域中存在該目标的某個部位特征時,其才會輸出較大的響應值,否則的話隻會輸出較小的響應值)。Figure 3中的9個得分圖對ROI中劃分的對應子區域都比較敏感(都有很強的響應值,越白表示響應越大,越黑表示響應越小),即ROI中的9個子區域都有較大的響應值。然後進行位置敏感池化操作,最後進行Vote操作,由于9個區域中基本上都有很高的響應值,最後投票通過,認為這個ROI中的對象是一個person。同理,可以得出Figure 4是一個背景類。(Figure 4的位置敏感ROI池化中有5個區域是黑色的,即表示具有較低的響應值,隻有4個區域比較高,即表示具有較高的響應值,根據Vote機制,就将其分類為背景類)。

損失函數

網路的損失函數如下:

L ( s , t x , y , w , h ) = L c l s ( s c ∗ ) + λ [ c ∗ > 0 ] L r e g ( t , t ∗ ) L\left(s, t_{x, y, w, h}\right)=L_{c l s}\left(s_{c^{*}}\right)+\lambda\left[c^{*}>0\right] L_{r e g}\left(t, t^{*}\right) L(s,tx,y,w,h​)=Lcls​(sc∗​)+λ[c∗>0]Lreg​(t,t∗)

這個Loss就是兩階段目标檢測架構常用的形式。包括一個分類Loss和一個回歸Loss。 λ \lambda λ用來平衡兩者的重要性。對于任意一個RoI,我們需要計算它的softmax損失,和當其不屬于背景時的回歸損失。這很簡單,因為每個RoI都被指定屬于某一個GT box或者屬于背景,即先選擇和GT box具有最大重疊率(IOU)的Rol,然後在剩餘的Rol中選擇與GT box的重疊率值大于0.5的Rol進行比對操作,最後将剩餘的Rol都歸為背景類。那麼RoI有了label後,loss自然很容易計算出來。(有監督學習)

R-FCN的訓練政策也是采用的Faster R-CNN中的4-step alternating training進行訓練的。

其他

  • online hard example mining

    這個方法是目标檢測架構中經常會用到的一個tricks,其主要的思路如下所示:首先對RPN獲得的候選ROI(正負樣本分别進行排序)進行排序操作;然後在含有正樣本(目标)的ROI中選擇前N個ROI,将正負樣本的比例維持在1:3的範圍内,基本上保證每次抽取的樣本中都會含有一定的正樣本,都可以通過訓練來提高網絡的分類能力。如果不進行此操作的話,很可能會出現抽取的所有樣本都是負樣本(背景)的情況,這樣讓網絡學習這些負樣本,會影響網絡的性能。

  • Atrous algorithm(Dilated Convolutions或者膨脹卷積)

    這個不多解釋了,不太懂的搜一下吧,其目的就是為了擴大感受野。

    R-FCN學習總結
  • 測試時的tricks

    在測試的時候,為了減少RoIs的數量,作者在RPN提取階段就将RPN提取的大約2W個proposals進行過濾:

    • 去除超過圖像邊界的proposals
    • 使用基于類别機率且門檻值IoU=0.7的NMS過濾
    • 按照類别機率選擇top-N個proposals
    是以在測試的時候,一般隻剩下300個RoIs,當然這個數量是一個超參數。并且在R-FCN的輸出300個預測框之後,仍然要對其使用NMS去除備援的預測框。

done~

References

  • https://arxiv.org/pdf/1605.06409v2.pdf
  • https://zhuanlan.zhihu.com/p/30867916
  • https://blog.csdn.net/WZZ18191171661/article/details/79481135
  • https://zhuanlan.zhihu.com/p/24780433
  • https://link.zhihu.com/?target=https%3A//arxiv.org/pdf/1412.7062.pdf

繼續閱讀