1. 程式人生 > 實用技巧 >【CoSOD】ICNet: Intra-saliency Correlation Network for Co-Saliency Detection

【CoSOD】ICNet: Intra-saliency Correlation Network for Co-Saliency Detection

ICNet: Intra-saliency Correlation Network for Co-Saliency Detection

原始文件:https://www.yuque.com/lart/papers/abs95w

前言

這是南開大學發表在NeurIPS 2020上的一篇關於Co-Saliency的文章. 這篇文章同樣也是利用現有的SOD方法(EGNet)設計的框架式的模型. 所以研究的關鍵在於如何同時利用來自SOD模型的intra-saliency cues, 並通過利用correlation techniques將其與inter-saliency cues進行整合.

整體框架

本文針對這個問題, 設計了一個模型. 整體框架如下:

  • 首先利用normalized masked average pooling (NMAP) 組合單影象slaiency maps (SISMs), 提取latent intra-saliency categories
  • 再利用correlation fusion module (CFM)通過利用intra cues和單張影象特徵的相關性來獲取inter cues
  • 同時也提出了category-independent rearranged self-correlation feature (RSCF) strategy來維持特徵相對於語義類別的獨立性, 既可以從全域性感受野中收益, 又可以提升效能

提取intra Cues

現有方法試圖使用SISM作為訓練目標來訓練子網路, 而不是直接整合SISM到網路中端到端訓練. 由於SISM的並不能準確的指示single-salient regions, 顯式用其監督模型會導致不準確的intra cues.
為了更好地而整合SISM和語義特徵以獲取更加具有判別力的intra cues, 這裡使用了normalized masked average pooling (NMAP)[Amp: Adaptive masked proxies for few-shot segmentation] 操作.

        # 從VGG16 backbone中提取特徵.
        conv1_2 = self.vgg(image_group, 'conv1_1', 'conv1_2_mp')  # shape=[N, 64, 224, 224]
        conv2_2 = self.vgg(conv1_2, 'conv1_2_mp', 'conv2_2_mp')  # shape=[N, 128, 112, 112]
        conv3_3 = self.vgg(conv2_2, 'conv2_2_mp', 'conv3_3_mp')  # shape=[N, 256, 56, 56]
        conv4_3 = self.vgg(conv3_3, 'conv3_3_mp', 'conv4_3_mp')  # shape=[N, 512, 28, 28]
        conv5_3 = self.vgg(conv4_3, 'conv4_3_mp', 'conv5_3_mp')  # shape=[N, 512, 14, 14]

        # 對high-level features的特徵先進行一次壓縮.
        conv6_cmprs = self.conv6_cmprs(conv5_3)  # shape=[N, 128, 7, 7]
        conv5_cmprs = self.conv5_cmprs(conv5_3)  # shape=[N, 256, 14, 14]
        conv4_cmprs = self.conv4_cmprs(conv4_3)  # shape=[N, 256, 28, 28]

        # 獲得co-saliancy features.
        cosal_feat_6 = self.Co6(conv6_cmprs, SISMs)  # shape=[N, 128, 7, 7]
        cosal_feat_5 = self.Co5(conv5_cmprs, SISMs)  # shape=[N, 128, 14, 14]
        cosal_feat_4 = self.Co4(conv4_cmprs, SISMs)  # shape=[N, 128, 28, 28]
  • 首先NMAP輸入包含兩部分: 來自VGG的高層特徵和來自現有SOD方法(off-the-shelf SOD model)的預測結果SISM, 作者給出的理由是: we use the SISMs predicted by any off-the-shelf SOD model to directly filter out the features of potentially non-salient regions by multiplication, rather than taking these SISMs as the training targets and forcing the Co-SOD models into overfitting inaccurate SISMs with performance drop. In this way, even though the SISMs are not precisely accurate, the inaccuracy will be largely diluted after averaging and normalizing operations.
    def forward(self, feats, SISMs):
        N, C, H, W = feats.shape
        HW = H * W
        # 將SISMs調整到和輸入特徵feats一樣的尺度.
        SISMs = resize(SISMs, [H, W])  # shape=[N, 1, H, W]
  • 輸入一組來自VGG的後兩層的l2歸一化後的特徵F:
        # NFs: L2標準化(normalize)後的特徵.
        NFs = F.normalize(feats, dim=1)  # shape=[N, C, H, W]
  • 使用對應的SISM S來對其放縮並生成single-image vectors (SIVs), 如式1. 也即是先空間上加權平均後在進行l2歸一化:
        # 計算 SIVs [3.2節, 式1].
        SIVs = F.normalize((NFs * SISMs).mean(dim=3).mean(dim=2), dim=1).view(N, C, 1, 1)  # shape=[N, C, 1, 1]

