先看效果
僅僅用了50張訓練照片,訓練了1000步之后進行測試,發現效果好得令人稱奇。
之前用YOLO訓練很難收斂。(雖然two-stage方法精度更高,這種比較雖然有些不合理)
Mask RCNN沿用了Faster RCNN的思想,特征提取采用ResNet-FPN的架構,另外多加了一個Mask預測分支。
Mask RCNN沿用了Faster RCNN的思想,特征提取采用ResNet-FPN的架構,另外多加了一個Mask預測分支。可見Mask RCNN綜合了很多此前優秀的研究成果。為了更好地講解Mask RCNN,我會先回顧一下幾個部分:
1.Faster RCNN
2.ResNet-FPN
3.ResNet-FPN+Fast RCNN
回顧完之后講ResNet-FPN+Fast RCNN+Mask,實際上就是Mask RCNN。
一、Faster RCNN
Faster RCNN是兩階段的目標檢測算法,包括階段一的Region proposal以及階段二的bounding box回歸和分類。用一張圖來直觀展示Faster RCNN的整個流程:

Faster RCNN使用CNN提取圖像特征,然后使用region proposal network(RPN)去提取出ROI,然后使用ROI pooling將這些ROI全部變成固定尺寸,再喂給全連接層進行Bounding box回歸和分類預測。
ResNet-FPN
多尺度檢測在目標檢測中變得越來越重要,對小目標的檢測尤其如此。現在主流的目標檢測方法很多都用到了多尺度的方法,包括最新的yolo v3。Feature Pyramid Network (FPN)則是一種精心設計的多尺度檢測方法,下面就開始簡要介紹FPN。

FPN實際上是一種通用架構,可以結合各種骨架網絡使用,比如VGG,ResNet等。Mask RCNN文章中使用了ResNNet-FPN網絡結構。如下圖:

ResNet-FPN包括3個部分,自下而上連接,自上而下連接和橫向連接。下面分別介紹。
3×3的卷積是為了消除混疊效應。
自上而下
從下到上路徑。可以明顯看出,其實就是簡單的特征提取過程,和傳統的沒有區別。具體就是將ResNet作為骨架網絡,根據feature map的大小分為5個stage。他們相對於原始圖片的stride是{4,8,16,32}。需要注意的是,考慮到內存原因,stage1的conv1並沒有使用。
三、ResNet-FPN+Fast RCNN

將ResNet-FPN和Fast RCNN進行結合,實際上就是Faster RCNN的了,但與最初的Faster RCNN不同的是,FPN產生了特征金字塔
,而並非只是一個feature map。金字塔經過RPN之后會產生很多region proposal。這些region proposal是分別由P2, P3,P4,P5,P6經過RPN產生的,但用於輸入到Fast RCNN中的是 P2, P3,P4,P5(沒有P6)也就是說要在 P2, P3,P4,P5中根據region proposal切出ROI進行后續的分類和回歸預測。問題來了,我們要選擇哪個feature map來切出這些ROI區域呢?實際上,我們會選擇最合適的尺度的feature map來切ROI。具體來說,我們通過一個公式來決定寬w和高h的ROI到底要從哪個Pk來切:
$K = \lfloor K0 + log_2( \sqrt{wh} /224) \rfloor$
這里224表示用於預訓練的ImageNet圖片的大小。 $k_0$表示面積為$w × h = 224 × 224$的ROI所應該在的層級。假設ROI的scale小於224(比如說是112 * 112), $k = k_0 - 1 = 4-1=3$就意味着要從更高分辨率的 P3 中產生。另外,k值會做取整處理,防止結果不是整數。
這種做法很合理,大尺度的ROI要從低分辨率的feature map上切,有利於檢測大目標,小尺度的ROI要從高分辨率的feature map上切,有利於檢測小目標。
四、ResNet-FPN+Fast RCNN+mask
我們再進一步,將ResNet-FPN+Fast RCNN+mask,則得到了最終的Mask RCNN,如下圖:

Mask RCNN的構建很簡單,只是在ROI pooling(實際上用到的是ROIAlign,后面會講到)之后添加卷積層,進行mask預測的任務。
下面總結一下Mask RCNN的網絡:
1.骨干網絡ResNet-FPN,用於特征提取,另外,ResNet還可以是:ResNet-50,ResNet-101,ResNeXt-50,ResNeXt-101;
2.頭部網絡,包括邊界框識別(分類和回歸)+mask預測。頭部結構見下圖:

