1. 程式人生 > >Faster R-CNN:詳解目標檢測的實現過程

Faster R-CNN:詳解目標檢測的實現過程

最大的 中心 width 小數據 等等 eat tar 優先 博文

本文詳細解釋了 Faster R-CNN 的網絡架構和工作流,一步步帶領讀者理解目標檢測的工作原理,作者本人也提供了 Luminoth 實現,供大家參考。

  • Luminoth 實現:https://github.com/tryolabs/luminoth/tree/master/luminoth/models/fasterrcnn

  去年,我們決定深入了解 Faster R-CNN,閱讀原始論文以及其中引用到的其他論文,現在我們對其工作方式和實現方法有了清晰的理解。

  我們最終在 Luminoth 中實現了 Faster R-CNN,Luminoth 是基於 TensorFlow 的計算機視覺工具包,易於訓練和監控,支持多種不同的模型。到目前為止,Luminoth 已經吸引了很大的關註,我們在 ODSC Europe 和 ODSC West 的論壇中也介紹過這個項目。(ODSC,Open Data Science Conference,專註於開源數據科學的會議)。

  基於開發 Luminoth 的工作和過去的報告,我們認為把所有實現 Faster RCNN 的細節和相關鏈接整合到一篇博客中是一個不錯的點子,這對未來其他對此領域感興趣的人會很有意義。

背景

  Faster R-CNN 最早在 2015 年的 NIPS 發布。其在發布後經歷了幾次修改,這在之後博文中會有討論。Faster-RCNN 是 RCNN 系列論文的第三次叠代,這一系列論文的一作和聯合作者是 Ross Girshick。

  這一切始於 2014 年的一篇論文「Rich feature hierarchies for accurate object detection and semantic segmentation」(R-CNN),其使用了稱為 Selective Search 的算法用來提取感興趣候選區域,並用一個標準的卷積神經網絡 (CNN) 去分類和調整這些區域。Fast R-CNN 從 R-CNN 演變優化而來,Fast R-CNN 發布於 2015 年上半年,其中一種稱為感興趣區域池化的技術,使得網絡可以共享計算結果,從而讓模型提速。這一系列算法最終被優化為 Faster R-CNN,這是第一個完全可微分的模型。

框架

  Faster R-CNN 的框架由幾個模塊部件組成,所以其框架有些復雜。我們將從高層次的概述開始,之後會介紹不同組成部分的具體細節。

  從一張圖片開始,我們將會得到:

    • 一個邊框列表

    • 每個邊框會被分配一個標簽

    • 每對標簽和邊框所對應的概率

技術分享圖片

完整的 Faster R-CNN 框架

  輸入的圖片以(長×寬×高)的張量形式表征,之後會被饋送入預訓練好的卷積神經網絡,在中間層得到特征圖。使用該特征圖作為特征提取器並用於下一流程。

  上述方法在遷移學習中經常使用,尤其在為小數據集訓練分類器時,其通常取用了在另一個較大數據集訓練好的權重。我們在下一章節會深入了解這個部分。接著,我們會使用到區域建議網絡(Region Proposal Network,RPN)

