1. 程式人生 > >R-FCN詳解

R-FCN詳解

論文題目:R-FCN: Object Detection via Region-based Fully Convolutional Networks 

論文連結:論文連結

論文程式碼:Caffe版本連結地址;Python版本連結地址;Deformable R-FCN版本連結地址

一、R-FCN初探

1. R-FCN貢獻

提出Position-sensitive score maps來解決目標檢測的位置敏感性問題;
區域為基礎的,全卷積網路的二階段目標檢測框架;
比Faster-RCNN快2.5-20倍(在K40GPU上面使用ResNet-101網路可以達到 0.17 sec/image);
2. R-FCN與傳統二階段網路的異同點

圖1 R-FCN與傳統二階段網路的異同點
相同點:首先,兩者二階段的檢測框架(全卷積子網路+RoI-wise subnetwork); 其次兩者最終輸出的結果都是相應的類別和對應的BB;
不同點:
如上圖所示,我們可以看到和Faster R-CNN相比,R-FCN具有更深的共享卷積網路層,這樣可以獲得更加抽象的特徵;同時,它沒有RoI-wise subnetwork,不像Faster R-CNN的feature map左右都有對應的網路層,它是真正的全卷積網路架構;從圖中的表格可以看出Faster R-CNN的共享卷積子網路是91層,RoI-wise子網路是10層,而R-FCN只有共享卷積子網路,深度為101層。與R-CNN相比,最大的不同就是直接獲得整幅影象的feature map,再提取對應的ROI,而不是直接在不同的ROI上面獲得相應的feature map。

3. 分類網路的位置不敏感性和檢測網路的位置敏感性
我在很多相關的檢測論文中都看到這兩個概念,但是一直都沒有理解其真正的含義,相信很多朋友們也有同樣的困惑,所以我在這裡解釋一下。


圖2 分類網路的位置不敏感性和檢測網路的位置敏感性

分類網路的位置不敏感性:簡單來講,對於分類任務而言,我希望我的網路有一個很好地分類效能,隨著某個目標在圖片中不斷的移動,我的網路仍然可以準確的將你區分為對應的類別。如上圖左邊所示,不管你這隻鳥在圖片中如何移動,我的分類網路都想要準確的將你分類為鳥。即我的網路有很好地區分能力。實驗表明,深的全卷積網路能夠具備這個特性,如ResNet-101等。
檢測網路的位置敏感性:簡單來講,對於檢測任務而言,我希望我的網路有一個好的檢測效能,可以準確的輸出目標所在的位置值。隨著某個目標的移動,我的網路希望能夠和它一起移動,仍然能夠準確的檢測到它,即我對目標位置的移動很敏感。我需要計算對應的偏差值,我需要計算我的預測和GT的重合率等。但是,深的全卷積網路不具備這樣的一個特徵。
總之,分類網路的位置不敏感性和檢測網路的位置敏感性的一個矛盾問題,而我們的目標檢測中不僅要分類也要定位,那麼如何解決這個問題呢,R-FCN提出了Position-sensitive score maps來解決這個問題;

4. 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架構分析

1. R-FCN演算法步驟

圖3 R-FCN演算法步驟

如圖所示,我們先來分析一下R-FCN演算法的整個執行步驟,使得我們對整個演算法有一個巨集觀的理解,接下來再對不同的細節進行詳細的分析。

首先,我們選擇一張需要處理的圖片,並對這張圖片進行相應的預處理操作;
接著,我們將預處理後的圖片送入一個預訓練好的分類網路中(這裡使用了ResNet-101網路的Conv4之前的網路),固定其對應的網路引數;
接著,在預訓練網路的最後一個卷積層獲得的feature map上存在3個分支,第1個分支就是在該feature map上面進行RPN操作,獲得相應的ROI;第2個分支就是在該feature map上獲得一個K*K*(C+1)維的位置敏感得分對映(position-sensitive score map),用來進行分類;第3個分支就是在該feature map上獲得一個4*K*K維的位置敏感得分對映,用來進行迴歸;
最後,在K*K*(C+1)維的位置敏感得分對映和4*K*K維的位置敏感得分對映上面分別執行位置敏感的ROI池化操作(Position-Sensitive Rol Pooling,這裡使用的是平均池化操作),獲得對應的類別和位置資訊。
這樣,我們就可以在測試圖片中獲得我們想要的類別資訊和位置資訊啦。

2. Position-Sensitive Score Map解析

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

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

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

OK,這就是position-sensitive score map的全部思想了,應該很容易理解了吧。

