1. 程式人生 > >目標檢測演算法的演進(two-stage檢測演算法):R-CNN、SPP-Net、Fast R-CNN、Faster R-CNN、Mask R-CNN

目標檢測演算法的演進(two-stage檢測演算法):R-CNN、SPP-Net、Fast R-CNN、Faster R-CNN、Mask R-CNN

什麼是目標檢測(object detection)

目標檢測(object detection),就是在給定的一張圖片中精確找到物體所在的位置,並標註出物體的類別。所以,目標檢測要解決的問題就是物體在哪裡以及是什麼的整個流程問題。

但是,在實際照片中,物體的尺寸變化範圍很大,擺放物體的角度、姿態、在圖片中的位置都不一樣,物體之間可能還有重疊現象,這使得目標檢測的難度變得很大。

目標檢測演算法:

傳統的目標檢測演算法:

Cascade + HOG/DPM + Haar/SVM以及上述方法的諸多改進、優化。

候選區域/框(Region Proposal) + 深度學習分類的演算法:

通過提取候選區域,並對相應區域進行以深度學習方法為主的分類的方案,比如R-CNN(Selective Search + CNN + SVM)、SPP-net(ROI Pooling)、Fast R-CNN(Selective Search + CNN + ROI)、Faster R-CNN(RPN + CNN + ROI)、Mask R-CNN(Mask Prediction Branch+RPN + CNN + ROI)等。

基於深度學習的迴歸演算法:

YOLO、SSD、YOLOv2、YOLOv3等演算法。

目標檢測演算法的演進(two-stage檢測演算法):

RCNN->SPP-net->Fast-RCNN->Faster-RCNN->Mask R-CNN:

目標檢測任務:

如下圖所示,目標檢測其實包含兩個子任務:影象的識別和定位。

影象識別(classification):

輸入:圖片;輸出:物體的類別;評估方法:準確率。

定位(localization):

輸入:圖片;輸出:方框在圖片中的位置(x,y,w,h);評估方法:檢測評價函式 intersection-over-union ( IOU ) 。

CNN網路已經可以完成影象識別分類的任務,我們只要解決定位的問題即可。

解決定位問題的思路一:

圖片的標籤中增加(x,y,w,h)標籤,然後模型也預測一個(x,y,w,h)標籤,將其看成迴歸問題來優化。這裡有兩個loss函式,一個是classification的loss函式,一般使用交叉熵函式;另一個是regression的loss函式,這裡使用歐幾里得距離(即兩點之間的直線距離)作為loss函式。

我們對CNN神經網路做一點改動,在最後一個卷積層加了兩個頭:“分類頭”和“迴歸頭”。

Regression的部分其實有兩種處理方法:

加在最後一個卷積層後面(如VGG);

加在最後一個全連線層後面(如R-CNN)。

regression的訓練引數收斂的時間要長得多,我們還是應想辦法轉換為classification問題。

解決定位問題的思路二:

我們取不同大小的框,讓框出現在不同的位置,得出這個框的判定得分(這個得分可以認為是這個框是框住這個物體的真實標籤中的框的概率),取得分最高的那個框認為是最有可能框住這個目標物體的框。

如:

怎麼確定這些框的大小和數量?

對一張圖片,用各種大小的框(遍歷整張圖片)依次從圖片左上角掃到右下角,這種方法叫做滑窗法(Sliding Window) 。這樣我們每次都會擷取一個和框一樣大部分的圖片,然後將圖片輸入到CNN,CNN會輸出這個框的得分(classification)以及這個框圖片對應的(x,y,w,h)標籤(regression),然後classification和regression分別計算loss函式。

滑窗法(Sliding Window) 

首先對輸入影象進行不同視窗大小的滑窗進行從左往右、從上到下的滑動。每次滑動時候對當前視窗擷取的這部分的圖片輸入CNN網路進行分類(這個CNN網路是事先訓練好的)。如果當前視窗得到較高的分類概率,則認為檢測到了物體。

對每個不同視窗大小的滑窗都進行檢測後,會得到不同視窗檢測到的物體標記,這些視窗大小會存在重複較高的部分,最後採用非極大值抑制(Non-Maximum Suppression, NMS)的方法進行篩選。最終,經過NMS篩選後獲得檢測到的物體。

IOU(Intersection over Union,交集並集比):

IOU是一種測量在特定資料集中檢測相應物體準確度的一個標準。通常我們在 HOG + Linear SVM object detectors 和 Convolutional Neural Network detectors (R-CNN, Faster R-CNN, YOLO等)中使用該方法檢測其效能。

IOU的公式如下:

IoU相當於兩個區域重疊的部分除以兩個區域的集合部分得出的結果。

一般來說,score > 0.5或0.6 就可以認為重合度比較高了。

非極大值抑制(Non-Maximum Suppression):

非極大值抑制(Non-Maximum Suppression,NMS),顧名思義就是抑制不是極大值的元素,可以理解為區域性最大搜索。

通用的NMS演算法可以看這篇論文:Efficient Non-Maximum Suppression,這篇論文主要講對1維和2維資料的NMS實現。

NMS演算法在目標檢測中的用法:

將所有框的得分排序,選中最高分及其對應的框;

