基於區域的目標檢測

目標檢測,即在一幅圖裏框出某個目標位置.有2個任務.算法

  • 定位出目標的邊界框
  • 識別出邊界框內的物體的類別

Sliding-window detectors

一種暴力的目標檢測方法就是使用滑動窗口,從左到右,從上到下掃描圖片,而後用分類器識別窗口中的目標.爲了檢測出不一樣的目標,或者同一目標但大小不一樣,必須使用不一樣大小,不一樣寬高比的滑動窗口.
windows

把滑動窗口框出來的圖片塊resize(由於不少分類器只接受固定大小的圖片輸入)後,送給CNN分類器,CNN提取出4096個特徵.而後使用SVM作分類,用線性迴歸作bounding box預測.
網絡


僞代碼以下性能

for window in windows
    patch = get_patch(image, window)
    results = detector(patch)

提升性能的一個明顯的方法就是減小window數量.測試

相比於暴力搜索,咱們使用一種區域建議(region proposal)方法去建立roi(感興趣區域region of intrest).在selective search(SS)中,咱們從將每個像素做爲一個group開始,接下來咱們計算每個group的texture,而後合併最接近的group.爲例避免某個區域吞併了其餘區域,咱們優先合併較小的group,不斷的合併各個group直到不能再合併了.以下圖:第一行圖顯示了region是怎麼不斷地增加的,第二行的藍色框顯示了在不斷地合併的過程裏,是怎麼產生ROI的.
ui

R-CNN

R-CNN採起區域建議方法建立2000個ROI.而後這些區域的圖片被送到CNN,提取特徵,而後送給全鏈接層作邊界框預測和類別預測

流程以下:
3d

因爲有了數量少質量高的ROI,R-CNN相比於暴力的滑動窗口搜索,要快的多,也準確的多.rest

ROIs = region_proposal(image)
for ROI in ROIs
    patch = get_patch(image, ROI)
    results = detector(patch)

Boundary box regressor

區域建議方法是須要大量算力的.爲了加速ROI尋找的過程,咱們每每選擇一個不須要巨量算力的區域建議方法來建立ROI,再用線性迴歸器(使用全鏈接層)對邊界框作微調.
code

Fast R-CNN

R-CNN須要大量的ROI,而且這些ROI不少都是重疊的.因此R-CNN在不管是訓練仍是推理都很慢.若是咱們有2000個建議區域,每個都要被CNN處理一次,也就是說,對於不一樣的ROI,特徵提取重複了2000次.orm

換個思路,對整幅圖片作特徵提取,而後在特徵圖的基礎上作ROI的查找.經過池化層作resize,而後送給全鏈接層作邊界框預測和分類.因爲只作了一次特徵提取,Fast R-CNN的性能顯著提升.

流程以下:

僞代碼以下:

feature_maps = process(image)
ROIs = region_proposal(image)
for ROI in ROIs
    patch = roi_pooling(feature_maps, ROI)
    results = detector2(patch)

因爲把特徵提取這一步抽到了for循環外部,性能大幅提高.相比R-CNN,Fast R-CNN在訓練上快了10倍,推理上快了150倍.
Fast R-CNN的一個要點是整個網絡(包括特徵提取,分類,邊界框迴歸)是端到端的訓練,而且採用了multi-task losses(分類loss + 邊界框定位loss),提升了準確率.

ROI pooling

因爲Fast R-CNN使用全鏈接層,咱們採用ROI池化,把不一樣size的ROI轉換成固定size.
以8*8的特徵圖轉換爲2*2爲例

  • 左上:CNN獲得的原始特徵圖
  • 右上:疊加藍色的ROI到特徵圖上
  • 左下:將ROI分割成目標維度.好比要轉換成2*2的,那咱們把ROI分紅4份,每一份大小近似.
  • 右下:對每一份作max pooling(即選出該部分最大的).獲得咱們想要的ROI對應的特徵圖.

而後就能夠把這些2*2的特徵圖送給分類器和線性迴歸器去作分類和邊界框預測了.

Faster R-CNN

Fast R-CNN依賴於區域建議方法,好比selective search.可是,這些算法只能跑在cpu上,速度很慢.在測試中,Fast R-CNN作出一次預測要2.3秒,其中2秒都花在了生成2000個ROI.

feature_maps = process(image)
ROIs = region_proposal(image)         # Expensive!
for ROI in ROIs
    patch = roi_pooling(feature_maps, ROI)
    results = detector2(patch)

在流程上,Faster R-CNN與Fast R-CNN是一致的,只是將獲得ROI的方式改成由一個region proposal network(RPN)獲得.RPN效率要高的多,每張圖生成ROI的時間僅在10ms.

Region proposal network

