目標檢測:SSD 算法

日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度學習實戰(不定時更新)


 

5.9 SSD算法原理

學習目標

  • 目標
    • 知道SSD的結構
    • 說明Detector & classifier的作用
    • 說明SSD的優點
  • 應用

5.9.1 SSD

5.9.1.1 簡介

SSD算法源於2016年發表的算法論文,論文網址:https://arxiv.org/abs/1512.02325

SSD的特點在於:

  • SSD結合了YOLO中的迴歸思想和Faster-RCNN中的Anchor機制,使用全圖各個位置的多尺度區域進行迴歸,既保持了YOLO速度快的特性,也保證了窗口預測的跟Faster-RCNN一樣比較精準。
  • SSD的核心是在不同尺度的特徵特徵圖上採用卷積核來預測一系列Default Bounding Boxes的類別、座標偏移。

網絡發展順序fasterrcnn->yolov1->ssd->yolov2->fpn->maskrcnn->yolov3(18)

5.9.1.2 結構

以VGG-16爲基礎,使用VGG的前五個卷積,後面增加從CONV6開始的5個卷積結構,輸入圖片要求300*300。

5.9.1.3 流程

SSD中引入了Defalut Box,實際上與Faster R-CNN的anchor box機制類似,就是預設一些目標預選框,不同的是在不同尺度feature map所有特徵點上使用PriorBox層

5.9.1.4 Detector & classifier

Detector & classifier的三個部分:

  • 1.PriorBox層:生成default boxes,默認先驗框
  • SSD借鑑了Faster R-CNN中anchor的理念,每個單元設置尺度或者長寬比不同的先驗框,預測時候的邊界框(bounding boxes)是以這些先驗框爲基準的,在一定程度上減少訓練難度。
  • 2.Conv3 x 3:生成localization, 4個位置偏移
  • 3.Conv3 x 3:confidence,21個類別置信度(要區分出背景)

5.9.1.5 PriorBox層-default boxes

default boxes(priorobx/先驗框)類似於RPN當中的滑動窗口生成的候選框,SSD中也是對特徵圖中的每一個像素生成若干個框。

先驗框特點分析:

  • priorbox:相當於faster rcnn裏的anchors,預設一些box,網絡根據box,通過分類和迴歸給出被檢測到物體的類別和位置。每個window都會被分類,並回歸到一個更準的位置和尺寸上

根據輸入的不同aspect ratio 和 scale 以及 num_prior來返回特定的default box,以feature map上每個點的中點爲中心,生成一些列同心的prior box

  • 3、最終每個feature map對應box的min_size和max_size由以下公式決定:

公式中的m是指進行預測時使用feature map的數量,如SSD300使用conv4-3等6個不同維度(Detector & classifier)的feature maps進行預測,所以 m=6。同時原文設定s_min=0.2 ,s_max=0.9。

  • 對於conv4-3:k=1, min_size=s1x300,max_size=s2x300...

所以得到默認下面每層的框大小參數:

  • 如下面爲不同大小bbox在每個不同層的設置(SSD使用感受野小的feature map檢測小目標,使用感受野大的feature map檢測更大目標。)

1、SSD網絡prior_box:打印出來的形狀爲:
Tensor("concat_2:0", shape=(?, 7308, 8), dtype=float32)