遍歷其餘的框,如果和當前最高分框的重疊面積(IOU)大於一定閾值,則將這個框刪除;

從未處理的框中繼續選一個得分最高的,重複上述過程。

舉例:

假設對於某個物體檢測到 4 個框(Boxes)A、B、C、D,每個框屬於這個物體的概率從小到大分別為S1、S2、S3、S4。

首先選擇概率最大的框D,分別計算B1, B2, B3 與 B4 的重疊程度 IOU,判斷其IOU是否大於預設定的閾值(比如將閾值設為0.5),假設B3的IOU超過閾值,則捨棄B3,標記B4為要保留的框;

然後從剩餘的框B1, B2中選取概率最大的框B2,計算B1 與 B2 的重疊程度 IoU,假設B1的IOU也超過閾值,則捨棄B1,標記B2為要保留的框;

檢查,發現已經沒有既沒有捨棄,也沒有保留的框了,遍歷結束;

 

滑窗法方法非常耗時,我們可以優化一下:

把思路一中的神經網路最後的全連線層也變成卷積層,如:

變為:

上面針對的都是單個物體的圖片,如果圖片中有多個物體該怎麼辦呢?

如果還是用上面的思路,我們需要的框的大小和數量會增加很多,這樣非常耗時。

改進方法:

找出可能含有物體的框(也就是候選框,比如選1000個候選框),這些框之間是可以互相重疊互相包含的,而不是在圖片上用各種大小的框(遍歷整張圖片)依次從圖片左上角掃到右下角(暴力列舉)。

找出候選框(Region Proposal)的改進方法:

常用的有EdgeBoxes和Selective Search。

Selective Search演算法:

這個演算法其實是借鑑了層次聚類的思想,將層次聚類的思想應用到區域的合併上面。

演算法論文:Selective Search for Object Recognition[J]. International Journal of Computer Vision, 2013

層次聚類思想:

最開始的時候將所有的每個資料點本身作為一個簇,然後找出距離最近的兩個簇將它們合為一個,不斷重複以上步驟直到簇的數量達到預設的簇的個數。

Selective Search演算法的主要思想:

影象中物體可能存在的區域應該是有某些相似性或者連續性區域的。因此,選擇搜尋基於上面這一想法採用子區域合併的方法進行提取候選邊界框。首先,對輸入影象進行分割演算法產生許多小的子區域。其次,根據這些子區域之間相似性(相似性標準主要有顏色、紋理、大小等等)進行區域合併,不斷的進行區域迭代合併。每次迭代過程中對這些合併的子區域做外切矩形(bounding boxes),這些子區域外切矩形就是通常所說的候選框。

Selective Search演算法的過程:

1、首先通過影象分割的方法(如大名鼎鼎的felzenszwalb演算法)獲得很多小的區域,假設現在影象上有n個預分割的區域(Efficient Graph-Based Image Segmentation),表示為R={R1, R2, ..., Rn};

2、計算區域集R裡每個相鄰區域的相似度S={s1,s2,…} ;

3、找出相似度最高的兩個區域,將其合併為新集(即兩個子區域合併為一個外切矩形(bounding boxes)的新區域),將這個新區域新增進R;

4、從S中移除所有與第3步中有關的子集(也就是被合併的區域所計算的相似度數值) ;

5、計算新集與所有子集的相似度 ;

6、跳至第3步,重複之後的過程,直到S為空。

為什麼要介紹Selective Search演算法呢,因為R-CNN和Fast R-CNN演算法都是用它產生候選框(region proposal)!下面我們來看看R-CNN演算法。

R-CNN(Regions with CNN features):

RCNN的論文:Rich feature hierarchies for accurate object detection and semantic segmentation

RCNN網路結構:

RCNN計算過程:

訓練一個AlexNet分類模型;

將該模型輸出層分類數從1000改為21(21是測試集中20個物體類別 + 1個背景),並去掉最後一個全連線層;

然後對上面的模型進行fine tuning,即用訓練好的引數(可以從已訓練好的模型中獲得)初始化微調後的網路,然後用自己的資料接著訓練;

利用Selective Search演算法對一張影象生成1000-2000個候選框;

對每個候選框縮放成224*224的大小,然後輸入CNN網路,儲存第五個pool層的輸出(即一個4096元素的一維向量,就是對候選框提取到的特徵) ;

訓練一個SVM分類器(二分類),然後將每個候選框提取到的特徵輸入到SVM進行分類,每個類別對應一個SVM,判斷是不是屬於這個類別,是就是positive,反之nagative;

對於SVM分好類的候選框做邊框座標的regression,用Bounding box迴歸值校正原來的建議視窗。對於每一個類,分別訓練一個regression模型。

舉例:

對狗分類的SVM:

候選框的regression:

RCNN網路也有一些缺點:

訓練過程是多級流水線。R-CNN首先使用目標候選框對卷積神經網路使用log損失進行微調。然後,它將卷積神經網路得到的特徵送入SVM。 這些SVM作為目標檢測器,替代通過微調學習的softmax分類器。 在第三個訓練階段,學習檢測框迴歸。

訓練在時間和空間上的開銷很大。對於SVM和檢測框迴歸訓練,從每個影象中的每個目標候選框提取特徵,並寫入磁碟。對於非常深的網路,如VGG16,這個過程在單個GPU上需要2.5天(VOC07 trainval上的5k個影象)。這些特徵需要數百GB的儲存空間。

