論文筆記-Strip Pooling: Rethinking Spatial Pooling for Scene Parsing


paper: Strip Pooling: Rethinking Spatial Pooling for Scene Parsing

code: https://github.com/Andrew-Qibin/SPNet

Abstract

  1. CVPR2020的一篇文章,通過改進空間池化層來優化場景分割的任務。其出發點是,傳統的標准pooling多是方形,而實際場景中會有一些物體是長條形,需要模型能夠盡可能捕獲一個long-range的dependencies。因此,作者引入來一種long but narrow kernel
  2. 本文主要的幾個關注點是:
    • 引入strip pooling,即前面說的long but narrow kernel
    • 在上面的基礎上,構造來strip pooling module(SPM),使得該結構在現有的網絡結構中能夠即插即用
    • 進一步將strip pooling和standard spatial pooling組合,提出mixed pooling module,即綜合標准的spatial pooling和strip pooling,以兼顧各種shape的物體的分割
    • 基於上面的所有改進,提出SPNet,驗證前面幾點的有效性

Details

  1. strip pooling如何實現?

    • 實際物體中有不少物體依賴long-range的dependencies,那么從pooling的角度解決這一的問題,最直接的方式應該就是把pooling操作改成long but narrow的形狀,即本文說的strip pooling
    • 實現上,很簡單,相當於把標准的spatial pooling的kernel的寬或高置為1,然后每次取所有水平元素或垂直元素相加求平均(average pooling,按文中公式的表述,每次取的所有水平元素或垂直元素的個數分別為輸入的tensor的w和h),即只是改變了spatial pooling中采樣的方式,對應論文中的公式2和3
    • 在作者公布的PyTorch源碼中,作者是通過AdaptiveAvgPooling實現的
      • PyTorch的AdaptiveAvgPooling操作,是由用戶指定輸入和輸出的size,該操作內部會去計算對應的stride和kernel size,可以參考這里
    • 利用strip pooling和spatial pooling的效果對比可以看下圖
  2. strip pooling module

    • 為了能讓strip pooling實現在現有的不同網絡結構中即插即用,作者設計了strip pooling module,即將strip pooling封裝到該模塊內部,保證對於輸入特征圖,經過SPM模塊后,是已經執行過strip pooling操作的特征圖
    • 如下圖:
      • 對於一個輸入tensor,用兩個pathway分別處理水平和垂直的strip pooling,然后再expand到輸入tensor的原尺寸(看下文中的代碼,這個expand應該是通過上采樣的插值實現的interprolate
      • 然后將兩個pathway的結果相加進行融合;之后再添加一個1x1 conv(改變channel個數),然后加上sigmoid激活函數
      • 同時SPM中有一個類似residual的identity map操作,將上面兩個pathway融合后經過sigmoid的結果直接通過element-wise的乘法融合到一起。這里相當於上一步sigmoid得到的是一個權重矩陣,得到輸入tensor中每個位置的特征的重要性,因此,上面2路的pathway其實是可以不用重新訓練的,有點像attention機制
  3. mixed pooling module

    • 如果因為上面的考慮將網絡中的所有pooling全部換成strip pooling操作,則必然會影響原來的非長條物體的效果,就得不償失了。因此,作者將strip pooling和pyramid pooling都加入進來,構造成mixed pooling module
    • 其中,strip pooling用於解決long-range dependencies,而輕量級的pyramid pooling用於解決short-range dependencies
  4. 實現代碼

    • SPNet部分,其backbone是resnet系列
    • 參考源碼StripPooling部分
      ### 通過AdaptiveAvgPool2d實現strip pooling
      self.pool1 = nn.AdaptiveAvgPool2d(pool_size[0])
      self.pool2 = nn.AdaptiveAvgPool2d(pool_size[1])
      self.pool3 = nn.AdaptiveAvgPool2d((1, None))
      self.pool4 = nn.AdaptiveAvgPool2d((None, 1))
      
      ## SPM模塊
      def forward(self, x):
          _, _, h, w = x.size()
          x1 = self.conv1_1(x)
          x2 = self.conv1_2(x)
          x2_1 = self.conv2_0(x1)
          x2_2 = F.interpolate(self.conv2_1(self.pool1(x1)), (h, w), **self._up_kwargs)
          x2_3 = F.interpolate(self.conv2_2(self.pool2(x1)), (h, w), **self._up_kwargs)
          x2_4 = F.interpolate(self.conv2_3(self.pool3(x2)), (h, w), **self._up_kwargs)
          x2_5 = F.interpolate(self.conv2_4(self.pool4(x2)), (h, w), **self._up_kwargs)
          x1 = self.conv2_5(F.relu_(x2_1 + x2_2 + x2_3))
          x2 = self.conv2_6(F.relu_(x2_5 + x2_4))
          out = self.conv3(torch.cat([x1, x2], dim=1))
          return F.relu_(x + out)
      

Conclusions

  1. 個人感覺strip pooling這個思路還是比較有道理,且實現也比較簡單,對於交通場景中的,路障,車道線這類物體,應該是會有所幫助的。
  2. 再者,其中strip pooling這個思路,如果和非對稱卷積結合到一起,有沒有可能會進一步提升文中闡述的需要long-range dependencies的物體的效果呢?如ACNet的做法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM