實例分割模型Mask R-CNN詳解:從R-CNN,Fast R-CNN,Faster R-CNN再到Mask R-CNN

好的文章怕沒了,先轉載過來。。。。。。。



實例分割模型Mask R-CNN詳解:從R-CNN,Fast R-CNN,Faster R-CNN再到Mask R-CNN

原創 2018年01月21日 10:46:47
  • 1244

   Mask R-CNN是ICCV 2017的best paper,彰顯了機器學習計算機視覺領域在2017年的最新成果。在機器學習2017年的最新發展中,單任務的網絡結構已經逐漸不再引人矚目,取而代之的是集成,複雜,一石多鳥的多任務網絡模型。Mask R-CNN就是典型的代表。本篇大作的一作是何凱明,在該篇論文發表的時候,何凱明已經去了FaceBook。我們先來看一下,Mask R-CNN取得了何等的成果。



   大家可以看到,在實例分割Mask R-CNN框架中,還是主要完成了三件事情:

   1) 目標檢測,直接在結果圖上繪製了目標框(bounding box)。

   2) 目標分類,對於每一個目標,需要找到對應的類別(class),區分到底是人,是車,還是其他類別。

   3) 像素級目標分割,在每個目標中,需要在像素層面區分,什麼是前景,什麼是背景。

   可是,在解析Mask R-CNN之前,筆者不得不告訴大家一個事實,Mask R-CNN是繼承於Faster R-CNN (2016)的,Mask R-CNN只是在Faster R-CNN上面加了一個Mask Prediction Branch (Mask 預測分支),並且改良了ROI Pooling,提出了ROI Align。從統計數據來看,"Faster R-CNN"在Mask R-CNN論文的前三章中出現了二十餘次,因此,如果不瞭解Ross Girshick和何凱明之前的工作,是很難弄懂Mask R-CNN的。所以,筆者在解析Mask R-CNN之前,先給大家分析一下Faster R-CNN。

   在給大家解析Faster R-CNN之前,筆者又要告訴大家,Faster R-CNN是繼承於Fast R-CNN (2015),Fast R-CNN繼承於R-CNN (2014)。因此,索性破釜沉舟,在本篇博文中,筆者就按照R-CNN, Fast R-CNN,Faster R-CNN再到Mask R-CNN的發展順序全部解析。

   首先時間回到了2014年,在2014年,正是深度學習如火如荼的發展的第三年。在CVPR 2014年中Ross Girshick提出的R-CNN中,使用到了卷積神經網絡來進行目標檢測。下面筆者就來概述一下R-CNN是如何採用卷積神經網絡進行目標檢測的工作。


   首先模型輸入爲一張圖片,然後在圖片上提出了約2000個待檢測區域,然後這2000個待檢測區域一個一個地(串聯方式)通過卷積神經網絡提取特徵,然後這些被提取的特徵通過一個支持向量機(SVM)進行分類,得到物體的類別,並通過一個bounding box regression調整目標包圍框的大小。下面,筆者簡要概述一下R-CNN是怎麼實現以上步驟的。

   首先在第一步提取2000個待檢測區域的時候,是通過一個2012年提出的方法,叫做selective search。簡單來說就是通過一些傳統圖像處理方法將圖像分成若干塊,然後通過一個SVM將屬於同一目標的若干塊拿出來。selective search的核心是一個SVM,架構如下所示:


   然後在第二步進行特徵提取的時候,Ross直接藉助了當時深度學習的最新成果AlexNet (2012)。那麼,該網絡是如何訓練的呢?是直接在ImageNet上面訓練的,也就是說,使用圖像分類數據集訓練了一個僅僅用於提取特徵的網絡。

   在第三步進行對目標的時候,使用了一個支持向量機(SVM),在訓練這個支持向量機的時候,結合目標的標籤(類別)與包圍框的大小進行訓練,因此,該支持向量機也是被單獨訓練的。

   在2014年R-CNN橫空出世的時候,顛覆了以往的目標檢測方案,精度大大提升。對於R-CNN的貢獻,可以主要分爲兩個方面:

   1) 使用了卷積神經網絡進行特徵提取

   2) 使用bounding box regression進行目標包圍框的修正

   但是,我們來看一下,R-CNN有什麼問題:

   1) 耗時的selective search,對一幀圖像,需要花費2s。

   2) 耗時的串行式CNN前向傳播,對於每一個RoI,都需要經過一個AlexNet提特徵,爲所有的RoI提特徵大約花費47s。

   3) 三個模塊是分別訓練的,並且在訓練的時候,對於存儲空間的消耗很大。

   那麼,面對這種情勢,Ross在2015年提出的Fast R-CNN進行了改進,下面我們來概述一下Fast R-CNN的解決方案:


   首先還是採用selective search提取2000個候選框,然後,使用一個神經網絡對全圖進行特徵提取。接着,使用一個RoI Pooling Layer在全圖特徵上摘取每一個RoI對應的特徵,再通過全連接層(FC Layer)進行分類與包圍框的修正。Fast R-CNN的貢獻可以主要分爲兩個方面:

   1) 取代R-CNN的串行特徵提取方式,直接採用一個神經網絡對全圖提取特徵(這也是爲什麼需要RoI Pooling的原因)。

   2) 除了selective search,其他部分都可以合在一起訓練。

   可是,Fast R-CNN也有缺點,體現在耗時的selective search還是依舊存在。那麼,如何改良這個缺陷呢?發表於2016年的Faster R-CNN進行了如下創新:

   取代selective search,直接通過一個Region Proposal Network (RPN)生成待檢測區域,這麼做,在生成RoI區域的時候,時間也就從2s縮減到了10ms。我們來看一下Faster R-CNN是怎麼做的。


   首先使用共享的卷積層爲全圖提取特徵,然後將得到的feature maps送入RPN,RPN生成待檢測框(指定RoI的位置)並對RoI的包圍框進行第一次修正。之後就是Fast R-CNN的架構了,RoI Pooling Layer根據RPN的輸出在feature map上面選取每個RoI對應的特徵,並將維度置爲定值。最後,使用全連接層(FC Layer)對框進行分類,並且進行目標包圍框的第二次修正。尤其注意的是,Faster R-CNN真正實現了端到端的訓練(end-to-end training)

   要理解Mask R-CNN,只有先理解Faster R-CNN。因此,筆者根據Faster R-CNN的架構(Faster R-CNN的ZF model的train.prototxt),畫了一個結構圖,如下所示:


   如上圖所示,Faster R-CNN的結構主要分爲三大部分,第一部分是共享的卷積層-backbone,第二部分是候選區域生成網絡-RPN,第三部分是對候選區域進行分類的網絡-classifier。其中,RPN與classifier部分均對目標框有修正。classifier部分是原原本本繼承的Fast R-CNN結構。我們下面來簡單看看Faster R-CNN的各個模塊。

   首先來看看RPN的工作原理:


   簡單地說,RPN依靠一個在共享特徵圖上滑動的窗口,爲每個位置生成9種預先設置好長寬比與面積的目標框(文中叫做anchor)。這9種初始anchor包含三種面積(128×128,256×256,512×512),每種面積又包含三種長寬比(1:1,1:2,2:1)。示意圖如下所示:


   由於共享特徵圖的大小約爲40×60,RPN生成的初始anchor的總數約爲20000個(40×60×9)。對於生成的anchor,RPN要做的事情有兩個,第一個是判斷anchor到底是前景還是背景,意思就是判斷這個anchor到底有沒有覆蓋目標,第二個是爲屬於前景的anchor進行第一次座標修正。對於前一個問題,Faster R-CNN的做法是使用SoftmaxLoss直接訓練;對於後一個問題,採用SmoothL1Loss進行訓練。那麼,RPN怎麼實現呢?這個問題通過RPN的本質很好求解,RPN的本質是一個樹狀結構,樹幹是一個3×3的卷積層,樹枝是兩個1×1的卷積層,第一個1×1的卷積層解決了前後景的輸出,第二個1×1的卷積層解決了邊框修正的輸出。來看看在代碼中是怎麼做的:


   從如上代碼中可以看到,對於RPN輸出的特徵圖中的每一個點,一個1×1的卷積層輸出了18個值,因爲是每一個點對應9個anchor,每個anchor有一個前景分數和一個背景分數,所以9×2=18。另一個1×1的卷積層輸出了36個值,因爲是每一個點對應9個anchor,每個anchor對應了4個修正座標的值,所以9×4=36。那麼,要得到這些值,RPN網絡需要訓練。在訓練的時候,就需要對應的標籤。那麼,如何判定一個anchor是前景還是背景呢?文中做出瞭如下定義:如果一個anchor與ground truth的IoU在0.7以上,那這個anchor就算前景(positive)。類似地,如果這個anchor與ground truth的IoU在0.3以下,那麼這個anchor就算背景(negative)。在作者進行RPN網絡訓練的時候,只使用了上述兩類anchor,與ground truth的IoU介於0.3和0.7的anchor沒有使用。在訓練anchor屬於前景與背景的時候,是在一張圖中,隨機抽取了128個前景anchor與128個背景anchor。

   在上一段中描述了前景與背景分類的訓練方法,本段描述anchor邊框修正的訓練方法。邊框修正主要由4個值完成,tx,ty,th,tw。這四個值的意思是修正後的框在anchor的x和y方向上做出平移(由tx和ty決定),並且長寬各自放大一定的倍數(由th和ty決定)。那麼,如何訓練網絡參數得到這四個值呢?Fast R-CNN給出了答案,採用SmoothL1loss進行訓練,具體可以描述爲:


   到這裏有個問題,就是不是對於所有的anchor,都需要進行anchor包圍框修正的參數訓練,只是對positive的anchors有這一步。因此,在訓練RPN的時候,只有對128個隨機抽取的positive anchors有這一步訓練。因此,訓練RPN的損失函數可以寫成:


   在這裏Lreg就是上面的Lloc,λ被設置爲10,Ncls爲256,Nreg爲2400。這樣設置的話,RPN的兩部分loss值能保持平衡。

   到這裏RPN就解析完畢了,下面我們來看看後面的classifier,但是在介紹classifier之前,我們先來看看RoI Pooling到底做了什麼?

   首先第一個問題是爲什麼需要RoI Pooling?答案是在Fast R-CNN中,特徵被共享卷積層一次性提取。因此,對於每個RoI而言,需要從共享卷積層上摘取對應的特徵,並且送入全連接層進行分類。因此,RoI Pooling主要做了兩件事,第一件是爲每個RoI選取對應的特徵,第二件事是爲了滿足全連接層的輸入需求,將每個RoI對應的特徵的維度轉化成某個定值。RoI Pooling示意圖如下所示:


   如上圖所示,對於每一個RoI,RoI Pooling Layer將其對應的特徵從共享卷積層上拿出來,並轉化成一樣的大小(6×6)。

   在RoI Pooling Layer之後,就是Fast R-CNN的分類器和RoI邊框修正訓練。分類器主要是分這個提取的RoI具體是什麼類別(人,車,馬等等),一共C+1類(包含一類背景)。RoI邊框修正和RPN中的anchor邊框修正原理一樣,同樣也是SmoothL1 Loss,值得注意的是,RoI邊框修正也是對於非背景的RoI進行修正,對於類別標籤爲背景的RoI,則不進行RoI邊框修正的參數訓練。對於分類器和RoI邊框修正的訓練,可以公式描述如下:


   上式中u>=1表示RoI邊框修正是對於非背景的RoI而言的,實驗中,上式的λ取1。

   在訓練分類器和RoI邊框修正時,步驟如下所示:

   1) 首先通過RPN生成約20000個anchor(40×60×9)。

   2) 對20000個anchor進行第一次邊框修正,得到修訂邊框後的proposal。

   3) 去掉超過圖像邊界的proposal。

   4) 忽略掉長或者寬太小的proposal。

   5) 將所有proposal按照前景分數從高到低排序,選取前6000個proposal。

   6) 使用閾值爲0.7的NMS算法排除掉重疊的proposal。

   7) 再將proposal按照前景分數從高到低排序,選取前2000個proposal進行Fast R-CNN部分的訓練。

   總的來說,Faster R-CNN的loss分兩大塊,第一大塊是訓練RPN的loss(包含一個SoftmaxLoss和SmoothL1Loss),第二大塊是訓練Fast R-CNN中分類器的loss(包含一個SoftmaxLoss和SmoothL1Loss),Faster R-CNN的總的loss函數描述如下:


   然後,對於Faster R-CNN的訓練方式有三種,可以被描述如下:

   1) RPN和Fast R-CNN交替訓練,這種方式也是作者採用的方式。

   2) 近似聯合RPN和Fast R-CNN的訓練,在訓練時忽略掉了RoI邊框修正的誤差,也就是說只對anchor做了邊框修訂,這也是爲什麼叫"近似聯合"的原因。

   3) 聯合RPN和Fast R-CNN的訓練。

   對於作者採用的交替訓練的方式,步驟如下:

   1) 使用在ImageNet上預訓練的模型初始化共享卷積層並訓練RPN

   2) 使用上一步得到的RPN參數生成RoI proposal。再使用ImageNet上預訓練的模型初始化共享卷積層,訓練Fast R-CNN部分(分類器和RoI邊框修訂)。

   3) 將訓練後的共享卷積層參數固定,同時將Fast R-CNN的參數固定,訓練RPN。(從這一步開始,共享卷積層的參數真正被兩大塊網絡共享)

   4) 同樣將共享卷積層參數固定,並將RPN的參數固定,訓練Fast R-CNN部分。

   Faster R-CNN的測試流程和訓練流程挺相似,描述如下:

   1) 首先通過RPN生成約20000個anchor(40×60×9)。

   2) 對20000個anchor進行第一次邊框修正,得到修訂邊框後的proposal。

   3) 對超過圖像邊界的proposal的邊進行clip,使得該proposal不超過圖像範圍。

   4) 忽略掉長或者寬太小的proposal。

   5) 將所有proposal按照前景分數從高到低排序,選取前6000個proposal。

   6) 使用閾值爲0.7的NMS算法排除掉重疊的proposal。

   6) 再將proposal按照前景分數從高到低排序,選取前300個proposal進行分類和第二次邊框修正。

   到這裏,Faster R-CNN就介紹完畢了。接下來到了Mask R-CNN,我們來看看RoI Pooling出了什麼問題:

   問題1:從輸入圖上的RoI到特徵圖上的RoI feature,RoI Pooling是直接通過四捨五入取整得到的結果。

   這一點可以在代碼中印證:


   可以看到直接用round取的值,這樣會帶來什麼壞處呢?就是RoI Pooling過後的得到的輸出可能和原圖像上的RoI對不上,如下圖所示:


   右圖中藍色部分表示包含了轎車主體的的信息的方格,RoI Pooling Layer的四捨五入取整操作導致其進行了偏移。

   問題2:再將每個RoI對應的特徵轉化爲固定大小的維度時,又採用了取整操作。在這裏筆者舉例講解一下RoI Pooling的操作:


   在從RoI得到對應的特徵圖時,進行了問題1描述的取整,在得到特徵圖後,如何得到一個6×6的全連接層的輸入呢?RoI Pooling這樣做:將RoI對應的特徵圖分成6×6塊,然後直接從每塊中找到最大值。在上圖中的例子中,比如原圖上的的RoI大小是280×480,得到對應的特徵圖是18×30。將特徵圖分成6塊,每塊大小是3×5,然後在每一塊中分別選擇最大值放入6×6的對應區域中。在將特徵圖分塊的時候,又用到了取整,這點同樣可以在代碼中得到佐證:


   這種取整操作(在Mask R-CNN中被稱爲quantization)對RoI分類影響不大,可是對逐像素的預測目標是有害的,因爲對每個RoI取得的特徵並沒有與RoI對齊。因此,Mask R-CNN對RoI Pooling做了改進並提出了RoI Align。

   RoI Align的主要創新點是,針對問題1,不再進行取整操作。針對問題2,使用雙線性插值來更精確地找到每個塊對應的特徵。總的來說,RoI Align的作用主要就是剔除了RoI Pooling的取整操作,並且使得爲每個RoI取得的特徵能夠更好地對齊原圖上的RoI區域。

   下圖闡述了Mask R-CNN的Mask branch:


   在Mask R-CNN中的RoI Align之後有一個"head"部分,主要作用是將RoI Align的輸出維度擴大,這樣在預測Mask時會更加精確。在Mask Branch的訓練環節,作者沒有采用FCN式的SoftmaxLoss,反而是輸出了K個Mask預測圖(爲每一個類都輸出一張),並採用average binary cross-entropy loss訓練,當然在訓練Mask branch的時候,輸出的K個特徵圖中,也只是對應ground truth類別的那一個特徵圖對Mask loss有貢獻。

   Mask R-CNN的訓練損失函數可以描述爲:


   在上式中,Lbox和Lmask都是對positive RoI纔會起作用的。

   在Mask R-CNN中,相較於Faster R-CNN還有些略微的調整,比如positive RoI被定義成了與Ground truth的IoU大於0.5的(Faster R-CNN中是0.7)。太過於細節的東西本篇博文不再贅述,詳情參見Mask R-CNN中的Implementation Details。

   到這裏再將Mask R-CNN和FCIS做個比較,首先兩者的相同點是均繼承了Faster R-CNN的RPN部分不同點是對於FCIS,預測mask和分類是共享的參數。而Mask R-CNN則是各玩各的,兩個任務各自有各自的可訓練參數。對於這一點,Mask R-CNN論文裏還專門作了比較,顯示對於預測mask和分類如果使用共享的特徵圖對於某些重疊目標可能會出現問題。


   Mask R-CNN的實驗取得了很好的效果,達到甚至超過了state-of-the-art的水平。不過訓練代價也是相當大的,需要8塊GPU聯合訓練。


   Mask R-CNN的實驗非常詳細,還做了很多對比實驗,比如說改換網絡深度,在訓練mask branch時的誤差種類,將RoI Align同RoI Pooling和RoI Warping進行比較,改變預測mask的方式(FCN和全連接層)等,詳情請參見Mask R-CNN的實驗部分。





   到這裏Mask R-CNN介紹就接近尾聲了,筆者還想說一些自己的思考與感想:

   1) 可繼承工作的充分體現。大家看到Mask R-CNN的結構相當複雜,實際上是繼承了大量之前的工作。首先bounding box regression在2014年的R-CNN中就出現過。Mask R-CNN的主要創新點RoI Align改良於RoI Pooling,而RoI Pooling是在2015年的Fast R-CNN中提出的。對於RPN的應用,更是直接繼承了2016年的Faster R-CNN。值得一提的是,上述的每一篇文章,都是顛覆目標檢測領域計算架構的傑出作品。

   2)集成的工作。還是那句老話,到了2017-2018年,隨着深度學習的高速發展,單任務模型已經逐漸被拋棄。取而代之的是更集成,更綜合,更強大的多任務模型。Mask R-CNN就是其中的代表。

   3)引領潮流。再次向何凱明和Ross Girshick致敬,他們的實力引領了目標檢測領域的發展,因此無論他們在哪,無論是在微軟還是FaceBook,他們的idea和作品都被非常多的人應用或者繼承。

   歡迎閱讀筆者後續博客,各位讀者朋友的支持與鼓勵是我最大的動力!


written by jiong

鴻爪踏雪泥,還是來得及。

版權聲明:本文爲博主原創文章,轉載時請附加博文鏈接。 https://blog.csdn.net/jiongnima/article/details/79094159
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章