目標檢測速度很慢。在測試時,對每個測試影象中的1000-2000個目標候選框各自提取特徵。用VGG16網路檢測目標每個影象需要47秒(在GPU上)。

怎麼解決這個問題呢?

這2000個候選框都是影象的一部分,那麼我們可以先對整個影象提取卷積層的特徵,然後將每個候選框在整個影象上的位置對映到卷積層的特徵圖上,這樣對於一張影象我們只需要提一次卷積層特徵,然後將每個候選框的卷積層特徵輸入到全連線層做後續操作。

但有一個問題還沒有解決,就是每個候選框的大小不一樣,而全連線的輸入資料長度必須固定,SPP Net就可以解決這個問題。

SPP-Net(Spatial Pyramid Pooling Network,空間金字塔池化網路):

SPP Net論文:Spatial Pyramid Pooling in Deep ConvolutionalNetworks for Visual Recognition,2015

論文地址:https://arxiv.org/pdf/1406.4729.pdf

我們知道,CNN網路的卷積層輸入不需要固定尺寸的影象,而全連線層需要固定大小的輸入。在R-CNN中,我們是將每個候選框縮放(warp)或者擷取(crop)成統一的224x224的大小,但這種縮放可能導致物體被拉伸變形或物體不全,這限制了識別精確度。

SPP Net的改進就是在最後一個卷積層和全連線層之間加入了一個SPP層(金字塔池化層)。此時網路的輸入可以是任意尺度的,在SPP層中每一個pooling的filter會根據輸入調整大小,保證傳到下一層全連線層的輸入固定。

SPP Net網路結構:

ROI Pooling層:

ROI是Region of Interest的簡寫,指的是在“特徵圖上的框”。

在SPP Net和Fast RCNN中, ROIS是指Selective Search完成後得到的所有“候選框”在特徵圖上的對映;

在Faster RCNN中,候選框是經過RPN演算法產生的,然後再把各個“候選框”對映到特徵圖上,得到ROIS。

ROI pooling層計算過程:

根據輸入的原始影象和Selective Search演算法提供的1000-2000個候選框位置,產生整個原始影象得到的feature map上對應的框,也就是我們說的ROI(Region of Interest,即“特徵圖上的框”);

將對映後的區域劃分為相同大小的塊,塊的數量是我們指定的;

對每個塊進行max pooling操作。

這樣我們就可以從不同大小的方框得到固定大小的相應的feature maps。輸出的pooling結果的大小隻和我們劃分成多少塊有關,而不取決於ROI和卷積feature maps的大小。

舉例:

輸入為一個8*8大小的feature map:

候選框位置座標:(左上角,右下角座標):(0,3),(7,8)。

先得到ROI,即feature map上與這個候選款位置對應的“特徵圖上的框”:

我們想讓這個ROI Pooling層的輸出為4個特徵值,那麼就要把候選框劃分成4塊(2*2):

對每個塊做max pooling操作,得到結果:

SPP Net計算過程:

SPP層的具體結構:

SPP層的具體結構如上圖,我們使用三層ROI Pooling層組成的SPP層,分別設定將圖片切分成(1,4,16)塊。這裡是採用了論文Spatial Pyramid Pooling in Deep ConvolutionalNetworks for Visual Recognition中的設定引數(1,4,16);

我們將Selective Search演算法提供的1000-2000個候選框的位置記錄下來,然後通過比例對映到整張影象的feature map上,每個候選框得到一個自己的候選區域的特徵圖B,然後將B同時送入上面的SPP層的3個ROI Pooling層;

SPP層第一層將整個特徵圖B進行池化,第二層將特徵圖B切分成4個小的特徵圖再池化,第三層將特徵圖B切分成16個小的特徵圖再池化。分別得到1、4、16個特徵值;

這樣我們就得到了21個特徵值。這21個特徵值經過softmax函式後就可以分類了。

SPP Net網路也有顯著的缺點:

像RCNN一樣,訓練過程是一個多級流水線,涉及提取特徵,使用log損失對網路進行微調,訓練SVM分類器,最後擬合檢測框迴歸。但是有一點要注意,就是SPP Net的優化演算法無法更新SPP層之前的卷積層(這些卷積層用來提取整張影象的特徵)。這種限制(固定的卷積層)影響了深層網路的精度。

Fast R-CNN:

Fast R-CNN論文:Fast R-CNN

Fast R-CNN論文地址:https://arxiv.org/pdf/1504.08083.pdf

Fast-R-CNN專案地址:https://github.com/rbgirshick/fast-rcnn

Fast R-CNN就是在RCNN的基礎上採納了SPP Net方法,對RCNN作了改進,使得網路效能進一步提高。

同RCNN相比,Fast RCNN作了以下改進:

規避R-CNN中冗餘的特徵提取操作,Fast RCNN只對整張影象全區域進行一次特徵提取;

用ROI pooling層取代最後一層max pooling層,直接在整張影象的feature map上找到Selective Search演算法提供的1000-2000個候選框的位置對應的特徵;