。使用 CNN 計算得到的特征,去尋找到預設好數量的可能包含目標的區域 (邊框)。

  使用深度學習進行目標檢測最大的困難可能是生成一個長度可變的邊框列表。使用深度神經網絡建模時,模型最後一部分通常是一個固定尺寸的張量輸出(除了循環神經網絡)。例如,在圖片分類中,輸出是 (N,) 形狀的張量,N 是類別的數量,其中在第 i 個位置標量含有該圖片屬於類別 i 的概率。

  RPN 中長度可變列表的問題可以使用錨點解決:使用固定尺寸的參考邊框在原始圖片上一致地定位。不是直接探測目標在哪,而是把問題分兩個方面建模,對每個錨點,我們考慮:

    • 這個錨點包含相關目標嗎?

    • 如何調整錨點以更好的擬合到相關目標?

  可能會有點困擾,但是沒關系,下面會深入了解。

  在取得一系列的相關目標和其在原始圖片上的位置後,目標探測問題就可以相對直觀地解決了。使用 CNN 提取到的特征和相關目標的邊框,我們在相關目標的特征圖上使用感興趣區域池化 (RoI Pooling),並將與目標相關的特征信息存入一個新的張量。之後的流程與 R-CNN 模型一致,利用這些信息:

    • 對邊框內的內容分類(或者舍棄它,並用「背景」標記邊框內容)

    • 調整邊框的坐標(使之更好地包含目標)

  顯然,這樣做會遺失掉部分信息,但這正是 Faster-RCNN 如何進行目標探測的基本思想。下一步,我們會仔細討論框架、損失函數以及訓練過程中各個組件的具體細節。

基礎網絡

  之前提到過,Faster R-CNN 第一步要使用在圖片分類任務 (例如,ImageNet) 上預訓練好的卷積神經網絡,使用該網絡得到的中間層特征的輸出。這對有深度學習背景的人來說很簡單,但是理解如何使用和為什麽這樣做才是關鍵,同時,可視化中間層的特征輸出也很重要。沒有一致的意見表明哪個網絡框架是最好的。原始的 Faster R-CNN 使用的是在 ImageNet 上預訓練的 ZF 和 VGG,但之後出現了很多不同的網絡,且不同網絡的參數數量變化很大。例如,MobileNet,以速度優先的一個小型的高效框架,大約有 330 萬個參數,而 ResNet-152(152 層),曾經的 ImageNet 圖片分類競賽優勝者,大約有 6000 萬個參數。最新的網絡結構如 DenseNet,可以在提高準確度的同時縮減參數數量。

VGG

  在討論網絡結構孰優孰劣之前,讓我們先以 VGG-16 為例來嘗試理解 Faster-RCNN 是如何工作的。

技術分享圖片

VGG 網絡結構

  VGG,其名字來自於在 ImageNet ILSVRC 2014 競賽中使用此網絡的小組組名,首次發布於論文「Very Deep Convolutional Networks for Large-Scale Image Recognition」, 作者是 Karen Simonyan 和 Andrew Zisserman。以今天的標準來看這個網絡談不上深度,但是在發布之際 VGG16 比當時常用的網絡要多一倍的層數,其推動了「深度 → 更強大性能 → 更好結果」的浪潮(只要訓練是可行的)。

  當使用 VGG 進行分類任務時,其輸入是 224×224×3 的張量 (表示一個 224×224 像素大小的 RGB 圖片)。在分類任務中輸入圖片的尺寸是固定的,因為網絡最後一部分的全連接層需要固定長度的輸入。在接入全連接層前,通常要將最後一層卷積的輸出展開成一維張量。

  因為要使用卷積網絡中間層的輸出,所以輸入圖片的尺寸不再有限制。至少,在這個模塊中不再是問題,因為只有卷積層參與計算。讓我們深入了解一下底層的細節,看看具體要使用哪一層卷積網絡的輸出。Faster R-CNN 論文中沒有具體指定使用哪一層;但是在官方的實現中可以觀察到,作者使用的是 conv5/conv5_1 這一層 (caffe 代碼)。

  每一層卷積網絡都在前一層的信息基礎上提取更加抽象的特征。第一層通常學習到簡單的邊緣,第二層尋找目標邊緣的模式,以激活後續卷積網絡中更加復雜的形狀。最終,我們得到一個在空間維度上比原始圖片小很多,但表征更深的卷積特征圖。特征圖的長和寬會隨著卷積層間的池化而縮小,深度會隨著卷積層濾波器的數量而增加。

技術分享圖片

從圖片到卷積特征圖

  卷積特征圖將圖片的所有信息編碼到深度的維度上,同時保留著原始圖片上目標物體的相對位置信息。例如,如果圖片左上角有一個紅色矩形,經過卷積層的激活,那麽紅色矩形的位置信息仍然保留在卷積特征圖的左上角。

