從R-CNN到Mask R-CNN

自從2012年的ILSVRC競賽中基於CNN的方法一鳴驚人之後,CNN已成為圖像分類、檢測和分割的神器。其中在圖像檢測的任務中,R-CNN系列是一套經典的方法,從最初的R-CNN到後來的Fast R-CNN, Faster R-CNN 和今年的Mask R-CNN, 我們可以看到CNN在圖像檢測中是如何一點一點提高的。和本文來一道回顧R-CNN家族的發展史,了解這些方法的演變和這個演變過程中的那些富有創意的想法。

R-CNN 系列的四篇文章如下:

  1. R-CNN: arxiv.org/abs/1311.2524
  2. Fast R-CNN: arxiv.org/abs/1504.0808
  3. Faster R-CNN: arxiv.org/abs/1506.0149
  4. Mask R-CNN: arxiv.org/abs/1703.0687

圖像的檢測任務是從一個複雜場景的圖像中找到不同的物體,並且給出各個物體的邊界框。圖像檢測的三個著名的數據集是PASCAL VOC,ImageNet和微軟COCO. PASCAL VOC包含20個物體的類別,而ImageNet包含一千多種物體類別,COCO有80中物體類別和150萬個物體實例。

PASCAL VOC目標檢測

COCO目標檢測和實例分割

1, R-CNN

R-CNN的思路是很直觀的三步曲:1,得到若干候選區域;2, 對每個候選區域分別用CNN分類;3,對每個候選區域分別進行邊框預測。

在R-CNN出現之前,目標檢測的流行思路是先從圖像中得到一些候選區域,再從候選區域中提取一些特徵,然後利用一個分類器對這些特徵進行分類。分類的結果和候選區域的邊界框就可以作為目標檢測的輸出。一種得到候選區域的方法是Selective Search, 該方法可以得到不同尺度的候選區域,每個候選區域是一個聯通的區域。如下圖中,左邊得到的是較小的候選區域,右邊是較大的候選區域,在該尺度下包含了整個人的區域。

Selective Search得到不同尺度的候選區域

R-CNN的想法是,既然CNN在圖像分類任務中的表現很好,可以自動學習特徵,何不用它來對每個候選區域進行特徵提取呢?於是R-CNN在Selective Search得到的候選區域的基礎上,將每個候選區域縮放到一個固定的大小,並且作為AlexNet(ImageNet 2012圖像分類競賽的冠軍)的輸入,依次對這些區域進行特徵提取,然後再使用支持向量機對各個區域的特徵分別進行分類。R-CNN的過程如下:

R-CNN示意圖

這樣就能得到一個檢測的結果了。但是Slelective Search得到的候選區域並不一定和目標物體的真實邊界相吻合,因此R-CNN提出對物體的邊界框做進一步的調整,使用一個線性回歸器來預測一個候選區域中物體的真實邊界。該回歸器的輸入就是候選區域的特徵,而輸出是邊界框的坐標。

R-CNN的效果很不錯,比VOC 2012的最好的結果提高了30%的準確度。但是問題就是太慢,主要有三方面原因:1,候選區域的生成是一個耗時的過程;2,對候選區域特徵提取需要在單張圖像上使用AlexNet 2000多次; 3, 特徵提取、圖像分類、邊框回歸是三個獨立的步驟,要分別進行訓練,測試過程中的效率也較低。

2, Fast R-CNN

為了解決R-CNN中效率低的問題,Fast R-CNN想,一張圖像上要使用AlexNet 2000多次來分別得到各個區域的特徵,但很多區域都是重合的,可否避免這些重複計算,只在一張圖像上使用一次AlexNet,然後再得到不同區域的特徵呢?

於是Fast R-CNN提出了一個ROI Pooling的方法,先對輸入圖像使用一次CNN前向計算,得到整個圖像的特徵圖,再在這個特徵圖中分別取提取各個候選區域的特徵。由於候選區域的大小不一樣,而對應的特徵需要要具有固定的大小,因此該方法對各個候選區域分別使用POI Pooling, 其做法是:假設第 i 個候選區域ROI的大小為h_itimes w_i, 要使輸出的大小為htimes w,那麼就將該ROI分成htimes w 個格子,每一個格子的大小為(h_i/h)times (w_i/w), 然後對每一格子使用max-pooling得到大小為htimes w的特徵圖像。

Fast R-CNN示意圖, 將每個候選區域分成h x w大小的格子做pooling

Fast R-CNN的第二點創意是把之前獨立的三個步驟(特徵提取、分類和回歸)放到一個統一的網路結構中。該網路結構同時預測一個候選區域的物體類別和該物體的邊界框,使用兩個全連接的輸出層分別進行類別預測和邊框預測(如下圖所示),將這兩個任務進行同時訓練,利用一個聯合代價函數:

L(p,u,t^{u},v )=L_{cls}(p,u) + lambda[ugeq 1]L_{reg}(t^{u},v)

公式中的兩項分別是classification loss 和regression loss。

特徵提取-分類-回歸聯合網路

使用VGG16作為特徵提取網路,Fast R-CNN在測試圖像上的處理時間比R-CNN快了200多倍,並且精度更高。如果不考慮生成候選區域的時間,可以達到實時檢測。生成候選區域的Selective Search演算法處理一張圖像大概需要2s的時間,因此成為該方法的一個瓶頸。

3, Faster R-CNN