Fast RCNN網路末尾採用並行的不同的全連線層,可同時輸出分類結果和視窗迴歸結果,實現了end-to-end的多工訓練(建議框提取除外),也不需要額外的特徵儲存空間(RCNN中這部分特徵是供SVM和Bounding-box regression進行訓練的);

採用SVD對Fast R-CNN網路末尾並行的全連線層進行分解,減少計算複雜度,加快檢測速度。

Fast RCNN網路的結構:

其中在roi_pool5之前的網路結構均為可選的,參考的網路結構,作者論文中用到的有VGG和Alexnet。

Fast RCNN網路的計算過程:

使用Selective Search演算法從影象紅獲得1000-2000個候選框。基本思路:使用分割方法將影象分成小區域。在此之後,觀察現有的區域。之後以最高概率合併這兩個區域。重複此步驟,直到所有影象合併為一個區域位置。合併規則與RCNN是相同的,優先合併以下四種區域: 顏色(顏色直方圖)相近的; 紋理(梯度直方圖)相近的; 合併後總面積小的。最後,所有已經存在的區域都被輸出,並生成候選區域。

使用CNN網路提取原始影象的特徵圖,然後通過比例對映將所有的候選框對映到整張影象的feature map上,每個候選框得到一個自己的候選區域的特徵圖;

使用一個單層的ROI Pooling層對每一個候選框的特徵圖做max pooling,得到固定大小的輸出維度向量;

使用SoftmaxLoss代替了SVM進行分類,使用SmoothL1Loss取代Bouding box迴歸。

Fast R-CNN損失函式分成兩部分:

loss_cls損失函式:

該層根據之前輸出的4096維特徵,用softmax函式生成多個類別概率,根據生成的結果和標籤計算loss,評估分類代價:


 

loss_bbox損失函式,評估迴歸損失代價,比較真實分類u對應的預測平移縮放參數和真實平移縮放參數v=的差距:

結合分類損失和迴歸損失,Fast R-CNN總的loss函式為:

約定u=0為背景分類,那麼[u≥1] 函式表示背景候選區域即負樣本不參與迴歸損失,不需要對候選區域進行迴歸操作; 

λ控制分類損失和迴歸損失的平衡,論文中所有實驗λ=1。

Fast RCNN的缺點:

Fast RCNN仍然使用selective search演算法生成候選框,這個過程很耗費時間,其進行候選區域提取所花費的時間約為2~3秒,而提取特徵分類僅需要0.32秒,這就造成該模型無法滿足實時的應用需求,而且因為使用selective search來預先提取候選區域,Fast RCNN並沒有實現真正意義上的端到端訓練模式。

Faster R-CNN:

Faster R-CNN論文:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

Faster R-CNN論文地址:https://arxiv.org/pdf/1506.01497.pdf

Faster R-CNN是Fast R-CNN網路的改進,Faster R-CNN使用RPN(Region Proposal Network)演算法代替原來的Selective Search方法產生候選框(RPN層放在最後一個卷積層的後面),且產生候選框的CNN網路和目標檢測的CNN網路是同一個CNN網路。這使得候選框的數目從原有的約2000個減少為300個,且建議框的質量也有本質的提高。Faster R-CNN生成候選框僅需約10ms,足以滿足端到端的實時的應用需求。

Faster R-CNN網路結構:

注意:前面的CNN網路不一定要是VGG。比如我們可以用5層CNN網路的ZF模型。

 

Faster R-CNN的結構主要分為三大部分:

第一部分是共享的卷積層-backbone,第二部分是候選區域生成網路-RPN,第三部分是對候選區域進行分類的網路-classifier。

RPN與classifier部分均對目標框有修正。classifier部分就是Fast R-CNN結構。

RPN層(Region Proposal Network,區域生成網路  ):

RPN層的結構:

Anchor:

Anchor實際上指的是預先設定好長寬比與面積的候選框。但是這種候選框產生的機制與Selective Search演算法不一樣。

在論文中,作者為每一個位置生成9種anchor,包含三種面積(128×128,256×256,512×512),每種面積又包含三種長寬比(1:1,1:2,2:1)。

RPN層的計算過程:

原始影象先進入CNN網路後在最後一個卷積層(RPN層的前一個卷積層)輸出了256個通道的feature map。假設每個通道的feature map的尺寸WXH;

對於一個大小為H*W的feature map,它上面每一個畫素點對應9個anchor,這裡有一個重要的引數feat_stride = 16, 它表示特徵層上移動一個點,對應原圖移動16個畫素點(這個16實際上是因為前4個卷積層中一共經過了4次max pooling,每次pooling後feature map的長寬都減半,所以最後一個卷積層(是第五個卷積層,且第五個卷積層輸出前沒有max pooling)的輸出feature map的長和寬都只有原始影象的16分之一,我們就認為我們是在原始影象上每隔16個畫素點取一個位置,然後得到這個位置的9個anchor);

把WXH大小的feature map上的每一個點映射回原圖,得到這些點的座標,然後得到這些點的Anchors,每一個點都有9個Anchors(論文中設定為9個)。如果feature map有256個通道,每個通道的大小為W×H,則一共有W×H×9個anchors;

下圖是9種anchor:

最後一個卷積層輸出的256個通道的feature map再進入RPN層進行卷積(卷積核3*3),卷積出來的feature map仍然是256個通道,feature map的尺寸WXH不變;