VGG vs ResNet

  如今,ResNet 已經取代大多數 VGG 網絡作為提取特征的基礎框架。Faster-RCNN 的三位聯合作者 (Kaiming He, Shaoqing Ren 和 Jian Sun) 也是論文「Deep Residual Learning for Image Recognition」的作者,這篇論文最初介紹了 ResNets 這一框架。

  ResNet 對比 VGG 的優勢在於它是一個更深層、大型的網絡,因此有更大的容量去學習所需要的信息。這些結論在圖片分類任務中可行,在目標探測的問題中也應該同樣有效。

  ResNet 在使用殘差連接和批歸一化的方法後更加易於訓練,這些方法在 VGG 發布的時候還沒有出現。

錨點

  現在,我們將使用處理過後的特征圖並建議目標區域,也就是用於分類任務的感興趣區域。之前提到過錨點是解決長度可變問題的一種方法,現在將詳細介紹。

  我們的目標是尋找圖片中的邊框。這些邊框是不同尺寸、不同比例的矩形。設想我們在解決問題前已知圖片中有兩個目標。那麽首先想到的應該是訓練一個網絡,這個網絡可以返回 8 個值:包含(xmin, ymin, xmax, ymax)的兩個元組,每個元組都用於定義一個目標的邊框坐標。這個方法有著根本問題,例如,圖片可能是不同尺寸和比例的,因此訓練一個可以直接準確預測原始坐標的模型是很復雜的。另一個問題是無效預測:當預測(xmin,xmax)和(ymin,ymax)時,應該強制設定 xmin 要小於 xmax,ymin 要小於 ymax。

  另一種更加簡單的方法是去預測參考邊框的偏移量。使用參考邊框(xcenter, ycenter, width, height),學習預測偏移量(Δxcenter,Δycenter,Δwidth,Δheight),因此我們只得到一些小數值的預測結果並挪動參考變量就可以達到更好的擬合結果。

  錨點是用固定的邊框置於不同尺寸和比例的圖片上,並且在之後目標位置的預測中用作參考邊框。

  我們在處理的卷積特征圖的尺寸分別是 conv_width×conv_height×conv_depth,因此在卷積圖的 conv_width×conv_height 上每一個點都生成一組錨點。很重要的一點是即使我們是在特征圖上生成的錨點,這些錨點最終是要映射回原始圖片的尺寸。

  因為我們只用到了卷積和池化層,所以特征圖的最終維度與原始圖片是呈比例的。數學上,如果圖片的尺寸是 w×h,那麽特征圖最終會縮小到尺寸為 w/r 和 h/r,其中 r 是次級采樣率。如果我們在特征圖上每個空間位置上都定義一個錨點,那麽最終圖片的錨點會相隔 r 個像素,在 VGG 中,r=16。

技術分享圖片

原始圖片的錨點中心

  為了選擇一組合適錨點,我們通常定義一組固定尺寸 (例如,64px、128px、256px,此處為邊框大小) 和比例 (例如,0.5、1、1.5,此處為邊框長寬比) 的邊框,使用這些變量的所有可能組合得到候選邊框 (這個例子中有 1 個錨點和 9 個邊框)。

技術分享圖片

左側:錨點、中心:特征圖空間單一錨點在原圖中的表達,右側:所有錨點在原圖中的表達

區域建議網絡

技術分享圖片

