基於區域的目標檢測
目標檢測,即在一幅圖裡框出某個目標位置.有2個任務.
- 定位出目標的邊界框
- 識別出邊界框內的物體的類別
Sliding-window detectors
一種暴力的目標檢測方法就是使用滑動視窗,從左到右,從上到下掃描圖片,然後用分類器識別視窗中的目標.為了檢測出不同的目標,或者同一目標但大小不同,必須使用不同大小,不同寬高比的滑動視窗.
把滑動視窗框出來的圖片塊resize(因為很多分類器只接受固定大小的圖片輸入)後,送給CNN分類器,CNN提取出4096個特徵.然後使用SVM做分類,用線性迴歸做bounding box預測.
虛擬碼如下
for window in windows patch = get_patch(image, window) results = detector(patch)
提高效能的一個明顯的方法就是減少window數量.
Selective Search
相比於暴力搜尋,我們使用一種區域建議(region proposal)方法去建立roi(感興趣區域region of intrest).在selective search(SS)中,我們從將每一個畫素作為一個group開始,接下來我們計算每一個group的texture,然後合併最接近的group.為例避免某個區域吞併了其他區域,我們優先合併較小的group,不斷的合併各個group直到不能再合併了.如下圖:第一行圖顯示了region是怎麼不斷地增長的,第二行的藍色框顯示了在不斷地合併的過程裡,是怎麼產生ROI的.
R-CNN
R-CNN採取區域建議方法建立2000個ROI.然後這些區域的圖片被送到CNN,提取特徵,然後送給全連線層做邊界框預測和類別預測
流程如下:
由於有了數量少質量高的ROI,R-CNN相比於暴力的滑動視窗搜尋,要快的多,也準確的多.
ROIs = region_proposal(image)
for ROI in ROIs
patch = get_patch(image, ROI)
results = detector(patch)
Boundary box regressor
區域建議方法是需要大量算力的.為了加速ROI尋找的過程,我們往往選擇一個不需要巨量算力的區域建議方法來建立ROI,再用線性迴歸器(使用全連線層)對邊界框做微調.
Fast R-CNN
R-CNN需要大量的ROI,並且這些ROI很多都是重疊的.所以R-CNN在無論是訓練還是推理都很慢.如果我們有2000個建議區域,每一個都要被CNN處理一次,也就是說,對於不同的ROI,特徵提取重複了2000次.
換個思路,對整幅圖片做特徵提取,然後在特徵圖的基礎上做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-7e354377a