# 其中某一層的結構輸出
 layer {
  name: "conv6_2_mbox_priorbox"
  type: "PriorBox"
  bottom: "conv6_2"
  bottom: "data"
  top: "conv6_2_mbox_priorbox"
  prior_box_param {
    min_size: 111.0
    max_size: 162.0
    aspect_ratio: 2.0
    aspect_ratio: 3.0
    flip: true
    clip: false
    variance: 0.10000000149
    variance: 0.10000000149
    variance: 0.20000000298
    variance: 0.20000000298
    step: 32.0
    offset: 0.5
}

5.9.1.5 prior box使用過程

localization與confidence這兩者的意義如下,主要作用用來過濾,訓練

1、邊界框的location預測邊界框位置解碼

包含4個值 (center_x,c_centery,w,h),分別表示邊界框的中心座標以及寬高。但是真實預測值其實只是邊界框相對於先驗框的轉換值(論文裏面說是offset類似於YOLO那種)

那麼注意假設我們的網絡最終的預測值L是一箇中間值,會需要經過一個解碼轉換(decode)。假設下面P真正的得到輸出的邊界框,d爲先驗框的位置:

 

那麼預測邊界框的真實位置爲:

當然反過來也是能夠得到一種預測值的編碼關係的。

2、SSD 預測邊界框trick

這裏就是設置variance超參數來調整檢測值,就需要手動設置超參數variance,用來對l的4個值進行放縮,此時邊界框需要這樣解碼

3、代碼展示過程

代碼中的位置輸出也會經過這樣的計算:

def decode(default_boxes, locs, variance=[0.1, 0.2]):
    """ 對default_boxes進行解碼到座標coordinates
    Args:
        default_boxes: tensor (num_default, 4)
                       of format (cx, cy, w, h)
        locs: tensor (batch_size, num_default, 4)
              of format (cx, cy, w, h)
        variance: variance for center point and size
    Returns:
        boxes: tensor (num_default, 4)
               of format (xmin, ymin, xmax, ymax)
    """
    # 解碼過程
    locs = tf.concat([
        locs[..., :2] * variance[0] *
        default_boxes[:, 2:] + default_boxes[:, :2],
        tf.math.exp(locs[..., 2:] * variance[1]) * default_boxes[:, 2:]], axis=-1)

    # (cx, cy, w, h)->(xmin, ymin, xmax, ymax)
    boxes = transform_center_to_corner(locs)

    return boxes

def encode(default_boxes, boxes, variance=[0.1, 0.2]):
    """ Compute regression values
    Args:
        default_boxes: tensor (num_default, 4)
                       of format (cx, cy, w, h)
        boxes: tensor (num_default, 4)
               of format (xmin, ymin, xmax, ymax)
        variance: variance for center point and size
    Returns:
        locs: regression values, tensor (num_default, 4)
    """
    # (xmin, ymin, xmax, ymax)->(cx, cy, w, h)
    transformed_boxes = transform_corner_to_center(boxes)

    # 編碼過程
    locs = tf.concat([
        (transformed_boxes[..., :2] - default_boxes[:, :2]
         ) / (default_boxes[:, 2:] * variance[0]),
        tf.math.log(transformed_boxes[..., 2:] / default_boxes[:, 2:]) / variance[1]],
        axis=-1)

    return locs

問題:SSD中的多個Detector & classifier有什麼作用?

SSD的核心是在不同尺度的特徵圖上來進行Detector & classifier 容易使得SSD觀察到更小的物體

5.9.2 訓練與測試流程

5.9.2.1 train流程

  • 輸入->輸出->結果與ground truth標記樣本回歸損失計算->反向傳播, 更新權值

1. 樣本標記:

先將prior box與ground truth box做匹配進行標記正負樣本,每次並不訓練8732張計算好的default boxes, 先進行置信度篩選,並且訓練指定的正樣本和負樣本, 如下規則

  • 正樣本

    • 1.與GT重合最高的boxes, 其輸出對應label設爲對應物體.
    • 2.物體GT與anchor iou滿足大於0.5
  • 負樣本:其它的樣本標記爲負樣本

在訓練時, default boxes按照正負樣本控制positive:negative=1:3

2. 損失

網絡輸出預測的predict box與ground truth迴歸變換之間的損失計算

  • 置信度是採用 Softmax Loss(Faster R-CNN是log loss)

  • 位置迴歸則是採用 Smooth L1 loss (與Faster R-CNN一樣)

    • 所以位置誤差僅針對正樣本進行計算。要先對ground truth的g進行編碼得到(預測框解碼的反向過程)

3、數據增強

採用數據擴增(Data Augmentation)可以提升SSD的性能,主要採用的技術有水平翻轉(horizontal flip),隨機裁剪加顏色扭曲(random crop & color distortion),隨機採集塊域(Randomly sample a patch)(獲取小目標訓練樣本)。SSD上數據增強的效果增加明顯

5.9.2.2 test流程

  • 預測過程比較簡單,對於每個預測框,首先根據類別置信度確定其類別(置信度最大者)與置信度值,並過濾掉屬於背景的預測框。然後根據置信度閾值(如0.5)過濾掉閾值較低的預測框。對於留下的預測框進行解碼,根據先驗框得到其真實的位置參數。

5.9.3 SSD實驗與總結

5.9.2.1 實驗

  • 1、SSD在VOC2007,VOC2012及COCO數據集上的性能,如下面所示。相比之下,SSD512的性能會更好

  • 2、多尺度特徵圖對SSD的影響

3、SSD與其它檢測算法的對比結果(在VOC2007數據集)如表2所示,基本可以看到,SSD與Faster R-CNN有同樣的準確度,並且與Yolo具有同樣較快地檢測速度。

5.9.3.3 總結

從圖中看出SSD算法有較高的準確率和性能,兼顧了**速度和精度。SSD算法的優點應該很明顯:運行速度可以和YOLO媲美,檢測精度可以和Faster RCNN媲美。當然也有一些缺點:

  • 1、需要人工設置prior box的min_size,max_size和aspect_ratio值。網絡中prior box的基礎大小和形狀不能直接通過學習獲得,而是需要手工設置。

  • 2、雖然採用了pyramdial feature hierarchy的思路,但是對小目標的recall依然一般,並沒有達到超越Faster RCNN太多。主要可能是這是由於SSD使用conv4_3低級feature去檢測小目標,而低級特徵卷積層數少,存在特徵提取不充分的問題。

下面兩個爲github實現的版本:有興趣可以閱讀使用

https://github.com/ChunML/ssd-tf2:易於閱讀和理解模型構建和計算過程

https://github.com/mattroos/ssd_tensorflow2:搭建多種結構模型

5.9.4 總結

  • SSD的結構
  • Detector & classifier的組成部分以及作用
  • SSD的訓練樣本標記
  • GT與default boxes的格式轉換過程

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章