前言
最近有一篇綜述目標檢測的論文《Deep Learning for Generic Object Detection: A Survey》,來自首爾國立大學的 Lee hoseong 在近期開源了「deep learning object detection」GitHub 項目,正是參考該論文開發的。該項目集合了從 2013 年 11 月提出的 R-CNN 至在近期發表的 M2Det 等幾十篇關於目標檢測的論文,相當全面。
github項目上有張圖片,裏面用紅色標註出了經典的必讀論文。
SSD
2016年12月北卡大學教堂山分校的Wei Liu等提出SSD算法。將YOLO的迴歸思想和Faster R-CNN的anchor box機制結合。
網絡的主要結構如下:
SSD借用預訓練的VGG16作爲主幹網絡,在網絡後面去掉了全連接層,新加了幾層定製的卷積層,然後在多尺度的特徵圖上用卷積核做分類和bbox迴歸。輸入圖片有300x300和512x512兩種大小。本文主要講述SSD300。
主要特點如下:
- 採用多尺度特徵圖用於檢測
SSD網絡最後參與分類和定位迴歸的不止一層特徵圖,而是好幾層。比較大的特徵圖來用來檢測相對較小的目標,而小的特徵圖負責檢測大目標。
- 採用卷積進行檢測
對特徵圖進行分類和定位迴歸的時候,沒有采用全連接,而是採用3x3的卷積核。對於形狀爲 m x n x p 的特徵圖,假設有c個分類, 每個位置有k個先驗框,則共需要3 x 3 x p這樣較小的卷積核,共需要(c+4) x k個。輸出的特徵大小爲m x n x ((c+4) x k)。
其實採用卷積進行檢測除了省時間還有一個附帶的好處,那就是能利用卷積的技巧進行更進一步的改進,後面很多基於SSD的改進項目都用到了特徵融合等技巧,這都是卷積帶來的便利。
- 使用不同大小和寬高比的先驗框
SSD借鑑了Faster R-CNN中anchor的理念,每個單元設置尺度或者長寬比不同的先驗框,預測的邊界框(bounding boxes)是以這些先驗框爲基準的偏移係數,在一定程度上減少訓練難度。偏移係數的計算方式和Faster R-CNN中一樣,就不多講了。
SSD設置先驗框的規律就是前面大的特徵圖(包含底層信息多)用小的先驗框檢測小物體,後面特徵圖越小(抽象層次越高)先驗框越大用於檢測大物體.
損失函數
損失函數定義爲位置誤差(locatization loss, loc)與置信度誤差(confidence loss, conf)的加權和:
位置誤差與Faster R-CNN一樣採用smooth_l1 loss, 分類置信度誤差採用交叉熵。α設爲1。
預測過程
預測過程比較簡單,對於每個預測框,首先根據類別置信度確定其類別(置信度最大者)與置信度值,並過濾掉屬於背景的預測框。然後根據置信度閾值(如0.5)過濾掉閾值較低的預測框。對於留下的預測框進行解碼,根據先驗框得到其真實的位置參數(解碼後一般還需要做clip,防止預測框位置超出圖片)。解碼之後,一般需要根據置信度進行降序排列,然後僅保留top-k(如400)個預測框。最後就是進行NMS算法,過濾掉那些重疊度較大的預測框。最後剩餘的預測框就是檢測結果了。
性能評估
一句話概括:又快又好。
Figure 4 展示了 SSD 模型對 bounding box 的 size 非常的敏感。也就是說,SSD 對小物體目標較爲敏感,在檢測小物體目標上表現較差。提高輸入圖像的 size 可以提高對小目標的檢測效果。要知道論文裏已經針對小目標做了數據增強了。
整體效果還是很驚豔的:
模型分析
對SSD的各個trick做了更爲細緻的分析:
從上表可以看出一下幾點:
- 數據增廣(Data augmentation)對於結果的提升非常明顯
- 使用更多的 feature maps 對結果提升更大
- 使用更多的 default boxes,結果也越好
- Atrous 使得 SSD 又好又快. Atrous其實就是空洞卷積,主要爲了利用已有的VGG模型做finetunning。我個人理解完全重新訓練SSD的話Atrous是沒必要的,暫時沒數據來支持自己的看法。
檢測代碼
下面代碼來自:balancap/SSD-Tensorflow
最上面的整體框圖,用於檢測的特徵圖傳給一個ssd_multibox_layer函數,代碼見下方。
- 分類和迴歸使用兩個不同的3x3卷積核來完成
- 兩個卷積核都沒有激活函數,這裏模擬的全連接的操作,但是計算量更小
def ssd_multibox_layer(inputs,
num_classes,
sizes,
ratios=[1],
normalization=-1,
bn_normalization=False):
"""Construct a multibox layer, return a class and localization predictions.
"""
net = inputs
if normalization > 0:
net = custom_layers.l2_normalization(net, scaling=True)
# Number of anchors.
num_anchors = len(sizes) + len(ratios)
# Location.
num_loc_pred = num_anchors * 4
loc_pred = slim.conv2d(net, num_loc_pred, [3, 3], activation_fn=None,
scope='conv_loc')
loc_pred = custom_layers.channel_to_last(loc_pred)
loc_pred = tf.reshape(loc_pred,
tensor_shape(loc_pred, 4)[:-1]+[num_anchors, 4])
# Class prediction.
num_cls_pred = num_anchors * num_classes
cls_pred = slim.conv2d(net, num_cls_pred, [3, 3], activation_fn=None,
scope='conv_cls')
cls_pred = custom_layers.channel_to_last(cls_pred)
cls_pred = tf.reshape(cls_pred,
tensor_shape(cls_pred, 4)[:-1]+[num_anchors, num_classes])
return cls_pred, loc_pred
DSSD
SSD的第一作者Wei Liu也是DSSD的第一作者,所以DSSD就是爲了改進SSD。
SSD的缺點作者在論文裏說了,對於小目標檢測較差,其次bachbone選的比較老的VGG16,這個還有進一步的改進空間。所以DSSD做出了以下改進:
- 使用具有更好表徵能力的resnet101代替VGG16
- 用反捲積層(deconvolution layer )上採樣, 利用Top-Down的網絡結構進行高低層特徵的融合,使得每個特徵圖預測都能充分利用上下文信息
- 改進特徵融合的方法:採用點積
- 提出由殘差單元組成的預測模塊,進一步提取深度特徵,最後輸入給框迴歸任務和分類任務
- 提出了一種通用的Top-Down的融合方法,使用vgg和resnet網絡,以及不同大小的訓練圖片尺寸來驗證算法的通用型
總體結構
DSSD的總體結構和SSD對比如下:
上圖的上面是SSD的結構,下面是DSSD的結構。
可以看到,除了最小的那個特徵圖,其他用於預測的特徵圖都是來自兩部分:原始特徵圖和前一級小一號的融合特徵圖。同時每個融合後的特徵圖除了用於預測,還要提供給更大的特徵圖進行上採樣融合。
這麼說可能不是很直觀,看下《Deep Learning for Generic Object Detection: A Survey》裏的圖就比較清楚了:
注意兩個分支融合的時候採用的是點積的方式。也就是說小特徵圖先2倍上採樣到與大特徵圖相同的尺寸,然後做點積。
預測模塊
作者提出了殘差單元組成的預測模塊:
上圖a是原始的SSD的預測模塊。後面3個是改進方案。
經過對比測試,C方案的預測模塊最好。然後在C預測模塊基礎上對比了融合的方法:相加和點乘。發現點乘好一點。最後一行是在整個網絡在backbone的基礎上 fine-tune之後再單獨 fine-tune DM模塊,但是結果回退了。
綜上,最好的結果就是c方案的預測模塊加點乘的融合模塊。
測試結果
無論是整體效果還是小目標的檢測效果,都優於SSD:
但是,速度也沒優勢了:
測試效果圖:
結論
與SSD相比,DSSD模型在兩種情況下都有所改進。第一種情況是在包含小物體或稠密物體的場景中,由於輸入的體積較小,SSD不適用於小對象,但DSSD明顯改善。第二種情況是可以改進具有特定關係的物體的檢測:領帶和穿西裝的男人,棒球棒和棒球運動員,足球和足球運動員,網球拍和網球運動員,以及滑板和跳躍的人。
參考資料
綜合
英文論文:Deep Learning for Generic Object Detection: A Survey
翻譯:Deep Learning for Generic Object Detection: A Survey – 目標檢測綜述總結
github: hoya012/deep_learning_object_detection
SSD資料
arxiv 論文 SSD:Single Shot MultiBox Detector
基本上算是對論文的翻譯:論文閱讀:SSD: Single Shot MultiBox Detector
ssd tensorflow 源碼: balancap/SSD-Tensorflow
DSSD資料
論文: DSSD : Deconvolutional Single Shot Detector