RPN 采用卷積特征圖並在圖像上生成建議

  像我們之前提到的那樣,RPN 接受所有的參考框(錨點)並為目標輸出一套好的建議。它通過為每個錨點提供兩個不同的輸出來完成。

  第一個輸出是錨點作為目標的概率。如果你願意,可以叫做「目標性得分」。註意,RPN 不關心目標的類別,只在意它實際上是不是一個目標(而不是背景)。我們將用這個目標性得分來過濾掉不好的預測,為第二階段做準備。第二個輸出是邊框回歸,用於調整錨點以更好的擬合其預測的目標。

  RPN 是用完全卷積的方式高效實現的,用基礎網絡返回的卷積特征圖作為輸入。首先,我們使用一個有 512 個通道和 3x3 卷積核大小的卷積層,然後我們有兩個使用 1x1 卷積核的並行卷積層,其通道數量取決於每個點的錨點數量。

技術分享圖片

RPN 架構的卷積實現,其中 k 是錨點的數量

  對於分類層,我們對每個錨點輸出兩個預測值:它是背景(不是目標)的分數,和它是前景(實際的目標)的分數。

  對於回歸或邊框調整層,我們輸出四個預測值:Δxcenter、Δycenter、Δwidth、Δheight,我們將會把這些值用到錨點中來得到最終的建議。

  使用最終的建議坐標和它們的目標性得分,然後可以得到一套很好的對於目標的建議。

訓練、目標和損失函數

  RPN 執行兩種不同類型的預測:二進制分類邊框回歸調整。為了訓練,我們把所有的錨 anchor box 分成兩類。一類是「前景」,它與真實目標重疊並且其 IoU(Intersection of Union)值大於 0.5;另一類是「背景」,它不與任何真實目標重疊或與真實目標的 IoU 值 小於 0.1。

  然後,我們對這些錨點隨機采樣,構成大小為 256 的 mini batch (維持前景錨點和背景錨點之間的平衡比例)。

  RPN 用所有以 mini batch 篩選出來的 anchor box 和二進制交叉熵(binary cross entropy)來計算分類損失。然後它只用那些標記為前景的 mini batch 錨點來計算回歸損失。為了計算回歸的目標,我們使用前景 anchor box 和最接近的真實目標,並計算將 anchor box 轉化為目標所需的正確 Δ。(因為不需要考慮其類別)

  論文中建議使用 Smooth L1 loss 來計算回歸誤差,而不是用簡單的 L1 或 L2 loss。Smooth L1 基本上就是 L1,但是當 L1 的誤差足夠小,由確定的 σ 定義時,可以認為誤差幾乎是正確的且損失以更快的速率減小。

  使用 dynamic batches 是具有挑戰性的,這裏的原因很多。即使我們試圖維持前景錨點和背景錨點之間的平衡比例,但這並不總是可能的。根據圖像上的真實目標以及錨點的大小和比例,可能會得到零前景錨點。在這種情況下,我們轉而使用對於真實框具有最大 IoU 值的錨點。這遠非理想情況,但是為了總是有前景樣本和目標可以學習,這還是挺實用的。

後處理

  非極大抑制(Non-maximum suppression):由於錨點經常重疊,因此建議最終也會在同一個目標上重疊。為了解決重復建議的問題,我們使用一個簡單的算法,稱為非極大抑制(NMS)。NMS 獲取按照分數排序的建議列表並對已排序的列表進行叠代,丟棄那些 IoU 值大於某個預定義閾值的建議,並提出一個具有更高分數的建議。

  雖然這看起來很簡單,但對 IoU 的閾值設定一定要非常小心。太低,你可能會丟失對目標的建議;太高,你可能會得到對同一個目標的很多建議。常用值是 0.6

  建議選擇:應用 NMS 後,我們保留評分最高的 N 個建議。論文中使用 N=2000,但是將這個數字降低到 50 仍然可以得到相當好的結果。

獨立應用程序

  RPN 可以獨立使用,而不需要第二階段的模型。在只有一類對象的問題中,目標性概率可以用作最終的類別概率。這是因為在這種情況下,「前景」=「目標類別」以及「背景」=「不是目標類別」。

  一些從獨立使用 RPN 中受益的機器學習問題的例子包括流行的(但仍然是具有挑戰性的)人臉檢測和文本檢測。

  僅使用 RPN 的優點之一是訓練和預測的速度都有所提高。由於 RPN 是一個非常簡單的僅使用卷積層的網絡,所以預測時間比使用分類基礎網絡更快。

