1. 程式人生 > 其它 >二階段目標檢測總結

二階段目標檢測總結

概述:

最新幾年的論文都是在單階段Transform上進行發掘提升,基本上2020-2021年二階段論文全軍覆沒,這篇博文也是總結2016-2019年的發展,最後一篇CenternetV2比較特殊,不能完全算作傳統意義的二階段網路。

目前什麼地方還使用二階段論文?

  1. 比賽場景,經常使用FasterRCNN的變種+其它網路進行聯合預測
  2. 目標比較小的場景(使用較少,一般用anchor-free、增大輸入去代替、分割影象檢測)
  3. 輔助一階段使用,和(2)類似但不同。比如檢測遠距離人形+人臉,方案一:先檢測人,後檢測人臉,兩個都是OneStage。方案二:使用TwoStage網路,第一階段檢測人形,第二階段檢測人臉。當然只有第二類別是第一類別的從屬,且是唯一關係才能進行!

一. FasterRCNN

以torchvision給出的demo為例子:

  1. 第一階段,和基礎SSD等一階段操作類似,但是這一階段會立刻輸出候選區域

https://github.com/pytorch/vision/blob/183a722169421c83638e68ee2d8fc5bd3415c4b4/torchvision/models/detection/rpn.py#L29

  1. 將候選區域從FPN輸出的feature上摳出來

  2. 使用ROIPooling對齊候選特徵的大小

https://github.com/pytorch/vision/blob/183a722169421c83638e68ee2d8fc5bd3415c4b4/torchvision/ops/poolers.py#L83-L277

  1. 第二階段,直接進行FC細化Reg/Cls,當然這裡只能是一個候選區域最多一個目標。
class FastRCNNPredictor(nn.Module):
    """
    Standard classification + bounding box regression layers
    for Fast R-CNN.
    Args:
        in_channels (int): number of input channels
        num_classes (int): number of output classes (including background)
    """

    def __init__(self, in_channels, num_classes):
        super(FastRCNNPredictor, self).__init__()
        self.cls_score = nn.Linear(in_channels, num_classes)
        self.bbox_pred = nn.Linear(in_channels, num_classes * 4)

    def forward(self, x):
        if x.dim() == 4:
            assert list(x.shape[2:]) == [1, 1]
        x = x.flatten(start_dim=1)
        scores = self.cls_score(x)
        bbox_deltas = self.bbox_pred(x)

        return scores, bbox_deltas

註釋:

  • 最後一步FC是參考anchor的做法,首先想到的是\(self.bbox\_pred = nn.Linear(in\_channels,4)\) ,因為已經使用class進行了過濾,沒有必要再把regression去使用class再去過濾一遍。當然使用class對迴歸進行區分,這效果肯定優於單個迴歸。
  • 我們再進一步延伸,如果在不同的class之下,再使用一種手段(長寬、面積、anchor等)對其進一步劃分,比如:假設候選區域數量不變為 \(P\),類別為兩類(人形、人臉),進一步使用anchor限制(兩個anchor,5和20,比例4倍以內使用5,超過4倍使用20),這樣會不會更精細?
  • 上一步我們限制了候選區域數量,能不能使用輸入多個不同組的候選區域,後面連線多個不同的predict?這就是後續改進cascadeRCNN的由來。

二. MaskRCNN

  1. 第一階段使用FasterRCNN,RPN網路都相同
  2. 第二階段輸出多一個分支 \(K\times m\times m\) , 其中 \(K\) 表示種類,\(m\) 表示輸出解析度

注意: 最後輸出的mask大小是固定的,設定大小得根據實際種類而定。這個mask分支和FCN有點區別,這裡使用K個feature,然後直接進行二分類操作,而FCN使用單個feature進行多分類操作,目前檢測的分類loss都是進行單獨的二分類操作。

三. CascadeRCNN

  1. 第一階段和FasterRCNN完全一樣

  2. 第二階段使用多個RoiHead層進行級聯