RPN層輸出的256通道feature map要分別進入兩個全連線層:reg層和cls層

reg層:預測proposal的anchor對應的proposal的(x,y,w,h);

cls層:判斷該proposal是前景(object)還是背景(non-object)。

針對上一層的WXH大小的feature_map的每一個畫素點,在第一個卷積層卷積取出其256維的特徵(一共256個通道),得到一個H*W個2*K的向量,每個2*K維的向量代表的就是針對每一個anchor,該畫素點代表的原圖中以這個畫素點為中心的相應區域是它的前景還是背景的概率;

WXH大小的feature_map還要輸入第二個卷積層,這個卷積層得到W*H*個4*K維的向量,即對WXH大小的feature_map的每一個畫素點得到一個4*K維的特徵向量,該特徵向量中每四個值對應一個anchor的四個頂點的位置(對於視窗一般使用四維向量(x, y, w, h)表示,分別表示視窗的中心點座標和寬高);

然後將H*W個2*K的向量輸入softmax進行分類,注意這裡softmax分類的含義是一個畫素點中的9個anchor中哪一個anchor裡是一個object的概率,也就是判斷每一個anchor是物件還是背景;

Proposal的生成:

由上面anchors座標和bbox迴歸引數計算得到預測框proposal的座標;

處理proposal座標超出影象邊界的情況(使得座標最小值為0,最大值為寬或高) ;

濾除掉尺寸(寬高)小於給定閾值的proposal;

對剩下的proposal按照目標得分(fg score)從大到小排序,提取約前2000個proposal(數量約等於WXH); 

對提取的proposal進行非極大值抑制,篩選前300個proposal作為最後的輸出。

如何訓練這個RPN網路?

在計算Loss值之前,作者設定了anchors的標定方法。

正樣本標定規則:

如果Anchor對應的reference box與ground truth的IoU值最大(可能Iou不到0.7),標記為正樣本;

如果Anchor對應的reference box與ground truth的IoU>0.7,標記為正樣本;

負樣本標定規則:

如果Anchor對應的reference box與ground truth的IoU<0.3,標記為負樣本。

剩下的既不是正樣本也不是負樣本,不用於最終訓練。跨越了影象邊界的樣本也不用於最終訓練。

這個網路的loss function就是一個用於分類的softmax loss和一個用於迴歸(即預測物體的候選框座標)的smooth L1 loss,即有兩種損失:

區域生成網路的前後景分類損失(Object or not object);

區域生成網路的區域位置損失(Bounding box proposal);

LOSS函式為:

為樣本分類的概率值(表示anchor裡是一個object的概率),為樣本的標定值(label),anchor為正樣本時為1,為負樣本時為0。即是FAST RCNN中smooth函式的定義。 是一個平衡因子,具體設定可以參考論文,它與Ncls和Nreg有關。

 

這一項表示只有目標anchor的(anchor是正樣本)才有迴歸損失,其他anchor不參與計算。

兩項損失函式分別由以及一個平衡權重λ歸一化。分類損失的歸一化值為minibatch的大小,即;迴歸損失的歸一化值為anchor位置的數量,即;λ一般取值為10,這樣分類損失和迴歸損失差不多是等權重的。

 

RPN網路的訓練:

首先過濾掉超出影象邊界的anchors ;

在訓練RPN時,一個Mini-batch是由一幅影象中任意選取的256個proposal組成的,其中正負樣本的比例為1:1;

如果正樣本不足128,則多用一些負樣本以滿足有256個Proposal可以用於訓練,反之亦然;

訓練RPN時,與VGG共有的層引數可以直接拷貝經ImageNet訓練得到的模型中的引數,剩下沒有的層引數用標準差=0.01的高斯分佈初始化。

RPN也有缺點,最大的問題就是對小物體檢測效果很差,假設輸入為512*512,經過網路後得到的feature map是32*32,那麼feature map上的一個點就要負責周圍至少是16*16的一個區域的特徵表達,那對於在原圖上很小的物體它的特徵就難以得到充分的表示,因此檢測效果比較差。

 

Faster R-CNN計算過程:

接上面RPN的結構,RPN得到的每一個proposal都輸入一個單層的ROI Pooling層對做max pooling,得到固定大小的輸出維度向量;

利用Softmax Loss(這裡分類的是每個proposal屬於哪一種物體) 和Smooth L1 Loss(探測邊框迴歸)對分類概率和邊框迴歸(Bounding box regression)聯合訓練,如果類別數為N+1(包括背景),分類層的向量維數為N+1,迴歸層的向量維數則為4(N+1)。這裡的聯合Loss和Fast R-CNN網路一樣。

由下面的訓練方法,我們可以發現不同訓練階段用的loss函式不一樣,訓練RPN時用的是RPN的損失函式;訓練Fast R-CNN網路時用的還是原來Fast R-CNN網路的損失函式。

注意:

RPN網路和Fast R-CNN網路共用了前五層CNN網路!實際上,Faster R-CNN網路就是RPN網路+Fast R-CNN網路。

Faster R-CNN網路的訓練:

第一步是訓練RPN網路,用ImageNet模型M0初始化,訓練得到模型M1;

