一、Mask-RCNN流程
Mask R-CNN是一個實例分割(Instance segmentation)算法,通過增加不同的分支,可以完成目標分類、目標檢測、語義分割、實例分割、人體姿勢識別等多種任務,靈活而強大。
Mask R-CNN進行目標檢測與實例分割
Mask R-CNN進行人體姿態識別
其抽象架構如下:
首先,輸入一幅你想處理的圖片,然后進行對應的預處理操作,或者預處理后的圖片;
然后,將其輸入到一個預訓練好的神經網絡中(ResNeXt等)獲得對應的feature map;
接着,對這個feature map中的每一點設定預定個的ROI,從而獲得多個候選ROI;
接着,將這些候選的ROI送入RPN網絡進行二值分類(前景或背景)和BB回歸,過濾掉一部分候選的ROI(截止到目前,Mask和Faster完全相同,其實R-FCN之類的在這之前也沒有什么不同);
接着,對這些剩下的ROI進行ROIAlign操作(即先將原圖和feature map的pixel對應起來,然后將feature map和固定的feature對應起來)(ROIAlign為本文創新點1,比ROIPooling有長足進步);
最后,對這些ROI進行分類(N類別分類)、BB回歸和MASK生成(在每一個ROI里面進行FCN操作)(引入FCN生成Mask為本文創新點2,使得本文結構可以進行分割型任務)。
【注】有關MASK部分,還有一處容易忽視的創新點3:損失函數的計算,作者放棄了更廣泛的softmax,轉而使用了sigmoid,避免了同類競爭,更多的經歷放在優化mask像素上,這一點我們下一小節會提到。
二、Mask-RCNN結構
ROIPooling的問題
RoiPool過程
假定我們輸入的是一張800x800的圖像,在圖像中有兩個目標(貓和狗),狗的BB大小為665x665,經過VGG16網絡后,獲得的feature map 會比原圖縮小一定的比例,這和Pooling層的個數和大小有關:
在該VGG16中,我們使用了5個池化操作,每個池化操作都是2Pooling,因此我們最終獲得feature map的大小為800/32 x 800/32 = 25x25(是整數),但是將狗的BB對應到feature map上面,我們得到的結果是665/32 x 665/32 = 20.78 x 20.78,結果是浮點數,含有小數,取整變為20 x 20,在這里引入了第一次的量化誤差;
然后我們需要將20 x 20的ROI映射成7 x 7的ROI feature,其結果是 20 /7 x 20/7 = 2.86 x 2.86,同樣是浮點數,含有小數點,同樣的取整,在這里引入了第二次量化誤差。
這里引入的誤差會導致圖像中的像素和特征中的像素的偏差,即將feature空間的ROI對應到原圖上面會出現很大的偏差。原因如下:比如用我們第二次引入的誤差來分析,本來是2,86,我們將其量化為2,這期間引入了0.86的feature空間誤差,我們的feature空間和圖像空間是有比例關系的,在這里是1:32,那么對應到原圖上面的差距就是0.86 x 32 = 27.52(這僅僅考慮了第二次的量化誤差)。
ROIAlign
ROIAlign過程
為了得到為了得到固定大小(7X7)的feature map,ROIAlign技術並沒有使用量化操作,取而代之的使用了雙線性插值,它充分的利用了原圖中虛擬點(比如20.56這個浮點數,像素位置都是整數值,沒有浮點值)四周的四個真實存在的像素值來共同決定目標圖中的一個像素值,即可以將20.56這個虛擬的位置點對應的像素值估計出來。
藍色的虛線框表示卷積后獲得的feature map,黑色實線框表示ROI feature,最后需要輸出的大小是2x2,那么我們就利用雙線性插值來估計這些藍點(虛擬坐標點,又稱雙線性插值的網格點)處所對應的像素值,最后得到相應的輸出。
然后在每一個橘紅色的區域里面進行max pooling或者average pooling操作,獲得最終2x2的輸出結果。我們的整個過程中沒有用到量化操作,沒有引入誤差,即原圖中的像素和feature map中的像素是完全對齊的,沒有偏差,這不僅會提高檢測的精度,同時也會有利於實例分割。
ROI處理架構
為了證明我們方法的通用性,我們構造了多種不同結構的Mask R-CNN。詳細的說,我們使用不同的:
(i)用於整個圖像上的特征提取的卷積主干架構;
(ii)用於邊框識別(分類和回歸)和掩模預測的上層網絡,分別應用於每個RoI。
我們使用術語“網絡深層特征”來命名下層架構。我們評估了深度為50或101層的ResNet [14]和ResNeXt [34] 網絡。使用ResNet [14]的Faster R-CNN從第四級的最終卷積層提取特征,我們稱之為C4。例如,使用ResNet-50的主干架構由ResNet-50-C4表示。這是[14,7,16,30]中常用的選擇。
我們也探索了由Li[21]等人最近提出的另一種更有效主干架構,稱為特征金字塔網絡(FPN)。FPN使用具有橫向連接(lateral connections )的自頂向下架構,從單一規模的輸入構建網絡功能金字塔。使用FPN的Faster R-CNN根據其尺度提取不同級別的金字塔的RoI特征,不過其他部分和平常的ResNet類似。使用ResNet-FPN主干架構的Mask R-CNN進行特征提取,可以在精度和速度方面獲得極大的提升。有關FPN的更多細節,讀者可以參考[21]。
對於上層網絡,我們基本遵循了以前論文中提出的架構,我們添加了一個全卷積的掩模預測分支。具體來說,我們擴展了ResNet [14]和FPN[21]中提出的Faster R-CNN的上層網絡。詳情見下圖(圖3)所示:(上層架構:我們擴展了兩種現有的Faster R-CNN上層架構[14,21],並分別添加了一個掩模分支。左/右面板分別顯示了ResNet C4和FPN主干的上層架構。圖中數字表示通道數和分辨率,箭頭表示卷積、反卷積和全連接層(可以通過上下文推斷,卷積減小維度,反卷積增加維度。)所有的卷積都是3×3的,除了輸出層是1×1。反卷積是2×2,其步進為2,我們在隱藏層中使用ReLU[24]。在左圖中,“res5”表示ResNet的第五級,簡單起見,我們修改了第一個卷積操作,使用7×7,步長為1的RoI代替14×14,步長為2的RoI[14]。右圖中的“×4 ”表示堆疊的4個連續的卷積。)ResNet-C4主干的上層網絡包括ResNet的第5階段(即9層的’res5’[14]),這是計算密集型的。但對於FPN,其主干已經包含了res5,因此可以使上層網絡包含更少的卷積核而變的更加高效。
重點在於:作者把各種網絡作為backbone進行對比,發現使用ResNet-FPN作為特征提取的backbone具有更高的精度和更快的運行速度,所以實際工作時大都采用右圖的完全並行的mask/分類回歸
mask分支針對每個RoI產生一個K*m*m的輸出,即K個分辨率為m*m的二值的掩膜,K為分類物體的種類數目。依據預測類別分支預測的輸出,我們僅將第i個類別的輸出登記,用於計算
Mask R-CNN采用了和Faster R-CNN相同的兩步走策略,即先使用RPN提取候選區域,關於RPN的詳細介紹,可以參考Faster R-CNN一文。不同於Faster R-CNN中使用分類和回歸的多任務回歸,Mask R-CNN在其基礎上並行添加了一個用於語義分割的Mask損失函數,所以Mask R-CNN的損失函數可以表示為下式。
上式中,
表示bounding box的分類損失值,
表示bounding box的回歸損失值,
表示mask部分的損失值。
對於預測的二值掩膜輸出,我們對每個像素點應用sigmoid函數,整體損失定義為平均二值交叉損失熵。引入預測K個輸出的機制,允許每個類都生成獨立的掩膜,避免類間競爭。這樣做解耦了掩膜和種類預測。不像FCN的做法,在每個像素點上應用softmax函數,整體采用的多任務交叉熵,這樣會導致類間競爭,最終導致分割效果差。
訓練參數
面試考點
這一部分是臨時看到面經,感覺還是有不少RCNN系列發展的要點,記錄下來,以后再看RCNN時可以帶着問題回憶。
RPN 作用和原理
RPN提出於Faster,所以參考之前的文章:『計算機視覺』經典RCNN_其一:從RCNN到Faster-RCNN
ROI align 和 ROI pooling 的不同
各部分損失函數選用的什么函數
參考后續文章:『計算機視覺』Mask-RCNN_訓練網絡其二:train網絡結構&損失函數
三、參考資料
TensorFlow實戰:Chapter-8上(Mask R-CNN介紹與實現)
開源代碼:
Tensorflow版本代碼鏈接;
Keras and TensorFlow版本代碼鏈接;
MxNet版本代碼鏈接