目標檢測,即在一幅圖裏框出某個目標位置.有2個任務.算法
一種暴力的目標檢測方法就是使用滑動窗口,從左到右,從上到下掃描圖片,而後用分類器識別窗口中的目標.爲了檢測出不一樣的目標,或者同一目標但大小不一樣,必須使用不一樣大小,不一樣寬高比的滑動窗口.
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採起區域建議方法建立2000個ROI.而後這些區域的圖片被送到CNN,提取特徵,而後送給全鏈接層作邊界框預測和類別預測
流程以下:
3d
因爲有了數量少質量高的ROI,R-CNN相比於暴力的滑動窗口搜索,要快的多,也準確的多.rest
ROIs = region_proposal(image) for ROI in ROIs patch = get_patch(image, ROI) results = detector(patch)
區域建議方法是須要大量算力的.爲了加速ROI尋找的過程,咱們每每選擇一個不須要巨量算力的區域建議方法來建立ROI,再用線性迴歸器(使用全鏈接層)對邊界框作微調.
code
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),提升了準確率.
因爲Fast R-CNN使用全鏈接層,咱們採用ROI池化,把不一樣size的ROI轉換成固定size.
以8*8的特徵圖轉換爲2*2爲例
而後就能夠把這些2*2的特徵圖送給分類器和線性迴歸器去作分類和邊界框預測了.
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.
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.
假設一下咱們只有一個檢測臉部中右眼的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