3. Position-Sensitive Rol Pooling解析

上面我們只是簡單的講解了一下ROl的K*K個子區域在各個類別的score maps上找到其每個子區域的響應值,我們並沒有詳細的解釋這個“找到”是如何找的?這就是位置敏感Rol池化操作(Position-sensitive RoI pooling),其字面意思是池化操作是位置敏感的,下來我們對它進行解釋說明。

如圖3所示,通過RPN提取出來的RoI區域,其是包含了x,y,w,h的4個值,也就是說不同的RoI區域能夠對應到score map的不同位置上,而一個RoI會被劃分成K*K個bins(也就是子區域。每個子區域bin的長寬分別是 h/k 和 w/k ),每個bin都對應到score map上的某一個區域。既然該RoI的每個bin都對應到score map上的某一個子區域,那麼池化操作就是在該bin對應的score map上的子區域執行,且執行的是平均池化。我們在前面已經講了,第i個bin應該在第i個score map上尋找響應值,那麼也就是在第i個score map上的第i個bin對應的位置上進行平均池化操作。由於我們有(C+1)個類別,所以每個類別都要進行相同方式的池化操作。

圖4 Position-Sensitive Rol Pooling解析
圖4已經很明顯的畫出了池化的方式,對於每個類別,它都有K*K個score maps,那麼按照上述的池化方式,ROI可以針對該類別可以獲得K*K個值,那麼一共有(C+1)個類別,那麼一個RoI就可以得到K*K*(C+1)個值,就是上圖的特徵圖。那麼對於每個類別,該類別的K*K個值都表示該RoI屬於該類別的響應值,那麼將這K*K個數相加就得到該類別的score,那麼一共有(C+1)個scores,那麼在這(C+1)個數上面使用簡單的softmax函式就可以得到各個類別的概率了(注意,這裡不需要使softmax分類器了,只需要使用簡答的softmax函式,因為這裡就是通過簡單的比大小來判斷最終的類別的)。

4. Position-Sensitive Regression解析
前面的position-sensitive score map和Position-sensitive RoI pooling得到的值是用來分類的,那麼自然需要相應的操作得到對應的值來進行迴歸操作。按照position-sensitive score map和Position-sensitive RoI pooling思路,其會讓每一個RoI得到(C+1)個數作為每個類別的score,那麼現在每個RoI還需要 4個數作為迴歸偏移量,也就是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的維度應當是 4*K*K ,然後經過Position-sensitive RoI pooling操作後,每一個RoI就能得到4個值作為該RoI的x,y,w,h的偏移量了,其思路和分類完全相同。

5. 為什麼position-sensitive score map能夠在含有某個類別的物體的某個部位的區域上具有高響應值?

這種有高響應值現在只是作者自己設想的啊,如果網路不滿足這一點的話,那麼我們前面的所有分析都不成立啦。現在我們就大致解釋一下為什麼訓練該網路能夠讓網路最終滿足這一點。首先根據網路的loss計算公式,如果一個RoI含有人這個物體,那麼該RoI通過position-sensitive score map和Position-sensitive RoI pooling得到的(C+1)個值中屬於人的那個值必然會在softmax損失函式的驅動下變得儘量的大,那麼如何才能使得屬於人的這個值儘量的大呢?那麼我們需要想想屬於人的這個預測值是怎麼來的?經過前面的分析,我們已經知道它是通過Position-sensitive RoI pooling這種池化操作獲得的,那麼也就是說使得(C+1)個值中屬於人的那個值儘量大,必然會使得position-sensitive score map中屬於人的那個score map上的RoI對應的位置區域的平均值儘量大,從而會使得該score map上在該區域上的響應值儘量大,因為只有該區域的響應值大了,才能使得預測為人的概率大,才會降低softmax的loss,整個訓練過程才能進行下去。

圖5 位置敏感得分對映表現1

圖6 位置敏感得分對映表現2

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

6. Loss計算及其分析

這個Loss就是兩階段目標檢測框架常用的形式。包括一個分類Loss和一個迴歸Loss。lamdy用來平衡兩者的重要性。對於任意一個RoI,我們需要計算它的softmax損失,和當其不屬於背景時的迴歸損失。這很簡單,因為每個RoI都被指定屬於某一個GT box或者屬於背景,即先選擇和GT box具有最大重疊率(IOU)的Rol,然後在剩餘的Rol中選擇與GT box的重疊率值大於0.5Rol進行匹配操作,最後將剩餘的Rol都歸為背景類。即每個Rol都有了對應的標籤,我們就可以根據監督學習常用的方法來訓練它啦。

