論文鏈接:論文鏈接
論文代碼:Facebook代碼鏈接;Tensorflow版本代碼鏈接; Keras and TensorFlow版本代碼鏈接;MxNet版本代碼鏈接
一、Mask R-CNN是什么,可以做哪些任務?
圖1 Mask R-CNN整體架構
Mask R-CNN是一個實例分割(Instance segmentation)算法,可以用來做“目標檢測”、“目標實例分割”、“目標關鍵點檢測”。
1. 實例分割(Instance segmentation)和語義分割(Semantic segmentation)的區(qū)別與聯(lián)系
聯(lián)系:語義分割和實例分割都是目標分割中的兩個小的領域,都是用來對輸入的圖片做分割處理;
區(qū)別:
圖2 實例分割與語義分割區(qū)別
1. 通常意義上的目標分割指的是語義分割,語義分割已經(jīng)有很長的發(fā)展歷史,已經(jīng)取得了很好地進展,目前有很多的學者在做這方面的研究;然而實例分割是一個從目標分割領域獨立出來的一個小領域,是最近幾年才發(fā)展起來的,與前者相比,后者更加復雜,當前研究的學者也比較少,是一個有研究空間的熱門領域,如圖1所示,這是一個正在探索中的領域;
圖3 實例分割與語義分割區(qū)別
2. 觀察圖3中的c和d圖,c圖是對a圖進行語義分割的結果,d圖是對a圖進行實例分割的結果。兩者最大的區(qū)別就是圖中的"cube對象",在語義分割中給了它們相同的顏色,而在實例分割中卻給了不同的顏色。即實例分割需要在語義分割的基礎上對同類物體進行更精細的分割。
注:很多博客中都沒有完全理解清楚這個問題,很多人將這個算法看做語義分割,其實它是一個實例分割算法。
2. Mask R-CNN可以完成的任務
圖4 Mask R-CNN進行目標檢測與實例分割
圖5 Mask R-CNN進行人體姿態(tài)識別
總之,Mask R-CNN是一個非常靈活的框架,可以增加不同的分支完成不同的任務,可以完成目標分類、目標檢測、語義分割、實例分割、人體姿勢識別等多種任務,真不愧是一個好算法!
3. Mask R-CNN預期達到的目標
4. 如何實現(xiàn)這些目標
高速和高準確率:為了實現(xiàn)這個目的,作者選用了經(jīng)典的目標檢測算法Faster-rcnn和經(jīng)典的語義分割算法FCN。Faster-rcnn可以既快又準的完成目標檢測的功能;FCN可以精準的完成語義分割的功能,這兩個算法都是對應領域中的經(jīng)典之作。Mask R-CNN比Faster-rcnn復雜,但是最終仍然可以達到5fps的速度,這和原始的Faster-rcnn的速度相當。由于發(fā)現(xiàn)了ROI Pooling中所存在的像素偏差問題,提出了對應的ROIAlign策略,加上FCN精準的像素MASK,使得其可以獲得高準確率。
簡單直觀:整個Mask R-CNN算法的思路很簡單,就是在原始Faster-rcnn算法的基礎上面增加了FCN來產(chǎn)生對應的MASK分支。即Faster-rcnn + FCN,更細致的是 RPN + ROIAlign + Fast-rcnn + FCN。
易于使用:整個Mask R-CNN算法非常的靈活,可以用來完成多種任務,包括目標分類、目標檢測、語義分割、實例分割、人體姿態(tài)識別等多個任務,這將其易于使用的特點展現(xiàn)的淋漓盡致。我很少見到有哪個算法有這么好的擴展性和易用性,值得我們學習和借鑒。除此之外,我們可以更換不同的backbone architecture和Head Architecture來獲得不同性能的結果。
二、Mask R-CNN框架解析
圖6 Mask R-CNN算法框架
1. Mask R-CNN算法步驟
2. Mask R-CNN架構分解
在這里,我將Mask R-CNN分解為如下的3個模塊,F(xiàn)aster-rcnn、ROIAlign和FCN。然后分別對這3個模塊進行講解,這也是該算法的核心。
3. Faster-rcnn(該算法請參考該鏈接,我進行了詳細的分析)
4. FCN
圖7 FCN網(wǎng)絡架構
FCN算法是一個經(jīng)典的語義分割算法,可以對圖片中的目標進行準確的分割。其總體架構如上圖所示,它是一個端到端的網(wǎng)絡,主要的??彀ň矸e和去卷積,即先對圖像進行卷積和池化,使其feature map的大小不斷減?。蝗缓筮M行反卷積操作,即進行插值操作,不斷的增大其feature map,最后對每一個像素值進行分類。從而實現(xiàn)對輸入圖像的準確分割。具體的細節(jié)請參考該鏈接。
5. ROIPooling和ROIAlign的分析與比較
圖8 ROIPooling和ROIAlign的比較
如圖8所示,ROI Pooling和ROIAlign最大的區(qū)別是:前者使用了兩次量化操作,而后者并沒有采用量化操作,使用了線性插值算法,具體的解釋如下所示。
圖9 ROI Pooling技術
如圖9所示,為了得到固定大小(7X7)的feature map,我們需要做兩次量化操作:1)圖像坐標 — feature map坐標,2)feature map坐標 — ROI feature坐標。我們來說一下具體的細節(jié),如圖我們輸入的是一張800x800的圖像,在圖像中有兩個目標(貓和狗),狗的BB大小為665x665,經(jīng)過VGG16網(wǎng)絡后,我們可以獲得對應的feature map,如果我們對卷積層進行Padding操作,我們的圖片經(jīng)過卷積層后保持原來的大小,但是由于池化層的存在,我們最終獲得feature map 會比原圖縮小一定的比例,這和Pooling層的個數(shù)和大小有關。在該VGG16中,我們使用了5個池化操作,每個池化操作都是2Pooling,因此我們最終獲得feature map的大小為800/32 x 800/32 = 25x25(是整數(shù)),但是將狗的BB對應到feature map上面,我們得到的結果是665/32 x 665/32 = 20.78 x 20.78,結果是浮點數(shù),含有小數(shù),但是我們的像素值可沒有小數(shù),那么作者就對其進行了量化操作(即取整操作),即其結果變?yōu)?0 x 20,在這里引入了第一次的量化誤差;然而我們的feature map中有不同大小的ROI,但是我們后面的網(wǎng)絡卻要求我們有固定的輸入,因此,我們需要將不同大小的ROI轉化為固定的ROI feature,在這里使用的是7x7的ROI feature,那么我們需要將20 x 20的ROI映射成7 x 7的ROI feature,其結果是 20 /7 x 20/7 = 2.86 x 2.86,同樣是浮點數(shù),含有小數(shù)點,我們采取同樣的操作對其進行取整吧,在這里引入了第二次量化誤差。其實,這里引入的誤差會導致圖像中的像素和特征中的像素的偏差,即將feature空間的ROI對應到原圖上面會出現(xiàn)很大的偏差。原因如下:比如用我們第二次引入的誤差來分析,本來是2,86,我們將其量化為2,這期間引入了0.86的誤差,看起來是一個很小的誤差呀,但是你要記得這是在feature空間,我們的feature空間和圖像空間是有比例關系的,在這里是1:32,那么對應到原圖上面的差距就是0.86 x 32 = 27.52。這個差距不小吧,這還是僅僅考慮了第二次的量化誤差。這會大大影響整個檢測算法的性能,因此是一個嚴重的問題。好的,應該解釋清楚了吧,好累!
圖10 ROIAlign技術
如圖10所示,為了得到為了得到固定大?。?X7)的feature map,ROIAlign技術并沒有使用量化操作,即我們不想引入量化誤差,比如665 / 32 = 20.78,我們就用20.78,不用什么20來替代它,比如20.78 / 7 = 2.97,我們就用2.97,而不用2來代替它。這就是ROIAlign的初衷。那么我們?nèi)绾翁幚磉@些浮點數(shù)呢,我們的解決思路是使用“雙線性插值”算法。雙線性插值是一種比較好的圖像縮放算法,它充分的利用了原圖中虛擬點(比如20.56這個浮點數(shù),像素位置都是整數(shù)值,沒有浮點值)四周的四個真實存在的像素值來共同決定目標圖中的一個像素值,即可以將20.56這個虛擬的位置點對應的像素值估計出來。厲害哈。如圖11所示,藍色的虛線框表示卷積后獲得的feature map,黑色實線框表示ROI feature,最后需要輸出的大小是2x2,那么我們就利用雙線性插值來估計這些藍點(虛擬坐標點,又稱雙線性插值的網(wǎng)格點)處所對應的像素值,最后得到相應的輸出。這些藍點是2x2Cell中的隨機采樣的普通點,作者指出,這些采樣點的個數(shù)和位置不會對性能產(chǎn)生很大的影響,你也可以用其它的方法獲得。然后在每一個橘紅色的區(qū)域里面進行max pooling或者average pooling操作,獲得最終2x2的輸出結果。我們的整個過程中沒有用到量化操作,沒有引入誤差,即原圖中的像素和feature map中的像素是完全對齊的,沒有偏差,這不僅會提高檢測的精度,同時也會有利于實例分割。這么細心,做科研就應該關注細節(jié),細節(jié)決定成敗。
we propose an RoIAlign layer that removes the harsh quantization of RoIPool, properly aligning the extracted features with the input. Our proposed change is simple: we avoid any quantization of the RoI boundaries or bins (i.e., we use x=16 instead of [x=16]). We use bilinear interpolation [22] to compute the exact values of the input features at four regularly sampled locations in each RoI bin, and aggregate the result (using max or average), see Figure 3 for details. We note that the results are not sensitive to the exact sampling locations, or how many points are sampled, as long as no quantization is performed。
圖11 雙線性插值
6. LOSS計算與分析
由于增加了mask分支,每個ROI的Loss函數(shù)如下所示:
其中Lcls和Lbox和Faster r-cnn中定義的相同。對于每一個ROI,mask分支有Km*m維度的輸出,其對K個大小為m*m的mask進行編碼,每一個mask有K個類別。我們使用了per-pixel sigmoid,并且將Lmask定義為the average binary cross-entropy loss 。對應一個屬于GT中的第k類的ROI,Lmask僅僅在第k個mask上面有定義(其它的k-1個mask輸出對整個Loss沒有貢獻)。我們定義的Lmask允許網(wǎng)絡為每一類生成一個mask,而不用和其它類進行競爭;我們依賴于分類分支所預測的類別標簽來選擇輸出的mask。這樣將分類和mask生成分解開來。這與利用FCN進行語義分割的有所不同,它通常使用一個per-pixel sigmoid和一個multinomial cross-entropy loss ,在這種情況下mask之間存在競爭關系;而由于我們使用了一個per-pixel sigmoid 和一個binary loss ,不同的mask之間不存在競爭關系。經(jīng)驗表明,這可以提高實例分割的效果。
一個mask對一個目標的輸入空間布局進行編碼,與類別標簽和BB偏置不同,它們通常需要通過FC層而導致其以短向量的形式輸出。我們可以通過由卷積提供的像素和像素的對應關系來獲得mask的空間結構信息。具體的來說,我們使用FCN從每一個ROI中預測出一個m*m大小的mask,這使得mask分支中的每個層能夠明確的保持m×m空間布局,而不將其折疊成缺少空間維度的向量表示。和以前用fc層做mask預測的方法不同的是,我們的實驗表明我們的mask表示需要更少的參數(shù),而且更加準確。這些像素到像素的行為需要我們的ROI特征,而我們的ROI特征通常是比較小的feature map,其已經(jīng)進行了對其操作,為了一致的較好的保持明確的單像素空間對應關系,我們提出了ROIAlign操作。
三、Mask R-CNN細節(jié)分析
1. Head Architecture
圖12 Head Architecture
如上圖所示,為了產(chǎn)生對應的Mask,文中提出了兩種架構,即左邊的Faster R-CNN/ResNet和右邊的Faster R-CNN/FPN。對于左邊的架構,我們的backbone使用的是預訓練好的ResNet,使用了ResNet倒數(shù)第4層的網(wǎng)絡。輸入的ROI首先獲得7x7x1024的ROI feature,然后將其升維到2048個通道(這里修改了原始的ResNet網(wǎng)絡架構),然后有兩個分支,上面的分支負責分類和回歸,下面的分支負責生成對應的mask。由于前面進行了多次卷積和池化,減小了對應的分辨率,mask分支開始利用反卷積進行分辨率的提升,同時減少通道的個數(shù),變?yōu)?4x14x256,最后輸出了14x14x80的mask模板。而右邊使用到的backbone是FPN網(wǎng)絡,這是一個新的網(wǎng)絡,通過輸入單一尺度的圖片,最后可以對應的特征金字塔,如果想要了解它的細節(jié),請參考該鏈接。得到證實的是,該網(wǎng)絡可以在一定程度上面提高檢測的精度,當前很多的方法都用到了它。由于FPN網(wǎng)絡已經(jīng)包含了res5,可以更加高效的使用特征,因此這里使用了較少的filters。該架構也分為兩個分支,作用于前者相同,但是分類分支和mask分支和前者相比有很大的區(qū)別??赡苁且驗镕PN網(wǎng)絡可以在不同尺度的特征上面獲得許多有用信息,因此分類時使用了更少的濾波器。而mask分支中進行了多次卷積操作,首先將ROI變化為14x14x256的feature,然后進行了5次相同的操作(不清楚這里的原理,期待著你的解釋),然后進行反卷積操作,最后輸出28x28x80的mask。即輸出了更大的mask,與前者相比可以獲得更細致的mask。
圖13 BB輸出的mask結果
如上圖所示,圖像中紅色的BB表示檢測到的目標,我們可以用肉眼可以觀察到檢測結果并不是很好,即整個BB稍微偏右,左邊的一部分像素并沒有包括在BB之內(nèi),但是右邊顯示的最終結果卻很完美。
2. Equivariance in Mask R-CNN
Equivariance 指隨著輸入的變化輸出也會發(fā)生變化。
圖14 Equivariance 1
即全卷積特征(Faster R-CNN網(wǎng)絡)和圖像的變換具有同變形,即隨著圖像的變換,全卷積的特征也會發(fā)生對應的變化;
圖15 Equivariance2
在ROI上面的全卷積操作(FCN網(wǎng)絡)和在ROI中的變換具有同變性;
圖16 Equivariance3
ROIAlign操作保持了ROI變換前后的同變性;
圖17 ROI中的全卷積
圖18 ROIAlign的尺度同變性
圖19 Mask R-CNN中的同變性總結
3. 算法實現(xiàn)細節(jié)
圖20 算法實現(xiàn)細節(jié)
觀察上圖,我們可以得到以下的信息:
四、性能比較
1. 定量結果分析
表1 ROI Pool和ROIAlign性能比較
由前面的分析,我們就可以定性的得到一個結論,ROIAlign會使得目標檢測的效果有很大的性能提升。根據(jù)上表,我們進行定量的分析,結果表明,ROIAlign使得mask的AP值提升了10.5個百分點,使得box的AP值提升了9.5個百分點。
表2 Multinomial和Binary loss比較
根據(jù)上表的分析,我們知道Mask R-CNN利用兩個分支將分類和mask生成解耦出來,然后利用Binary Loss代替Multinomial Loss,使得不同類別的mask之間消除了競爭。依賴于分類分支所預測的類別標簽來選擇輸出對應的mask。使得mask分支不需要進行重新的分類工作,使得性能得到了提升。
表3 MLP與FCN mask性能比較
如上表所示,MLP即利用FC來生成對應的mask,而FCN利用Conv來生成對應的mask,僅僅從參數(shù)量上來講,后者比前者少了很多,這樣不僅會節(jié)約大量的內(nèi)存空間,同時會加速整個訓練過程(因此需要進行推理、更新的參數(shù)更少啦)。除此之外,由于MLP獲得的特征比較抽象,使得最終的mask中丟失了一部分有用信息,我們可以直觀的從右邊看到差別。從定性角度來講,F(xiàn)CN使得mask AP值提升了2.1個百分點。
表4 實例分割的結果
表5 目標檢測的結果
觀察目標檢測的表格,我們可以發(fā)現(xiàn)使用了ROIAlign操作的Faster R-CNN算法性能得到了0.9個百分點,Mask R-CNN比最好的Faster R-CNN高出了2.6個百分點。
2. 定性結果分析
圖21 實例分割結果1
圖22 實例分割結果2
圖23 人體姿勢識別結果
圖24 失敗檢測案例1
圖25 失敗檢測案例2
五、總結
Mask R-CNN論文的主要貢獻包括以下幾點:
參考文獻:
[1] 何鎧明大神在ICCV2017上在的Slides,視頻鏈接
[2] Ardian Umam對Mask R-CNN的講解,視頻鏈接
注意事項:
[1] 該博客是本人原創(chuàng)博客,如果您對該博客感興趣,想要轉載該博客,請與我聯(lián)系(qq郵箱:1575262785@qq.com),我會在第一時間回復大家,謝謝大家。
[2] 由于個人能力有限,該博客可能存在很多的問題,希望大家能夠提出改進意見。
[3] 如果您在閱讀本博客時遇到不理解的地方,希望可以聯(lián)系我,我會及時的回復您,和您交流想法和意見,謝謝。
[4] 本人業(yè)余時間承接各種本科畢設設計和各種小項目,包括圖像處理(數(shù)據(jù)挖掘、機器學習、深度學習等)、matlab仿真、python算法及仿真等,有需要的請加QQ:1575262785詳聊?。?!