五、ROI Align
實際上,Mask RCNN中還有一個很重要的改進,就是ROIAlign。Faster R-CNN存在的問題是:特征圖與原始圖像是不對准的(mis-alignment),所以會影響檢測精度。而Mask R-CNN提出了RoIAlign的方法來取代ROI pooling,RoIAlign可以保留大致的空間位置。
為了講清楚ROI Align,這里先插入兩個知識,雙線性插值和ROI pooling。
1.雙線性插值
在講雙線性插值之前,還得看最簡單的線性插值。
已知數據$(x_0, y_0)$與$(x_1,y_1)$,要計算$[x_0, x_1]$區間內某一位置$x$在直線上的$y$值,如下圖所示。

計算方法很簡單,通過斜率相等就可以構建y和x之間的關系,如下:

雙線性插值本質上就是在兩個方向上做線性插值。

如圖,假設我們想得到P點的插值,我們可以先在x方向上,對Q11和Q21之間做線性插值得到R1,R2。然后在y方向上對 R1和R2進行線性插值就可以得到最終的P。其實知道這個就已經理解了雙線性插值的意思了,如果用公式表達則如下(注意前面的系數看成權重就很好理解了)。
首先在 x 方向進行線性插值,得到:

然后在 y 方向進行線性插值,得到

這樣就得到所要的結果 

2.ROIpooling
ROI pooling就不多解釋了,直接通過一個例子來形象理解。假設現在我們有一個8x8大小的feature map,我們要在這個feature map上得到ROI,並且進行ROI pooling到2x2大小的輸出。

假設ROI的bounding box為:$[x_1, y_1, x_2, y_2] = [0,3,7,8]$,如圖:

將它划分為2x2的網格,因為ROI的長寬除以2是不能整除的,所以會出現每個格子大小不一樣的情況。

進行max pooling的最終2x2的輸出為:

3. ROI Align
在Faster RCNN中,有兩次整數化的過程:
region proposal的xywh通常是小數(注意這里四個值是小數),但是為了方便操作會把它整數化。
兩次整數化的過程如下圖所示:

事實上,經過上述兩次整數化,此時的候選框已經和最開始回歸出來的位置有一定的偏差,這個偏差會影響檢測或者分割的准確度。在論文里,作者把它總結為“不匹配題”(misalignment)。
為了解決這個問題,ROI Align方法取消整數化操作,保留了小數,使用以上介紹的雙線性插值的方法獲得坐標為浮點數的像素點上的圖像數值。但在實際操作中,ROI Align並不是簡單地補充出候選區域邊界上的坐標點,然后進行池化,而是重新進行設計。
下面通過一個例子來講解ROI Align操作。如下圖所示,虛線部分表示feature map,實線表示ROI,這里將ROI切分成2x2的單元格。如果采樣點數是4,那我們首先將每個單元格子均分成四個小方格(如紅色線所示),每個小方格中心就是采樣點。這些采樣點的坐標通常是浮點數,所以需要對采樣點像素進行雙線性插值(如四個箭頭所示),就可以得到該像素點的值了。然后對每個單元格內的四個采樣點進行maxpooling,就可以得到最終的ROIAlign的結果。

需要說明的是,在相關實驗中,作者發現將采樣點設為4會獲得最佳性能,甚至直接設為1在性能上也相差無幾。事實上,ROI Align 在遍歷取樣點的數量上沒有ROIPooling那么多,但卻可以獲得更好的性能,這主要歸功於解決了misalignment的問題。
六、損失
Mask RCNN定義多任務損失:


需要具體說明的是 $L_{mask}$,假設一共有K個類別,則mask分割分支的輸出維度是$Kmm$,對於$m*m$中的每個點,都會輸出K個二值Mask(每個類別使用sigmoid輸出)。需要注意的是,計算loss的時候,並不是每個類別的sigmoid輸出都計算二值交叉熵損失,而是該像素屬於哪個類,哪個類的sigmoid輸出才要計算損失(如圖紅色方形所示)。需要注意的是,計算loss的時候,並不是每個類別的sigmoid輸出都計算二值交叉熵損失,而是該像素屬於哪個類,哪個類的sigmoid輸出才要計算損失(如圖紅色方形所示)。並且在測試的時候,我們是通過分類分支預測的類別來選擇相應的mask預測。這樣,mask預測和分類預測就徹底解耦了。這與FCN方法是不同,FCN是對每個像素進行多類別softmax分類,然后計算交叉熵損失,很明顯,這種做法是會造成類間競爭的,而每個類別使用sigmoid輸出並計算二值損失,可以避免類間競爭。實驗表明,通過這種方法,可以較好地提升性能。
