1. 程式人生 > >mask rcnn 論文閱讀筆記

mask rcnn 論文閱讀筆記

Mask RCNN閱讀筆記

目錄

一. 文章主題介紹:

該文章主要是通過擴充套件Faster RCNN,實現例項分割的功能;具體來說,就是在後面添加了一個mask分支用於畫素級別的預測(也就是例項分割)。如下圖所示:
圖1 mask 分支
這個分支僅僅增加很好的計算的消耗
論文作者:Kaiming He(first),CVPR 2017的會議best paper。

二. 文章核心設計:

2.1 mask分支損失函式的計算

新的思想:

1. 不同於FCNs系列的工作——每個畫素即預測類別也預測是否被為物件;而Mask RCNN 分離 了每個畫素是物件以及屬於哪個類別的預測——類別預測直接從類別預測Cls分支中讀取。
2. 這種分離的預測存在另一種特性:就是畫素級的預測掩碼(mask)沒有類別競爭。


mask分支的執行: mask分支的輸出為針對每個RoI 有一個Km2-dimensional輸出。掩碼為二值掩碼——只有0或1。只用來預測該畫素級別的點是否為物件。
Mask 分支程式碼設計示例

class Model ...
# 前層輸出(N,1024,7,7) 
self.out_mask = 
    nn.Sequential(
            nn.ConvTranspose2d(self.out_channels, 
            256, kernel_size=2, stride=2), #(N,256,14,14)
            nn.ReLU(inplace=True)
, nn.Conv2d(256, nb_classes - 1, kernel_size=1, stride=1), # (N,20,14,14) VOC 資料集,20個類別 nn.Sigmoid(), # sigmoid啟用 )

mask分支的損失計算: 利用平均二值交叉驗證損失函式 (binary cross-entroy loss) ,並且根據每個RoI所關聯的類別k,只計算該類別k對應的mask損失計算,其他非k的mask不參與損失計算,也就是每個ROI只計算(1,1,m,m)大小的損失。
損失程式碼:

class class_loss_mask(nn.Module):
    def __init__(self, obj_classes=20):
        super(class_loss_mask, self).__init__()
        self.obj_classes = obj_classes
    def forward(self, preds, targets):
        '''
        :param preds:  (num_rois,num_class,pool,pool)=(20,14,14)
        :param targets: (num_rois,num_class,pool,pool)
        :return:
        '''
        weight = targets[:, :self.obj_classes, :, :]  
        y_true = targets[:, self.obj_classes:, :, :]
        weight = Variable(torch.from_numpy(weight).float()).cuda()
        y_true = Variable(torch.from_numpy(y_true).float()).cuda()
        preds = preds * weight #用於遮蔽非k的類別的損失計算,只計算有效類別的損失
        N = torch.sum(weight)
        return F.binary_cross_entropy(preds, y_true, size_average=False) / N
2.2 ROIAlign的一些改進
1.該技術要解決的問題描述:

[12,18]說明了ROIPooling是粗糙的對齊,ROIPooling存在兩個量化階段

  • RoI邊界量化階段:原圖box與RoI之間的量化, RoIPooling主要採用round[x/16]的方式,16是特徵圖的步長。

  • ROI到Pool盒(bin)階段:RoI與提取的特徵之間的量化,特徵圖(h,w) –> (pool,pool)pool=7或14。作為後面Fast RCNN階段的輸入。

這兩種量化階段導致了RoI提取的特徵之間的錯位(misalignment)問題

2.具體的實現:

1)為了修復這種不對齊的方式,針對兩個量化階段進行修改,在RoI邊界和pool盒(box)階段避免任何量化:

  • x/16代替[x/16],即對步長不做round操作。

  • 對每個RoI在四個位置上執行bilinear interpolation(雙線差值法)操作,然後再用max或者average pool操作。

2)關鍵程式碼如下所示:

class RoIAlign: ....
    region = x_img[:, :, y:(y + h + 1), x:(x + w + 1)]
    region = F.upsample_bilinear(region, (h, w)) # 對RoI使用bilinear操作
    region = self.adaptive_max_pool(region)
