SOLO 與 SOLOv2 論文閱讀

李謦伊
謦伊的閱讀筆記
8 min readOct 9, 2021

SOLO 的全名為 Segmenting Objects by Locations,顧名思義就是根據位置來分割目標物,是一個簡單、快速且強大的實例分割模型。本文將要來介紹 SOLO 與 SOLOv2 ~

🔖 Github: https://github.com/WXinlong/SOLO

SOLO (ECCV 2020)

📝 Paper: https://arxiv.org/abs/1912.04488

SOLO 引入了實例類別 (instance categories) 的概念,來預測每個 pixel 所在的物件實例的類別,而區分物件實例的方式是根據其中心位置尺寸大小。這樣的作法將實例分割問題轉化為分類問題,出發點為仿照語義分割的思想: 預測每個 pixel 的類別。

整體思路可以看作者的回答 → 🔍 如何看待SOLO: Segmenting Objects by Locations,是實例分割方向嗎?

網路架構為 backbone + FPN,且在 FPN 的每一層都有兩個分支 — Category Branch、Mask Branch。最後再使用 NMS 獲得最終的分割結果,不需要其他的後處理。

實現作法是先將不同大小的物體藉由 FPN 分配到不同層級的 feature map,這樣的方式就是依據尺寸大小來區分實例。接著再把輸入圖像劃分為 S x S 個 grid,因此會有 S² 個位置。若實例的中心落入其中一個 grid cell,則此 grid cell 要負責預測該實例的類別及 mask。

Category Branch

用來預測實例的類別,這部分會利用中心位置來區分實例,輸出為 S x S x C,其中 C 表示該實例的中心位置類別。

Mask Branch

用來預測實例的 mask,對於每個正樣本會預測相對應的 mask,其中正樣本的選取是在實例的中心點周圍 ε=0.2 倍區域。輸出會是 H x W x S²,其 channel 與 grid 的關係式: k = i x S + j,表示第 k 個 channel 負責預測第 (i, j) 個 grid 的 mask。

此外,在輸入到網路前使用了 CoordConv,將每個 pixel 的座標 normalize 至 [-1, 1],再跟原輸入 concat,這時維度變為 H x W x (D+2),其中最後兩個 channel 為 x, y 座標。

之所以使用 CoordConv 是因為 FCN 具有平移不變性,但 mask 基於 S x S 個grid 且需要用不同的 channel 來分割。

Decoupled SOLO

在大多數情況下,圖像不會有非常多的實例,而原本的 Mask Branch 的輸出 channel 為 S²,因此會有很多 channel 是多餘的。

為了讓訓練及測試更有效率,提出了 Decoupled SOLO。作法是替換原始的輸入為 X branch: H x W x S 和 Y branch: H x W x S,再進行 element-wise multiplication,將輸出降成了 S+S。能夠在保持準確率的同時,降低 GPU 的使用率。

下表為 SOLO 的 mask AP 結果,若使用 Res-101-FPN backbone 的 SOLO 能夠跟 Mask R-CNN∗ 有相同的表現,若採用 D-SOLO 則有更高的 AP,其中 D-SOLO 代表 Decoupled SOLO。

SOLOv2

📝 Paper: https://arxiv.org/abs/2003.10152

延續了 SOLO 的做法,針對 mask 的準確率與速度做了兩項改進: Mask learning、Mask NMS,前者是為了產生高精準度的 mask,而後者是為了提升推理速度。

Mask learning

將原始的 Mask Branch 改為 mask kernel branch 以及 mask feature branch,如下圖 (b),分別用於學習卷積核跟特徵。

  • mask kernel branch

由輸入 F_I 經過 4 個 conv + 3x3xD conv 生成 G,並且在進入第一個卷積層前會仿照 CoordConv 的作法以加入空間功能 (spatial functionality) — 將每個 pixel 的座標 normalize 至 [-1, 1],再跟原輸入 concat。

輸出 G 為預測的 kernel weights,維度 SxSxD,S 為 grid 的數目、D 為參數的數量,其中 D 的計算方式與輸入的維度有關,是根據輸入來動態的學習 kernel weights。若輸入 feature map 為 1x1xE,則 D = E;若輸入 feature map 為 3x3xE,則 D = 9E。

  • mask feature branch

這個分支是用於將所有 FPN 層輸出的特徵進行融合,一般來說有兩種做法:

  1. learn the feature in the head separately for each FPN level: 對 FPN 每一層都預測 mask feature,再進行融合
  2. unified mask feature representation for all FPN levels: 對 FPN 每一層預測一個統一的 mask feature

SOLOv2 採用了第二種方法,由下圖所示,將 FPN 的 P2~P5 層分別通過 3x3 conv, group norm, ReLU, 2x bilinear upsampling,統一至原輸入的 1/4,再做 element-wise summation,最後採用 1x1 convolution, group norm, ReLU 得到 mask feature。另外,在 FPN 最深層 (即 1/32 scale) 中有使用 CoordConv,放置位置在 3x3 conv 之前。

Mask NMS

Mask NMS 用於獲取最終的分割結果,其思路來自於 Soft NMS。Soft NMS 的作法是降低 IOU 較大候選框的置信度,但由於流程是 sequential,因此沒辦法實現平行處理。

對於某一個候選框 m_j 的置信度被降低會受到以下因素影響:

  1. 每個預測的 m_i 對候選框 m_j 的懲罰 (penalty),其中 s_i > s_j,s 表示為置信度分數,該懲罰可由 f(iou_i, j) 得到。
  2. m_i 的置信度有可能受到其他 m_k 的影響而衰減,但這個概率不太容易計算。由於該概率與 IOU 呈現正相關,因此直接使用 m_k 和 m_i 最大的 IOU 來近似該概率。

最終的 decay factor 公式如下

接著乘上 decay factor 更新置信度

另外,f(iou_i, j) 和 Soft NMS 一樣考慮了兩個遞減函數: 線性和高斯函數

以下是 Matrix NNS 的 pseudo-code,其操作可以一次性地實現,因而能夠提升推理速度,比 traditional NMS 快九倍。

由下圖可以看到 SOLOv2 的結果,能夠在提升推理速度的同時,達到更高的準確率。另外,還有提供更輕量的模型,在 COCO test-dev 達到 37.1% AP、31.3 FPS。除此之外,在物件檢測與全景分割任務上也擁有很好的表現。

--

--