興趣區域池化

  在 RPN 步驟之後,我們有很多沒有分配類別的目標建議。我們接下來要解決的問題就是如何將這些邊框分類到我們想要的類別中。

最簡單的方法是采用每個建議,裁剪出來,然後讓它通過預訓練的基礎網絡。然後,我們可以用提取的特征作為基礎圖像分類器的輸入。這種方法的主要問題是運行所有 2000 個建議的計算效率和速度都是非常低的。

  Faster R-CNN 試圖通過復用現有的卷積特征圖來解決或至少緩解這個問題。這是通過用興趣區域池化為每個建議提取固定大小的特征圖實現的。R-CNN 需要固定大小的特征圖,以便將它們分類到固定數量的類別中。

技術分享圖片

興趣區域池化

  一種更簡單的方法(被包括 Luminoth 版本的 Faster R-CNN 在內的目標檢測實現方法所廣泛使用),是用每個建議來裁剪卷積特征圖,然後用插值(通常是雙線性的)將每個裁剪調整為固定大小(14×14×convdepth)。裁剪之後,用 2x2 核大小的最大池化來獲得每個建議最終的 7×7×convdepth 特征圖。

  選擇這些確切形狀的原因與下一模塊(R-CNN)如何使用它有關,這些設定是根據第二階段的用途得到的。

基於區域的卷積神經網絡

  基於區域的卷積神經網絡(R-CNN)是 Faster R-CNN 工作流的最後一步。從圖像上獲得卷積特征圖之後,用它通過 RPN 來獲得目標建議並最終為每個建議提取特征(通過 RoI Pooling),最後我們需要使用這些特征進行分類。R-CNN 試圖模仿分類 CNNs 的最後階段,在這個階段用一個全連接層為每個可能的目標類輸出一個分數。

  R-CNN 有兩個不同的目標:

    1. 將建議分到一個類中,加上一個背景類(用於刪除不好的建議)。

    2. 根據預測的類別更好地調整建議的邊框。

  在最初的 Faster R-CNN 論文中,R-CNN 對每個建議采用特征圖,將它平坦化並使用兩個大小為 4096 的有 ReLU 激活函數的全連接層。

  然後,它對每個不同的目標使用兩種不同的全連接層:

    • 一個有 N+1 個單元的全連接層,其中 N 是類的總數,另外一個是背景類。

    • 一個有 4N 個單元的全連接層。我們希望有一個回歸預測,因此對 N 個類別中的每一個可能的類別,我們都需要 Δcenterx、Δcentery、Δwidth、Δheight。

技術分享圖片

R-CNN 架構

訓練和目標

  R-CNN 的目標與 RPN 的目標的計算方法幾乎相同,但是考慮的是不同的可能類別。我們采用建議和真實邊框,並計算它們之間的 IoU。

  那些有任何真實邊框的建議,只要其 IoU 大於 0.5,都被分配給那個真實數據。那些 IoU 在 0.1 和 0.5 之間的被標記為背景。與我們在為 RPN 分配目標時相反的是,我們忽略了沒有任何交集的建議。這是因為在這個階段,我們假設已經有好的建議並且我們對解決更困難的情況更有興趣。當然,這些所有的值都是可以為了更好的擬合你想找的目標類型而做調整的超參數。

  邊框回歸的目標是計算建議和與其對應的真實框之間的偏移量,僅針對那些基於 IoU 閾值分配了類別的建議。

  我們隨機抽樣了一個尺寸為 64 的 balanced mini batch,其中我們有高達 25% 的前景建議(有類別)和 75% 的背景。

  按照我們對 RPN 損失所做的相同處理方式,現在的分類損失是一個多類別的交叉熵損失,使用所有選定的建議和用於與真實框匹配的 25% 建議的 Smooth L1 loss。由於 R-CNN 邊框回歸的全連接網絡的輸出對於每個類都有一個預測,所以當我們得到這種損失時必須小心。在計算損失時,我們只需要考慮正確的類。