上面兩種方法都依賴於Selective Search生成候選區域,十分耗時。考慮到CNN如此強大,Faster R-CNN提出使用CNN來得到候選區域。假設有兩個卷積神經網路,一個是區域生成網路,得到圖像中的各個候選區域,另一個是候選區域的分類和邊框回歸網路。這兩個網路的前幾層都要計算卷積,如果讓它們在這幾層共享參數,只是在末尾的幾層分別實現各自的特定的目標任務,那麼對一幅圖像只需用這幾個共享的卷積層進行一次前向卷積計算,就能同時得到候選區域和各候選區域的類別及邊框。

Faster R-CNN:在卷積後的特徵圖上使用Region Proposal Network

候選區域生成網路(Region Proposal Network, RPN)如下,先通過對輸入圖像的數層卷積得到一個特徵圖像,然後在特徵圖像上生成候選區域。它使用一個ntimes nn=3)的滑動窗口,將局部的特徵圖像轉換成一個低維特徵, 預測k個的區域(cls層,2k個輸出)是否為候選區域和對應的k個邊框(reg層,4k個輸出)。這裡的k個區域被稱為錨(anchor), 對應著與滑動窗口具有相同的中心的不同大小和不同長寬比的矩形框。假設卷積後的特徵圖像大小為Wtimes H,那麼一共有WHk個錨。這種特徵提取和候選區域生成的方法具有位移不變性。

對一個滑動窗口中的anchor預測候選區域

使用RPN得到候選區域後,對候選區域的分類和邊框回歸仍然使用Fast R-CNN。這兩個網路使用共同的卷積層。 由於Fast R-CNN的訓練過程中需要使用固定的候選區域生成方法,不能同時對RPN和Fast R-CNN使用反向傳播演算法進行訓練。該文章使用了四個步驟完成訓練過程:1,單獨訓練RPN;2,使用步驟中1得到的區域生成方法單獨訓練Fast R-CNN; 3, 使用步驟2得到的網路作為初始網路訓練RPN;4, 再次訓練Fast R-CNN, 微調參數。

Faster R-CNN的精度和Fast R-CNN差不多,但是訓練時間和測試時間都縮短了10倍。

4, Mask R-CNN

Faster R-CNN 在物體檢測中已達到非常好的性能,Mask R-CNN在此基礎上更進一步:得到像素級別的檢測結果。 對每一個目標物體,不僅給出其邊界框,並且對邊界框內的各個像素是否屬於該物體進行標記。

Mask R-CNN: 像素級別的目標檢測

Mask R-CNN利用Faster R-CNN中已有的網路結構,再添加了一個頭部分支,使用FCN對每個區域做二值分割。

Mask R-CNN還提出了兩個小的改進使分割的結果更好。第一,對各個區域分割時,解除不同類之間的耦合。假設有K類物體,一般的分割方法直接預測一個有K個通道的輸出,其中每個通道代表對應的類別。而Mask R-CNN預測K個有2個通道(前景和背景)的輸出,這樣各個類別的預測是獨立的。第二,Faster R-CNN中使用ROI Pooling之前的取整操作使特徵圖中所使用的ROI與原圖中ROI的位置不完全對應。在Fast和Faster R-CNN中,在使用ROI Pooling之前的特徵圖大小是原圖的1/16。假設一個ROI在原圖中的橫坐標範圍是 w_0w_1 ,縱坐標範圍是 h_0h_1 ,那麼在特徵圖中該ROI的橫坐範圍是 w_0/16w_1/16 , 縱坐標範圍是 h_0/16h_1/16 , 取整得到 left[ w_0/16 right][w_1/16] , [h_0/16] , [h_1/16] 。這樣會導致Pooling前的特徵圖中的ROI與原圖中的ROI沒有完全對齊。這不會對分類和邊框回歸造成大的影響,但是會影響分割的結果,因為沒有保持空間對應關係。Faster R-CNN不取整,使用雙線性插值得到 與原圖中ROI對應的特徵圖中的區域,保留坐標的對應關係,該方法稱作ROIAlign.

上述幾種方法的代碼:

R-CNN

  • Caffe版本:rbgirshick/rcnn

Fast R-CNN

  • Caffe版本: rbgirshick/fast-rcnn

Faster R-CNN

  • Caffe版本: github.com/rbgirshick/p
  • PyTorch版本: github.com/longcw/faste
  • MatLab版本: github.com/ShaoqingRen/

Mask R-CNN

  • PyTorch版本: github.com/felixgwu/mas
  • TensorFlow版本: github.com/CharlesShang

註:R-CNN, Fast R-CNN和Faster R-CNN已在之前的文章總結過,這裡添上Mask R-CNN。更多目標檢測的方法在《深度卷積神經網路在目標檢測中的進展》這篇文章中。另外,《A Brief History of CNNs in Image Segmentation: From R-CNN to Mask R-CNN》這篇文章也做了詳細的介紹。


推薦閱讀:

視覺目標檢測和識別之過去,現在及可能
Mask_RCNN:基於Keras and TensorFlow 的 Mask R-CNN 為 目標檢測和情景分割
目標檢測筆記二:Object Detection API 小白實踐指南
【簡評】FaceBoxes
感覺靈感被掏空?你需要這 9 篇論文來補一補 | PaperDaily #05

TAG:目标检测 | MaskR-CNN | 卷积神经网络CNN |