第二步是利用第一步訓練的RPN網路模型M1,生成Proposal P1。再使用Proposal P1,訓練Fast R-CNN網路,同樣用ImageNet模型初始化,訓練得到模型M2。這兩個階段兩個網路每一層的引數完全不共享;

第三步是使用第二步的Fast-RCNN網路引數初始化一個新的RPN網路,但是把RPN、Fast-RCNN共享的那些卷積層的learning rate設定為0,也就是不更新,僅僅更新RPN特有的那些網路層,重新訓練,得到模型M3。此時,兩個網路已經共享了所有公共的卷積層;

第四步是利用上一步訓練的RPN網路模型M3,生成Proposal P2。仍然固定共享的那些網路層,把Fast R-CNN特有的網路層也加入進來,再使用Proposal P2訓練Fast R-CNN網路,用RPN網路模型M3初始化,且卷積層引數和RPN引數不變,只微調Fast R-CNN獨有的網路層,得到最終模型M4。

此時,該網路已經實現我們設想的目標,即網路內部預測proposal並實現檢測的功能。

論文作者按上面步驟進行交替訓練,只迭代2次的原因是作者發現多次的迭代並沒有顯著的改善效能。 

ROI Pooling中存在的問題:

由於預選ROI的位置通常是有模型迴歸得到的,一般來說是個浮點數,而pooling後的特徵圖要求尺度固定,因此ROI Pooling這個操作存在兩次資料量化的過程。首先將候選框邊界量化為整數點座標值,然後將量化後的邊界區域平均分割成KxK個單元,對每個單元的邊界進行量化。經過上面的兩次量化操作,此時的ROI已經和最開始的ROI之間存在一定的偏差,這個偏差會影響檢測的精確度。

如下圖:

輸入一張800x800的圖片,圖片中有一個665x665的候選框恰好框中一隻狗。圖片經過特徵提取網路之後,整個圖片的特徵圖變為800/32 * 800/32,即25x25,但是665/32=20.87,帶有小數,ROI Pooling時會直接將它量化為20。這裡引入了第一次量化偏差。由於最終的特徵對映的大小為7x7,即需要將20x20的區域對映成7x7,矩形區域的邊長為2.86,又一次將其量化為2。這裡引入了第二次量化偏差。經過這兩次量化,候選ROI已經出現了嚴重的偏差(如圖中淺藍色部分所示)。更重要的是,在特徵圖上差0.1個畫素,對應到原圖上就是3.2個畫素。

當我們的候選框本身比較小時,這個偏差會顯得非常大,嚴重影響結果。

Mask R-CNN:

論文:Mask R-CNN

論文地址:https://arxiv.org/pdf/1703.06870.pdf

Mask R-CNN是一個例項分割(Instance segmentation)演算法,可以用來完成多種任務,包括目標分類、目標檢測、語義分割、例項分割、人體姿態識別等,這個演算法具有很好的擴充套件性和易用性。除此之外,我們可以更換不同的backbone architecture和Head Architecture來獲得不同效能的結果。

整個Mask R-CNN演算法的思路很簡單,就是在原始Faster-rcnn演算法的基礎上面增加了FCN來產生對應的MASK分支。對於RPN前面的CNN網路,由VGG換成了ResNeXt-101(深度殘差網路)同時,對於ROI Pooling中存在的畫素偏差問題,提出了ROIAlign策略來解決。即Faster-rcnn + FCN,或者說是RPN + ROIAlign + Fast-rcnn + FCN。

影象分類(Image classification)、目標檢測(Object detection)、語義分割(Semantic segmentation)、例項分割(Instance segmentation)之間的區別:

語義分割和例項分割都是目標分割中的兩個小的領域,都是用來對輸入的圖片做分割處理。 通常意義上的目標分割指的是語義分割,語義分割已經有很長的發展歷史,已經取得了很好地進展,目前有很多的學者在做這方面的研究。而例項分割是一個從目標分割領域獨立出來的一個小領域,是最近幾年才發展起來的,與前者相比,後者更加複雜,當前研究的學者也比較少,是一個有研究空間的熱門領域。

如下圖,左下角圖是語義分割的結果,右下角圖是例項分割的結果。兩者最大的區別就是圖中的"cube物件",在語義分割中給了它們相同的顏色,而在例項分割中卻給了不同的顏色。即例項分割需要在語義分割的基礎上對同類物體進行更精細的分割。

Mask R-CNN網路結構:

Mask R-CNN網路可以分解成3個部分:Faster R-CNN、ROIAlign和FCN。

Faster R-CNN:

Faster R-CNN上面已經介紹過,可以往回翻看一下。

ROIAlign:

在介紹Faster R-CNN網路時,我們已經介紹了ROI Pooling中存在的問題,即ROI Pooling操作中的兩次資料量化的過程中可能會引入偏差。

ROIAlign在這一點上進行了改進。ROI Pooling和ROIAlign最大的區別是:前者使用了兩次量化操作,而後者並沒有採用量化操作。

ROIAlign層中,ROI對映到feature map後,不再進行四捨五入。然後將候選區域分割成K x K個單元, 在每個單元中計算固定四個座標位置,用雙線性內插的方法計算出這四個位置的值,然後進行最大池化操作。

如:

 

舉例:

