【核心概念】影象分類和目標檢測中的正負樣本劃分以及架構理解

2022-07-31 12:02:26

1.前言

理解有監督的深度學習的關鍵在於將 推理訓練 階段進行分開,分別理解各種深度神經網路架構的推理和訓練階段的操作就可以理解某個模型。

我們定義的模型相當於一個複雜的非線性函數的集合,使用有監督學習的優化方法(如SGD),我們就可以在這個函數集中優化出來一個 複雜的非線性函數。對於分類問題,通過該函數就可以把線性不可分的特徵輸入,轉化為線性可分的特徵。對於迴歸問題,該函數是一個學習的高維輸入特徵到輸出的對映。

推理階段是將模型看成一個類似於黑箱的非線性函數,比如通過各種折積模組的組合構成一個backbone,輸出想要的shape的張量,再去做後處理。

訓練階段是需要劃分正負樣本,然後根據任務設計一個損失函數,使用優化演演算法如SGD以迭代的方式更新神經元的weightbias,優化的目標是最小化損失函數,因此訓練好的模型就可以擬合訓練集。這就帶來了訓練的模型的過擬合問題,也就是所謂的泛化問題。許多深度學習的工作都在解決該問題,這確實是一個值得研究的好問題,後面我會全面的整理該問題。

我們通常可以把所有的神經網路以 編碼器-解碼器 的架構進行理解。

2. 影象分類

  1. 推理階段:輸入為一個小 batch 的影象, 然後是編碼器(如CNN)進行編碼為張量,一般是 W/H 減小 x 倍, 而通道數 C 增加 y 倍, 編碼成新的張量 (bs,W/x, H/x, yC)。然後是 解碼器 ,加入 FC、softmax 等。當然,也可以將 softmax 之前的全部理解為 編碼器, 把 softmax 理解為 解碼器。

  2. 訓練階段:和推理階段一樣,不過是softmax輸出的 向量 需要和 標註的標籤計算交叉熵損失(常用),從而反向傳播更新 softmax 之前的全部weightbias

正負樣本

在影象分類任務 中正樣本是該類所有的影象,負樣本是其他類所有的影象。網路輸入正樣本影象, 然後該位置的預測值和標籤向量中 1 的地方求損失, 所以預測值會變大, 從而降低損失,由於 softmax 約束, 那麼預測向量的其他值會變小;同理,對於當前類,其他類別的影象就是負樣本,輸出概率會往 0 進行優化。所以,對於影象分類來說,我們並不需要關注正負樣本的劃分,因為通過 標籤的one-hot 編碼,自然的相當於區分了正負樣本。

但是,這也帶來了一個致命問題:上述方法是在封閉訓練集中訓練的,只能把輸入分類到定義的類別,雖然可以通過卡閾值的方法過濾結果,但是有的負樣本完全和定義的類別不一樣卻可能有很高的概率。這種問題叫做:開放域識別問題

3. 目標檢測

目標檢測是一個略顯複雜的問題,因為一般它包含 目標的定位(迴歸任務)、目標分類(分類任務)和置信度(迴歸)。這使得目標檢測的架構更加複雜,一般來說,目標檢測的架構為Backbone + Neck + Detection head。有趣的是 這個命名, 軀幹 然後是 脖子 最後是 決策的檢測頭。

  1. 推理階段
  • Backbone 常為 我們在大型的影象分類資料集(如ImageNet)上進行訓練的預訓練模型(影象分類的編碼器),這是因為 分類問題的標註 更加便宜,而網路在兩個任務上的提取的特徵卻可以通用,因此是一種遷移學習的思想。
  • Neck 是 Backbone 輸出的張量的一些 特徵融合操作,得到更好的組合特徵以適應於不同大小目標的檢測
  • Detection head 是對 Neck 融合後的張量的進行操作,輸出想要的shape的張量。最後是後處理,根據閾值刪除一部分向量,然後使用NMS去除冗餘的邊框。

當然,我們可以將 Backbone + Neck 看成編碼器,Detection head 看成解碼器。注意:可能有的架構並沒有 Neck , 如 YOLO v1,所以會帶來效能損失。

Backbone + Neck + Detection head 的架構讓我們可以分別設計單個模組, 然後進行替換即可構造不同的目標檢測模型。(當然,許多人就這樣水論文嘛,簡稱縫合怪!)

  1. 訓練階段

訓練階段的核心在於 損失函數的設計。Detection head 輸出的張量與標籤標註的求損失,從而去更新網路。所以,這部分並不涉及上面的 後處理。 這裡的關鍵在於 正負樣本的選擇 ,從而來計算損失。

目標檢測任務中,輸入一張影象,和影象分類不同的是,正負樣本的單位不再是一張影象,而是一張影象中的某個區域,所以一張影象有多個正負樣本,雖然這些區域的大小比影象分類中的影象要小,但是由於數量巨多,所以目標檢測相比影象分類要慢的多。

那麼如何得到這些區域(樣本)?如何把這麼多的區域分為正負樣本?

這是兩個重要的問題。前者:一種常用的做法是 anchor based 的方法來得到這些區域,每個影象的小塊上生成的一些先驗框 anchor 就是樣本。 後者:常用的是基於和 真實標註框 的IOU來劃分正負樣本, 不同的演演算法策略不同。

那麼劃分的正負樣本有什麼用?

劃分的正負樣本在訓練模型時候是用來確定哪些損失被計算。如果anchor 劃分為正樣本, 那麼對該正樣本進行迴歸就可以得到預測框,那麼預測框就可以參與損失函數中定位損失的計算。正樣本需要計算 邊框迴歸損失,置信度損失和分類損失。如果anchor 劃分為負樣本, 那麼只需要對該負樣本計算置信度損失即可。通過這種方式,模型對不同的 anchor 就可以給出一個置信度,目標的置信度一般會得到一個較大的概率。所以,模型學習到了哪些區域才是目標。

注意這裡有三種框:

  • 真實標註框
  • 先驗框anchor
  • 預測框

綜上,目標檢測中的正樣本並不是真實標註框。正如影象分類中的 one-hot 編碼的向量一樣,真實標註框是優化的目標。正如影象分類中的 某個類的影象,正樣本是那些選擇的部分先驗框anchor。正如影象分類中的預測向量,而通過模型迴歸先驗框anchor得到的結果是預測框。所以預測框和真實框求Loss。當然,像 yolov1 並沒有 anchor,所以有部分不同。

YOLOv4 中總結了整個架構:

Backbone + Neck + Detection head 模組:

  • Input: Image, Patches, Image Pyramid
  • Backbones: VGG16, ResNet-50, SpineNet , EffificientNet-B0/B7, CSPResNeXt50, CSPDarknet53, swin transformer
  • Neck:
    • Additional blocks: SPP, ASPP, RFB , SAM
    • Path-aggregation blocks: FPN, PAN, NAS-FPN, Fully-connected FPN, BiFPN, ASFF, SFAM
  • Heads:
    • Dense Prediction (one-stage):
      • RPN, SSD, YOLO(v2-v5), RetinaNet (anchor based)
      • YOLOv1, CornerNet, CenterNet, MatrixNet, FCOS(anchor free)
    • Sparse Prediction (two-stage):
      • Faster R-CNN, R-FCN, Mask R-CNN(anchor based)
      • RepPoints(anchor free)

參考:

一部分 正負樣本劃分策略:https://murphypei.github.io/blog/2020/10/anchor-loss.html

anchor 生成方法:https://zhuanlan.zhihu.com/p/450451509

YOLOv4 論文:https://arxiv.org/abs/2004.10934