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郵箱:1575262785@qq.com),我會在第一時間回復大家,謝謝大家。
[2] 由于個人能力有限,該博客可能存在很多的問題,希望大家能夠提出改進意見。
[3] 如果您在閱讀本博客時遇到不理解的地方,希望可以聯系我,我會及時的回復您,和您交流想法和意見,謝謝。
---------------------?
作者:技術挖掘者?
來源:CSDN?
原文:https://blog.csdn.net/WZZ18191171661/article/details/79481135?utm_source=copy?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
總結
- 上一篇: 关于hard-negative mini
- 下一篇: 深度学习: 从 RoIPooling 到