假如還是上面ROI Pooling中存在的問題中的例子,現在我們用ROIAlign來處理它。

輸入圖片為800x800畫素,圖片中有一個665x665的候選框恰好框中一隻狗。圖片經過特徵提取網路之後,整個圖片的特徵圖變為800/32 * 800/32,即25x25,但是665/32=20.87,我們就用20.78,不用20替代它,20.78 / 7 = 2.97,我們就用2.97,也不用2來代替它。現在怎麼用這些浮點值來計算呢?

我們的解決思路是使用“雙線性插值”演算法。雙線性插值是一種比較好的影象縮放演算法,它充分利用了原圖中虛擬點(比如20.56這個浮點數,畫素位置都是整數值,沒有浮點值)四周的四個真實存在的畫素值來共同決定目標圖中的一個畫素值,就可以將20.56這個虛擬的位置點對應的畫素值估計出來。

比如下圖中

藍色的虛線框表示卷積後獲得的feature map,黑色實線框表示ROI feature,最後需要輸出的大小是2x2,那麼我們就利用雙線性插值來估計這些藍點(虛擬座標點,又稱雙線性插值的網格點)處所對應的畫素值,最後得到相應的輸出。這些藍點是2x2Cell中的隨機取樣的普通點,作者指出,這些取樣點的個數和位置不會對效能產生很大的影響,你也可以用其它的方法獲得。然後在每一個橘紅色的區域裡面進行max pooling或者average pooling操作,獲得最終2x2的輸出結果。我們的整個過程中沒有用到量化操作,沒有引入誤差,即原圖中的畫素和feature map中的畫素是完全對齊的,沒有偏差,這不僅會提高檢測的精度,同時也會有利於例項分割。

FCN:

FCN演算法是一個經典的語義分割演算法,可以對圖片中的目標進行準確的分割。其總體架構如上圖所示,它是一個端到端的網路,主要的模快包括卷積和去卷積,即先對影象進行卷積和池化,使其feature map的大小不斷減小;然後進行反捲積操作,即進行插值操作,不斷的增大其feature map,最後對每一個畫素值進行分類。從而實現對輸入影象的準確分割。

關於FCN演算法可以看這篇論文:https://arxiv.org/pdf/1411.4038.pdf

