2017 CVPR
Mask R-CNN
Mask RCNN, PyTorch
Instance Segmentation
Introduction
Mask RCNN = Faster RCNN + ResNet-FPN + Mask
Motivation
-
強化的基礎網絡
通過 ResNeXt-101+FPN 用作特徵提取網絡,達到 state-of-the-art 的效果。 -
ROI Pooling → ROI Align
解決特徵圖與原始圖像上的RoI不對準問題- ROI Pooling 是一種針對每一個RoI的提取一個小尺度特徵圖(e.g. 7x7)的標準操作
- ROI Align 使用雙線性插值(bilinear interpolation)在每個RoI塊中4個採樣位置上計算輸入特徵的精確值,並將結果聚合(使用max或者average)。
-
分割、分類、定位同時進行
檢測和分割是並行出結果的,而不像以前是分割完了之後再做分類- FCNs是對每個像素進行多類別分類,它同時進行分類和分割
- Mask RCNN 對每個類別獨立地預測一個二值掩模,沒有引入類間競爭,每個二值掩模的類別依靠網絡RoI分類分支給出的分類預測結果
-
Loss Function
- mask loss
由原來的 FCIS 的 基於單像素softmax的多項式交叉熵變爲了基於單像素sigmod二值交叉熵。
softmax會產生 FCIS 的 ROI inside map 與 ROI outside map的競爭。但文章作者確實寫到了類間的競爭, 二值交叉熵會使得每一類的 mask 不相互競爭,而不是和其他類別的 mask 比較 。
- mask loss
Network
faster rcnn
Mask rcnn
“head” 作用是將RoI Align的輸出維度擴大,這樣在預測Mask時會更加精確。
在Mask Branch的訓練環節,作者沒有采用FCN式的SoftmaxLoss,反而是輸出了K個Mask預測圖(爲每一個類都輸出一張),並採用average binary cross-entropy loss訓練,
-
two-state
extract feature 、RPN
對RPN找到的每個RoI進行 分類、定位、找到binary mask(對於 Faster RCNN 的每個 Proposal Box 使用 FCN 進行語義分割)
注意:這裏和其他分割網絡(先 mask 然後分類 )是不同的 -
Loss
-
Mask Representation
沒有采用全連接層並且使用了RoIAlign,可以實現輸出與輸入的像素一一對應
backbone
resnet-50,resnet-101,resnext-50,resnext-101;FPN
Mask
Faster RCNN使用resnet50時,從CONV4導出特徵供RPN使用,這種叫做ResNet-50-C4
對於新增加的mask支路,其對於每個ROI的輸出維度是,其中表示mask的大小,K表示K個類別,因此這裏每一個ROI一共生成個binary mask,這就是文章中提到的class-specific mask概念。
在得到預測mask後,對mask的每個像素點值求sigmoid函數值(即所謂的per-pixel sigmoid),得到的結果作爲Lmask(交叉熵損失函數)的輸入之一。
- sigmoid:A logistic function or logistic curve is a common “S” shape (sigmoid curve).
二分類損失 - softmax:softmax is a generalization of logistic function that “squashes”(maps) a K-dimensional vector z of arbitrary real values to a K-dimensional vector σ(z) of real values in the range (0, 1) that add up to 1.
多分類損失
送進mask分支的ROI其實是隻有正樣本的ROI才被送進去。只有正樣本ROI纔會用於計算Lmask,正樣本的定義和目標檢測一樣,都是IOU大於0.5定義爲正樣本。
問題
怎麼做到區別 實例而不是類別??
對於每一個ROI,如果檢測得到ROI屬於哪一個分類,就只使用哪一個分支的相對熵誤差作爲誤差值進行計算。
舉例說明:分類有3類(貓,狗,人),檢測得到當前ROI屬於“人”這一類,那麼所使用的Lmask爲“人”這一分支的mask。
這樣的定義使得我們的網絡不需要去區分每一個像素屬於哪一類,只需要去區別在這個類當中的不同小類。
我們定義的Lmask允許網絡爲每一類生成一個mask,而不用和其它類進行競爭;我們依賴於分類分支所預測的類別標籤來選擇輸出的mask。
- FCN
-
Mask-RCNN
Mask-RCNN不是一次性對所有的通道channel上的像素求多分類損失,而是隻在每一個ROI所對應的類別上對每一個像素求一個sigmoid二分類
第一個ROI我們只在對應的K=3的類別中,即在channel爲3的通道上的那個mask上面對每一個像素求二分類
第二個ROI我們只在對應的K=8的類別中,即在channel爲8的通道上的那個mask上面對每一個像素求二分類
- 關鍵問題:怎麼知道每一個ROI到底是那個類別呢?
- 藉助分類網絡
分類網絡告訴分割網絡這個對應的 ROI 是屬於哪一個類別 K 。 - 好處:
定義的 Lmask 允許網絡爲每一類生成一個mask,只用在自己的類別(即channel)上計算損失,而不用和其它類進行競爭。
對每個固定的類別的那張特徵圖的每一個像素計算損失之後,然後再求所有像素的平均,這也是文章中將Lmask稱爲average binary cross-entropy loss的原因。
- 藉助分類網絡
ROI Align 原理?
- 爲了得到爲了得到固定大小(7X7)的feature map,ROIAlign技術並沒有使用量化操作,即我們不想引入量化誤差,比如665 / 32 = 20.78,我們就用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 中的像素是完全對齊的,沒有偏差,這不僅會提高檢測的精度,同時也會有利於實例分割。
Pytorch
改進
基於 Mask RCNN 的改進:
Reference
https://blog.csdn.net/jiongnima/article/details/79094159
https://zhuanlan.zhihu.com/p/37998710
https://blog.csdn.net/linolzhang/article/details/71774168
https://blog.csdn.net/u014380165/article/details/81878644
https://blog.csdn.net/xiamentingtao/article/details/78598511
https://blog.csdn.net/wangdongwei0/article/details/83110305
https://blog.csdn.net/qq_27825451/article/details/89677068