2.3 兩種基礎網路

為了驗證Mask RCNN的一般性,它的backbone使用了ResNet和FPN兩種型別的基礎網路架構用於提取特徵,兩個結構對應的mask 分支的示意圖
FPN和ResNet基礎框架對應的Mask分支

FPN獲得的效能優於ResNet的效能;主要是FPN使用金字塔特徵結構,將low-level的特徵與high-level的特徵融合,能提取更加準確的位置等特徵資訊。

三. 打磨實驗:

3.1 實驗引數的配置:
引數
min_side 800 pixels
pos:neg 1:3
learning_rate 0.02(160k),0.002(120k)
weight_decay 0.0001
momentum 0.9
gradient method SGD
RoI數目(ResNet/FPN) (64/512)
anchors 5 scales ,3 aspect ratios
mini_batch 16 (on 8 GPUs)
training set COCO (80 classes)
—test—-
proposal number 300(ResNet), 1000(FPN)
mask branch 取得分top 100的RoI對應的mask輸出
mask threshold 0.5 就是預測大於0.5的標位1
3.2 主要的一些對比實驗

(實驗圖片來自於原始論文
1. 基礎網路結構ResNet和FPN的對比
1)網路深的比淺的效能高 (然而,根據論文,對於物件檢測系統來說不一定越深的、越先進的網路效能就越好)
2)FPN backbone優於ResNet的backbone .
這裡寫圖片描述
2. FCNs系列聯合預測方式與Mask RCNN這種分離的預測方式對比
1)實驗結果表明,這種分離的預測方式比FCNs系列效能好的多,其他分支確定類別和box,而mask只需要預測二值掩碼即可(sigmoid+binary loss)
這裡寫圖片描述
3. 類別指定和類別不可知的mask方式的對比(也就是求mask時是否利用cls分支的結果選擇對應的mask進行解析
1)如下圖所示的對比實驗,結果為Class-Specific .vs Class-Agnotic——30.3 AP vs 29.7 AP,表明了分離的mask分支獨立有效性 (不知理解是否正確,有待考察)
這裡寫圖片描述
4. RoIAlign與RoIPool,RoIWarp等方式的對比
1) 各個資料表明,RoIAlign優於ROIPool
2) RoIAlign 對max或者average pool不敏感
3) 對於更大的32跨度的結構,RoIAlign優勢更加突出,表明RoIAlign一定程度改善大跨度的問題
4) 對於FPN backbone的網路結構,RoIAlign在物件識別的方面表現優勢不明顯,而在關鍵點檢測方面,表現很明顯 (第二、三個表)
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
5. Mask分支使用MLP還是使用FCN結構(全卷積層)的對比
1) 使用FCN結構作為mask分支表現優於MLP,因為卷積層保持了空間佈局的資訊
這裡寫圖片描述
6. Mask RCNN與其他前沿工作的對比
1) 與FCIS和MNC工作的對比,Mask RCNN的效能明顯要好
2) 如下面效果圖展示,FCIS存在systematic artifacts——也就是掩碼中存在一些雜質,瑕疵。而Mask RCNN沒有這種問題 (如紅圈標註)
這裡寫圖片描述
這裡寫圖片描述
7. mask 分支對檢測框預測的影響
1) Mask 分支對Box的預測有一定的提升,可能是多工訓練的原因。
2) 通過列表觀察可以發現,Mask 的AP和Box AP很相近,表明Mask RCNN拉近了box預測和更加有挑戰性的例項分割預測的距離。
**重點內容**這裡寫圖片描述

四. 收穫/總結/啟發:

1) 提出了一種新的思想,將畫素級的預測——分離類別預測和掩碼預測**
2) 為了解決RoIPool錯位問題,提出了RoIAlign 層——使用x/16而不是[x/16]和使用bilinear取樣避免ROI量化**

補充說明

注:(一些網頁需要外網VPN連結)

引用