Mask R-CNN是一個實例分割(Instance segmentation)算法,經過增長不一樣的分支,能夠完成目標分類、目標檢測、語義分割、實例分割、人體姿式識別等多種任務,靈活而強大。html
Mask R-CNN進行目標檢測與實例分割git
Mask R-CNN進行人體姿態識別github
其抽象架構以下:面試
首先,輸入一幅你想處理的圖片,而後進行對應的預處理操做,或者預處理後的圖片;算法
而後,將其輸入到一個預訓練好的神經網絡中(ResNeXt等)得到對應的feature map;網絡
接着,對這個feature map中的每一點設定預約個的ROI,從而得到多個候選ROI;架構
接着,將這些候選的ROI送入RPN網絡進行二值分類(前景或背景)和BB迴歸,過濾掉一部分候選的ROI(截止到目前,Mask和Faster徹底相同,其實R-FCN之類的在這以前也沒有什麼不一樣);app
接着,對這些剩下的ROI進行ROIAlign操做(即先將原圖和feature map的pixel對應起來,而後將feature map和固定的feature對應起來)(ROIAlign爲本文創新點1,比ROIPooling有長足進步);函數
最後,對這些ROI進行分類(N類別分類)、BB迴歸和MASK生成(在每個ROI裏面進行FCN操做)(引入FCN生成Mask爲本文創新點2,使得本文結構能夠進行分割型任務)。post
【注】有關MASK部分,還有一處容易忽視的創新點3:損失函數的計算,做者放棄了更普遍的softmax,轉而使用了sigmoid,避免了同類競爭,更多的經歷放在優化mask像素上,這一點咱們下一小節會提到。
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過程
爲了獲得爲了獲得固定大小(7X7)的feature map,ROIAlign技術並無使用量化操做,取而代之的使用了雙線性插值,它充分的利用了原圖中虛擬點(好比20.56這個浮點數,像素位置都是整數值,沒有浮點值)四周的四個真實存在的像素值來共同決定目標圖中的一個像素值,便可以將20.56這個虛擬的位置點對應的像素值估計出來。
藍色的虛線框表示卷積後得到的feature map,黑色實線框表示ROI feature,最後須要輸出的大小是2x2,那麼咱們就利用雙線性插值來估計這些藍點(虛擬座標點,又稱雙線性插值的網格點)處所對應的像素值,最後獲得相應的輸出。
而後在每個橘紅色的區域裏面進行max pooling或者average pooling操做,得到最終2x2的輸出結果。咱們的整個過程當中沒有用到量化操做,沒有引入偏差,即原圖中的像素和feature map中的像素是徹底對齊的,沒有誤差,這不只會提升檢測的精度,同時也會有利於實例分割。
爲了證實咱們方法的通用性,咱們構造了多種不一樣結構的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版本代碼連接