後處理

  與 RPN 相似,我們最終得到了很多已經分配了類別的目標,在返回它們之前需要進一步處理。

  為了實施邊框調整,我們必須考慮哪個類別具有對該建議的最高概率。我們也需要忽略具有最高概率的背景類的建議。

  在得到最終目標和忽略被預測為背景的目標之後,我們應用基於類的 NMS。這通過按類進行分組完成,通過概率對其排序,然後將 NMS 應用於每個獨立的組。

  對於我們最後的目標列表,我們也可以設置一個概率閾值並且對每個類限制目標的數量。

訓練

  在最初的論文中,Faster R-CNN 是用多步法訓練的,獨立地訓練各部分並且在應用最終的全面訓練方法之前合並訓練的權重。之後,人們發現進行端到端的聯合訓練會帶來更好的結果。

  把完整的模型放在一起後,我們得到 4 個不同的損失,兩個用於 RPN,另外兩個用於 R-CNN。我們在 RPN 和 R-CNN 中有可訓練的層,我們也有可以訓練(微調)或不能訓練的基礎網絡。

  是否訓練基礎網絡的決定取決於我們想要學習的目標特性和可用的計算能力。如果我們想檢測與在原始數據集(用於訓練基礎網絡)上的數據相似的目標,那麽除了嘗試壓縮我們能獲得的所有可能的性能外,其他做法都是沒有必要的。另一方面,為了擬合完整的梯度,訓練基礎網絡在時間和必要的硬件上都是昂貴的。

  用加權和將四種不同的損失組合起來。這是因為相對於回歸損失,我們可能希望給分類損失更大的權重,或者相比於 RPN 可能給 R-CNN 損失更大的權重。

  除了常規的損失之外,我們也有正則化損失,為了簡潔起見,我們可以跳過這部分,但是它們在 RPN 和 R-CNN 中都可以定義。我們用 L2 正則化一些層。根據正在使用哪個基礎網絡,以及如果它經過訓練,也有可能進行正則化。

  我們用隨機梯度下降的動量算法訓練,將動量值設置為 0.9。你可以輕松的用其他任何優化方法訓練 Faster R-CNN,而不會遇到任何大問題。

  學習率從 0.001 開始,然後在 50K 步後下降到 0.0001。這是通常最重要的超參數之一。當用 Luminoth 訓練時,我們經常從默認值開始,並以此開始做調整。

評估

  在一些特定的 IoU 閾值下,使用標準平均精度均值(mAP)來完成評估(例如,[email protected])。mAP 是源於信息檢索的度量標準,並且常用於計算排序問題中的誤差和評估目標檢測問題。

  我們不會深入討論細節,因為這些類型的度量標準值得用一篇完整博客來總結,但重要的是,當你錯過了你應該檢測到的框,以及當你發現一些不存在的東西或多次檢測到相同的東西時,mAP 會對此進行懲罰。

結論

  到目前為止,你應該清楚 Faster R-CNN 的工作方式、設計目的以及如何針對特定的情況進行調整。如果你想更深入的了解它的工作原理,你應該看看 Luminoth 的實現。

  Faster R-CNN 是被證明可以用相同的原理解決復雜的計算機視覺問題的模型之一,在這個新的深度學習革命剛開始的時候,它就展現出如此驚人的結果。

  目前正在建立的新模型不僅用於目標檢測,還用於基於這種原始模型的語義分割、3D 目標檢測等等。有的借用 RPN,有的借用 R-CNN,還有的建立在兩者之上。因此,充分了解底層架構非常重要,從而可以解決更加廣泛的和復雜的問題。


原文地址: https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/

Faster R-CNN:詳解目標檢測的實現過程