【實例分割系列:一】Mask RCNN 論文筆記解析

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 比較 。

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
    L=Lcls+Lbox+LmaskL=Lcls+Lbox+Lmask

  • Mask Representation
    沒有采用全連接層並且使用了RoIAlign,可以實現輸出與輸入的像素一一對應

backbone

resnet-50,resnet-101,resnext-50,resnext-101;FPN

Mask

Faster RCNN使用resnet50時,從CONV4導出特徵供RPN使用,這種叫做ResNet-50-C4

對於新增加的mask支路,其對於每個ROI的輸出維度是KmmK*m*m,其中mmm*m表示mask的大小,K表示K個類別,因此這裏每一個ROI一共生成KK個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, 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章