RPN接受卷積網絡輸出的特徵圖做爲輸入,用以下的ZF網絡作區域建議.也能夠用其餘的網絡好比VGG或者ResNet去作更全面的特徵提取,代價是速度的降低.ZF網絡輸出256個值,送到兩個全鏈接層,一個用於預測邊界框(boudary box),一個用於預測2個objectness scores.objectness衡量bounding box是否包含一個object.咱們能夠用一個迴歸器去計算出一個single objectness score.可是爲簡單起見,Fast R-CNN使用一個分類器,分類器分出的類別有2種:即包含目標和不包含.

對特徵圖中的每個位置,RPN作出k個猜想.因此RPN輸出4*k個座標,2*k個score.以下表示對一個8*8的特徵圖,用3*3的filter,最終獲得8*8*3個ROI.

後面咱們將繼續微調咱們的猜想.因爲咱們須要有一個正確的猜想,咱們初始化的猜想最好有不一樣的shape,不一樣的size.因此,Faster R-CNN不是隨機亂猜的邊界框,它預測相對於咱們稱之爲anchors的參考框(reference box)左上角的偏移.咱們限定偏移的大小,這樣咱們最終預測出的bounding box依然是與anchors相似的.

爲了每一個位置可以獲得k個預測,每一個位置須要k個anchor.每個預測都與一個特定的anchor有關.不一樣的位置共享一樣的anchor shape.

這些anchors不是瞎選的,要儘量地覆蓋到real-life objects,而且要儘可能有合理的尺度和寬高比.這樣可使得每次的prediction更準確.這個策略使得訓練的早期能夠更容易更穩定.

Faster R-CNN uses far more anchors. It deploys 9 anchor boxes: 3 different scales at 3 different aspect ratio. Using 9 anchors per location, it generates 2 × 9 objectness scores and 4 × 9 coordinates per location.

Performance for R-CNN methods

Region-base Fully Convolutional Networks (R-FCN)

假設一下咱們只有一個檢測臉部中右眼的feature map,咱們能夠用它來定位整張臉嗎?答案是確定的,由於右眼位於面部的左上角,因此咱們能夠用來定位整張臉.

若是咱們有其餘專門用於檢測左眼、鼻子或嘴巴的特徵圖,咱們能夠將這些結果結合起來,更好地定位人臉.

在Faster R-CNN中,咱們最終會將整幅圖片的feature map切成相應的roi對應的feature map,再送給多個全鏈接層去作預測.有2000個ROI的時候,這一步的代價是很高昂的.

feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs
    patch = roi_pooling(feature_maps, ROI)
    class_scores, box = detector(patch)         # Expensive!
    class_probabilities = softmax(class_scores)

R-FCN經過減小每個roi的處理時間提速.下面是僞代碼

feature_maps = process(image)
ROIs = region_proposal(feature_maps)         
score_maps = compute_score_map(feature_maps)
for ROI in ROIs
    V = region_roi_pool(score_maps, ROI)     
    class_scores, box = average(V)                   # Much simpler!
    class_probabilities = softmax(class_scores)

考慮一個5*5的feature map,其中藍色部分的feature構成了咱們想要檢測的object.咱們將藍色部分劃分爲3*3的區域.如今咱們能夠建立一個新的feature map,僅僅用來檢測object的top left corner(TL).以下:

因爲咱們將object分紅了9個部分,咱們從整幅圖的feature map中獲得9個feature map,每個feature map負責檢測object的相應區域.這些feature map咱們稱之爲position-sensitive score maps,由於每一個map都只detect(scores)一個object的子區域.

假設下圖的紅色虛線框是ROI.咱們將其劃分紅3*3的區域,而後考慮每一個區域包含目標的對應位置的可能性.例如,top-left ROI區域包含左眼的可能.咱們把結果存儲在一個3*3的vote array裏.好比,vote_array[0][0]存儲了一個score,表示咱們是否發現了目標的top-left region.

這個依據score map和ROI獲得vote array的過程稱之爲position-sensitive ROI-pool.這個過程和前文提過的ROI pool很相似.

計算出全部的值之後,取平均,就獲得了class score.

假設咱們有C種目標待檢測.咱們擴展爲C+1種,即包含一種class for the background(non-object).每一種目標都有本身的3*3個score map.因此一共有(C+1)*3*3個score maps.使用這些score maps咱們能夠爲每個類別都算出一個class score.而後用softmax能夠計算出每個類別的class probability.

總體流程以下,下圖中k=3.

R-FCN的一個示例

原文link:https://medium.com/@jonathan_hui/what-do-we-learn-from-region-based-object-detectors-faster-r-cnn-r-fcn-fpn-7e354377a7c9

相關文章
相關標籤/搜索