7. online hard example mining 

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

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

圖7 膨脹卷積

這個方法同樣也是目標檢測中常用的一個tricks,其最主要的目的是可以在減小卷積步長的同時擴大feature map的大小,即同等情況下,通過這個操作,我們可以獲得一個更大的feature map,而實驗表明,大的feature map會提升檢測的效能。具體的解釋可以去看這個連結。上圖是一個膨脹卷積的操作,通過幾次操作,我們可以看到我們的接收場在不斷的擴大,具體的解釋請看英文吧。

9. 為了過濾背景Rols使用的方法

在測試的時候,為了減少RoIs的數量,作者在RPN提取階段就對RPN提取的大約2W個proposals進行了過濾,方法如下所示,

去除超過影象邊界的proposals;
使用基於類別概率且閾值IoU=0.7的NMS過濾;
按照類別概率選擇top-N個proposals;
所以在測試的時候,最後一般只剩下300左右個RoIs,當然這個數量是一個超引數。並且在R-FCN的輸出300個預測框之後,仍然要對其使用NMS去除冗餘的預測框。

10. 訓練細節

R-FCN和Faster R-CNN採取了同樣的訓練策略,具體的訓練策略可以參考這篇部落格。

11. 圖片中的ROI和特徵上的ROI之間的對映關係

如果你不清楚它們是如何對映的,請檢視這個連結。

三、R-FCN效能分析

1. 定量結果分析

表1 使用ResNet-101全卷積策略

如上表所示,作者測試了不同大小的ROI對效能的影響(我們使用了預訓練的ResNet-101網路,在VOC 07資料集上面進行測試),我們可以看到如果使用1x1的ROI,顯示輸出失敗,具體原因不得而知。當使用7x7的ROI時,能夠獲得最好的結果,這也是論文中最終使用7x7大小的ROI的原因吧,作者應該是做了很多的驗證工作。

表2 Faster R-CNN與R-FCN效能比較

如上表所示,我們比較了Faster R-CNN和R-FCN的效能,從表中我們可以看出與Faster R-CNN相比,R-FCN有更快的執行速度,大概是2.5倍以上。另外,我們可以發現效能稍微有一點點提升,當調整ROI的個數時,我們發現300個ROI時能夠獲得最好的效能。

表3 預訓練網路的深度對效能的影響

如上表所示,隨著預訓練網路層數的加深,我們的檢測效能在不斷的得到提高,使用VGG和ResNet網路還是有很大的效能差異,但是過深的網路並沒有提高其效能,可能的原因是我們的網路發生了過擬合情況。

表4 COCO資料集的訓練結果

如上表所示,我們採用了COCO資料集進行效能驗證,與Faster R-CNN相比,R-FCN可以實現3倍的加速,準確率可以提升2個百分點。

2. 定性結果分析


圖8 VOC 2007檢測結果


圖9 COCO檢測結果

以上是R-FCN演算法在VOC2007和COCO資料集上面的效能表現,總體上看效果還是挺不錯的,具體的效果需要你自己去嘗試,根據自己的需求去選擇合適的演算法。

四、總結

總的來講,和Faster R-CNN相比,R-FCN具有更快的執行速度(2.5倍以上),稍微提高了一點檢測精度,在速度和準確率之間進行了折中,提出position-sensitive score map來解決檢測的位置敏感性問題。演算法中的很多細節值得我們進行深入的研究和分析,希望你從中學到了很多有用的東西。

參考文獻:

[1] R-FCN對應的poster,相關連結;

[2] VGG Reading Group - Sam Albanie ,參考連結,密碼:hby1;

[3] 詳解R-FCN,部落格連結;

注意事項:

[1] 該部落格是本人原創部落格,如果您對該部落格感興趣,想要轉載該部落格,請與我聯絡(qq郵箱:[email protected]),我會在第一時間回覆大家,謝謝大家。

[2] 由於個人能力有限,該部落格可能存在很多的問題,希望大家能夠提出改進意見。

[3] 如果您在閱讀本部落格時遇到不理解的地方,希望可以聯絡我,我會及時的回覆您,和您交流想法和意見,謝謝。
--------------------- 
作者:技術挖掘者 
來源:CSDN 
原文:https://blog.csdn.net/WZZ18191171661/article/details/79481135?utm_source=copy 
版權宣告:本文為博主原創文章,轉載請附上博文連結!