在論文:Mask R-CNN(https://arxiv.org/pdf/1703.06870.pdf)中,作者實際上提出了兩種不同產生mask的網路結構:

左邊的Faster R-CNN/ResNet:

對於左邊的架構,我們的backbone使用的是預訓練好的ResNet,使用了ResNet倒數第4層的網路。輸入的ROI首先獲得7x7x1024的ROI feature,然後將其升維到2048個通道(這裡修改了原始的ResNet網路架構),然後有兩個分支,上面的分支負責分類和迴歸,下面的分支負責生成對應的mask。由於前面進行了多次卷積和池化,減小了對應的解析度,mask分支開始利用反捲積進行解析度的提升,同時減少通道的個數,變為14x14x256,最後輸出了14x14x80的mask模板。

右邊的Faster R-CNN/FPN:

右邊使用到的backbone是FPN網路,這是一個新的網路,通過輸入單一尺度的圖片,最後可以得到對應的Feature Pyramid(特徵金字塔)。該網路可以在一定程度上面提高檢測的精度,當前很多的方法都用到了它。由於FPN網路已經包含了res5,可以更加高效的使用特徵,因此這裡使用了較少的filters。該架構也分為兩個分支,作用與前者相同,但是分類分支和mask分支和前者相比有很大的區別。可能是因為FPN網路可以在不同尺度的特徵上面獲得許多有用資訊,因此分類時使用了更少的濾波器。而mask分支中進行了多次卷積操作,首先將ROI變化為14x14x256的feature,然後進行了5次相同的操作(不清楚這裡的原理,期待著你的解釋),然後進行反捲積操作,最後輸出28x28x80的mask。即輸出了更大的mask,與前者相比可以獲得更細緻的mask,因此可以更好的檢測更加小的目標。 

FPN網路(Feature Pyramid Networks,特徵金字塔網路):

論文:Feature Pyramid Networks for Object Detection

論文地址:https://arxiv.org/pdf/1612.03144v2.pdf

在faster rcnn進行目標檢測時,無論是rpn還是fast rcnn,roi 都作用在最後一層,這在大目標的檢測上沒有問題,但是對於小目標檢測時,由於小目標占據的畫素區域本來就小,當進行卷積池化到最後一層,特徵圖上對應的畫素點就很少或者就沒有了。所以,為了解決多尺度檢測的問題,引入了FPN網路。

上面是4種特徵金字塔網路。

圖(a)是相當常見的一種多尺度方法,稱為featurized image pyramid,這種方法在較早的人工設計特徵(DPM)時被廣泛使用,在CNN中也有人使用過。就是對input iamge進行multi scale,通過設定不同的縮放比例實現。這種可以解決多尺度,但是相當於訓練了多個模型(假設要求輸入大小固定),即便允許輸入大小不固定,但是也增加了儲存不同scale影象的記憶體空間。

圖(b)就是CNN網路,cnn相比人工設計特徵,能夠自己學習到更高階的語義特徵,同時CNN對尺度變化魯棒,因此如圖,從單個尺度的輸入計算的特徵也能用來識別,但是遇到明顯的多尺度目標檢測時,還是需要金字塔結構來進一步提升準確率。 

從現在在imageNet和COCO資料集上領先的的一些方法來看,在測試的時候都用到了featurized image pyramid方法,即結合(a),(b)。 說明了特徵化影象金字塔的每一級的好處在於,產生了多尺度的特徵表示,每一級的特徵都有很強的語義(因為都用cnn生成的特徵),包括高解析度的一級(最大尺度的輸入影象)。 但是這種模式有明顯的弊端,相比於原來方法,時間增長了4倍,很難在實時應用中使用,同樣,也增大了儲存代價。

圖(c)是SSD方法中使用的CNN金字塔形的層級特徵。SSD方法中的特徵金字塔重利用了前向過程計算出的來自多層的多尺度特徵圖(這是CNN網路計算時本來就會生成的),因此這種重利用是不消耗額外的資源。但是SSD為了避免使用low-level的特徵,放棄了淺層的feature map,而是從conv4_3開始建立金字塔,而且加入了一些新的層。也就是說,SSD放棄了重利用更高解析度的feature map(最開始的兩三層卷積出的feature map),但是這些feature map對檢測小目標非常重要。這就是SSD與FPN的區別。

圖(4)是FPN的結構,FPN是為了自然地利用CNN層級特徵的金字塔形式,同時生成在所有尺度上都具有強語義資訊的特徵金字塔。FPN的結構設計了自下而上的路徑和橫向連線,以此融合具有高解析度的淺層layer和具有豐富語義資訊的深層layer。這樣就實現了從單尺度的單張輸入影象,快速構建在所有尺度上都具有強語義資訊的特徵金字塔,同時不產生明顯的代價。

自上而下的路徑和橫向連線:

CNN的前饋計算就是自下而上的路徑,特徵圖經過卷積核計算,通常是越變越小的,當然也有一些特徵層的輸出和原來大小一樣,稱為“相同網路階段”(same network stage ),這與我們設計的CNN網路結構有關。對於我們的FPN網路,作者把網路的每個階段定義一個金字塔級別, 然後選擇每個階段的最後一層的輸出作為特徵圖的參考集。 這種選擇是很自然的,因為每個階段的最深層應該具有最強的特徵。

比如說,對於ResNets,作者使用了每個階段的最後一個殘差結構的特徵啟用輸出。將這些殘差模組輸出表示為{C2, C3, C4, C5},對應於conv2,conv3,conv4和conv5的輸出,並且注意它們相對於輸入影象具有{4, 8, 16, 32}畫素的步長。考慮到記憶體佔用,沒有將conv1包含在金字塔中。

橫向連線就是把更抽象,語義更強的高層特徵圖進行上取樣,然後把該特徵橫向連線(lateral connections )至前一層特徵,因此高層特徵得到加強。要注意的是,橫向連線的兩層特徵在空間尺寸上要相同。

如,把高層特徵做2倍上取樣(最鄰近上取樣法,可以參考反捲積),然後將其和對應的前一層特徵結合(前一層要經過1 * 1的卷積核才能用,目的是改變channels,應該是要和後一層的channels相同),結合方式就是做畫素間的加法。重複迭代該過程,直至生成最精細的特徵圖。迭代開始階段,作者在C5層後面加了一個1 * 1的卷積核來產生最粗略的特徵圖,最後,作者用3 * 3的卷積核去處理已經融合的特徵圖(為了消除上取樣的混疊效應),以生成最後需要的特徵圖。為了後面的應用能夠在所有層級共享分類層,這裡坐著固定了3*3卷積後的輸出通道為d,這裡設為256,因此所有額外的卷積層(比如P2)具有256通道輸出。這些額外層沒有用非線性。{C2, C3, C4, C5}層對應的融合特徵層為{P2, P3, P4, P5},對應的層空間尺寸是相通的。

Mask R-CNN演算法過程:

首先,輸入一幅你想處理的圖片,然後進行對應的預處理操作,或者預處理後的圖片;

然後,將其輸入到一個預訓練好的神經網路中(ResNet等)獲得對應的feature map;

接著,對這個feature map中的每一點設定預定個的ROI,從而獲得多個候選ROI;

接著,將這些候選的ROI送入RPN網路進行二值分類(前景或背景)和BB迴歸,過濾掉一部分候選的ROI;

接著,對這些剩下的ROI進行ROIAlign操作(即先將原圖和feature map的pixel對應起來,然後將feature map和固定的feature對應起來);

最後,對這些ROI進行分類(N類別分類)、BB迴歸和MASK生成(在每一個ROI裡面進行FCN操作)。

Mask R-CNN的loss函式:

每個ROI的loss函式就是分類,迴歸加mask預測的損失之和。 

其中Lcls和Lbox和Faster r-cnn中定義的相同。對於每一個ROI,mask分支有Km*m維度的輸出,其對K個大小為m*m的mask進行編碼,每一個mask有K個類別。注意這裡mask的輸出使用了sigmoid函式。最後可以通過與閾值0.5作比較輸出二值mask。這樣避免了類間的競爭,將分類的任務交給專業的classification分支。Lmask對於每一個畫素使用二值的sigmoid交叉熵損失。