下圖完全顯示了CascadeRCNN的由來

  • 下圖(C)僅僅在前向計算的時候使用級聯finetune操作,精度也得到一定提升,但是有兩個缺陷。1)使用共享的Head-H1,不僅時間沒降低,而且引數效果還不好。所以在端側單階段目標檢測中,一般不使用共享的頭,雖然引數減少了,但是計算量一點未變,所以都使用不共享的頭。2)都是固定的,不能進行訓練,後面的階段已經處於過擬合狀態。
  • 下圖(d)最大的缺點就是候選區域固定,非常容易過擬合。有一個優點,後面的stage僅僅進行分類而不進行reg,這是cascade未考慮的。但是,分類分支花費的代價很小,基本影響不到大局,所以討論的人很少。
  • 下圖(b)融合了兩者的優點,1)可訓練。2)不共享。3)候選區域不同。

四. Libra RCNN

未改變實際的流程結構,文章從均衡的角度對各個模組進行改進。

  1. \(feature\) 均衡,使用FPN、PAN、BiFPN進行互相連結
  2. 取樣均衡,原始SSD分配使用Max-IOU,取樣使用Random-Sample
  3. loss均衡,原始SSD直接使用獨立的分支進行計算

IOU-Balance取樣,下圖是困難負樣本(\(Iou<0.5\) 稱為困難負樣本)的Iou分佈,其中64%樣本\(Iou>0.05\),36%的樣本\(Iou<0.05\),注意這裡是百分比圖,不是個數量圖!!!下圖中使用隨機取樣,會導致70%的樣本\(Iou<0.05\) ,這明顯是不符合下圖的困難負樣本的分佈圖的。如何將下附圖的每個方格取樣比例趨於平衡?很明顯的想到還是使用方格將IOU進行區域劃分(直方圖的表示方法),然後按照一定比例進行取樣即可。論文給出一些控制引數,使得表達更為通俗易懂。

關於feature部分的平衡,這部分有點玄,意義不大。。。

關於loss的平衡,主要對smooth-L1進行調整,文章分析了loss的貢獻率,\(loss<1.0\) 貢獻30%,相反貢獻70%,既然要平衡,那就要提升 \(loss<1.0\) 的梯度(loss佔比),其實和focal-loss一樣,都是提升困難樣本的比重。

\[L_{b}(x)=\left\{\begin{array}{ll} \frac{\alpha}{b}(b|x|+1) \ln (b|x|+1)-\alpha|x| & \text { if }|x|<1 \\ \gamma|x|+C & \text { otherwise } \end{array}\right. \]

五. GridRCNN

  1. 第一階段和FasterRCNN完全一樣
  2. 分類分支相同,迴歸分支使用關鍵點

從當前的角度看,這篇論文較為簡單,屬於簡化版的anchor-free模型,因為是對候選區域進行操作,不需要anchor的匹配,不需要進行nms等操作。和top-bottom的pose估計一模一樣!!

如果把第一階段也使用關鍵點去估計,那這篇二階段文章就完全是anchor-free+pose的文章了。

需要注意一點,經常出現候選區域把目標截斷(二階段網路都存在的問題),那關鍵點就不存在(使用0表示),但是對於定位就很不準確。最簡單的方式是直接擴大候選區域的截圖範圍,作者嘗試這種方案效果不理想。作者採用候選區域不變,僅對候選迴歸框做擴大。如下圖所示,綠色是目標框,白色實線是候選框,輸入白色實線候選區域,在白色虛線的基礎上進行迴歸。

GridRCNN-V2

  1. 第一階段和FasterRCNN完全一樣
  2. 第二階段和GridRCNN-V1基本相同

這篇論文主要是對第一版本的速度進行改進:

  • keypoint branch 從\(56\times56\)降低到\(28 \times 28\) ,論文說這樣做不僅會加快速度,而且還會提高精度。之前在關鍵點上試驗,使用期望定位會有精度損失。
  • 減小候選區域的大小,降低channels
  • 聯合整個batch影象進行計算。之前使用for迴圈,單次計算單張影象,對於目標數量非常敏感,現在是對batch進行一次計算。
  • NMS僅進行一次

六. CenterNetV2

在剛開始的概述(3)中,表達了一種二階段網路的特殊應用,這篇文章將此應用表述成一種方案:我們可以使用任何一階段的網路作為RPN層(包括anchor-based、anchor-free操作),後面ROI階段可以使用任何之前的第二階段網路。這不就是集合前人的大雜燴?搞不懂為啥沒有使用YOLOV4作為第一階段進行比較

進一步引申:

  • 類似人形+人臉的檢測組合(概述3)
  • 關鍵點檢測模型(Top-Bottom),比如人體關鍵點估計,可以直接使用二階段網路。