提取Inter Cues

這部分主要設計來提取intra cues之間的Inter cues. 不同於現有方法通過拼接、或者使用固定數量圖片分組(這類方法使用迴圈結構, 對於輸入順序有依賴, 而固定的數量也會導致, 預定義類別上學習到的語義向量難以處理看到沒有見過的目標類別)來整合特徵, 為此作者提出了correlation fusion module (CFM) 來避免以上的這些問題.

受到VOS的啟發, 這座認為獲得準確CoSOD map的關鍵在於_dense correlations between the SIVs and single-image features_, 所以CFM主要就是在計算SIV中的V和SISM中的F之間的畫素級相關性, 從而可以生成有用的inter cues, 並且處理任意數量的圖片組. 主要過程如下:

  • 該部分輸入包含兩部分, 前面得到的SIV特徵V和l2歸一化後的來自VGG的特徵F:
        # 計算 co-salient attention (CSA) maps [3.3節].
        CSA_maps = CFM(SIVs, NFs)  # shape=[N, 1, H, W]
  • 使用SIV中的向量( shape=[N, C, 1, 1]這裡直接作為F.conv2d的權重, 也就是對應於\((\text{out_channels} , \frac{\text{in_channels}}{\text{groups}} , kH , kW)\)的卷積核, 與歸一化特徵計算相似性(內積), 從而獲得correlation maps C, 這裡實際上關聯起了單樣本特徵內部的通道和外部樣本的分組.
        def CFM(SIVs, NFs):
            # 計算SIVs和NFs中每個畫素的內積, 產生correlation maps [圖4].
            # 我們通過 ``F.conv2d()'' 來實現這一過程, 其中將SIVs作為1*1卷積的引數對NFs進行卷積.
            correlation_maps = F.conv2d(NFs, weight=SIVs)  # shape=[N, N, H, W]
  • 但是由於SIVs並不表示co-salient category類別, 所以生成的相關圖會強調與co-salient category無關的區域. 為了抑制這些噪聲的影響, 作者進一步使用相關圖之間的相關性對自身加權.

            # 向量化(vectorize)並標準化(normalize) correlation maps.
            correlation_maps = F.normalize(correlation_maps.reshape(N, N, HW), dim=2)  # shape=[N, N, HW]

            # 計算權重向量(weight vectors) [式2].
            correlation_matrix = torch.matmul(correlation_maps, correlation_maps.permute(0, 2, 1))  # shape=[N, N, N]
            weight_vectors = correlation_matrix.sum(dim=2).softmax(dim=1)  # shape=[N, N]
  • 接下來使用權重W加權C, 獲得一個co-salient attention (CSA) map A, 作為F的Inter cue.
            # 根據權重向量(weight vectors)對correlation maps進行融合, 產生co-salient attention (CSA) maps.
            CSA_maps = torch.sum(correlation_maps * weight_vectors.view(N, N, 1), dim=1)  # shape=[N, HW]
  • 之後使用min-max歸一化操作獲得A. 這樣的相關性權重可以在一定程度上弱化噪聲的影響, 因為有噪聲的相關圖和其他相關圖勢必有更小的相關性.
           # Max-min normalize CSA maps (將CSA maps的範圍拉伸至0~1之間).
            min_value = torch.min(CSA_maps, dim=1, keepdim=True)[0]
            max_value = torch.max(CSA_maps, dim=1, keepdim=True)[0]
            CSA_maps = (CSA_maps - min_value) / (max_value - min_value + 1e-12)  # shape=[N, HW]
            CSA_maps = CSA_maps.view(N, 1, H, W)  # shape=[N, 1, H, W]
            return CSA_maps

Rearranged Self-Correlation Feature

獲得CSA map之後, 正如[Co-saliency detection via mask-guided fully convolutional networks with multi-scale label smoothing]中建議的, 將其與l2規範化的特徵F相乘來專注於co-salient region和最終預測得到Co-SOD map A. 然而, 觀察到這種方式下, 模型不能判斷有著相似但是卻不同類別的畫素.這主要是因為A和F之間不一致的類別依賴.

  • A是category-independent且可以反映出潛在的co-saliency socre得分
  • F是category-related且每個畫素都是一個表示特定類別的向量

  • 為了計算SCF, 這裡需要輸入前面的歸一化特徵F.
        # 計算 self-correlation features (SCFs) [3.4節].
        SCFs = get_SCFs(NFs)  # shape=[N, HW, H, W]
  • 計算F內部的自相關矩陣, 並調整維度. 最終得到的張量中, 會表示F中的任一點與全圖HxW之間的相關性. 這確保SCF不依賴於特定的類別資訊, 而是與全域性有關.
        def get_SCFs(NFs):
            NFs = NFs.view(N, C, HW)  # shape=[N, C, HW]
            SCFs = torch.matmul(NFs.permute(0, 2, 1), NFs).view(N, -1, H, W)  # shape=[N, HW, H, W]
            return SCFs
  • 雖然SCF與CSA的組合受益於類別獨立的一致性, 但是SCF的使用可能導致潛在的過擬合風險, 這是因為SCF中的每個通道是一個關於某個空間位置的自相關圖, 這使得基於固定通道順序學習到的引數是位置相關的. 為了緩解這一問題, 這裡對SCF使用了通道重排的策略.
  • 對於通道重排, 這裡是基於得到的CSA作為索引參考的. 也就是在A中有著更高co-saliency value的位置, 在F中的對應的\(z=(x-1)W+y\)通道會被放置到重新生成的RSCF F中的靠上的通道位置裡. 這樣的設計使得FSCF中的通道順序獨立於畫素位置. 這裡使用 gather方法對SCF的通道進行調整.
      # 重排列(Rearrange)SCFs的通道順序, 產生RSCFs [3.4節].
        evidence = CSA_maps.view(N, HW)  # shape=[N, HW]
        indices = torch.argsort(
            evidence, dim=1, descending=True
        ).view(N, HW, 1, 1).repeat(1, 1, H,  W)  # shape=[N, HW, H, W]
        RSCFs = torch.gather(SCFs, dim=1, index=indices)  # shape=[N, HW, H, W]
        cosal_feat = self.conv(RSCFs * CSA_maps)  # shape=[N, 128, H, W]

實驗細節

  • 訓練設定:

    • 資料集為COCO的9213張子集圖片, 可在github上下載到.
    • 輸入尺寸為:224x224.
    • 每個迭代的batch是一組包含10個影象的分組
  • 測試設定:

    • 輸入尺寸為:224x224.
    • 每個包含任意數量的影象的影象組作為一個batch, 一次性預測結果(也就是整個測試資料中的影象組一起處理).
  • 損失函式:

    • IOUloss:

失敗案例分析

由於本文的模型構建與SISM之上, 當使用的SISM不夠可靠的時候, 會出現CoSOD的錯誤預測. 作者回應道, 雖然失敗案例可能會讓人懷疑我們的ICNet的健壯性, 但這種極端情況很少發生. 同時, 我們的實驗表明, 只要不是大部分的SISM是不可靠的, ICNet就可以穩定地執行.

相關連結