五、SSD原理(Single Shot MultiBox Detector)


主流的算法主要分為兩個類型:

(1)tow-stage

R-CNN系列算法,其主要思路是先通過啟發式方法(selective search)或者CNN網絡(RPN)產生一些列稀疏的候選框,然后對這些候選框進行分類和回歸。two-stage方法的優勢是准確度高。

(2)one-stage

如YOLO和SSD,主要思路是均勻的在圖片的不同位置進行密集抽樣,抽樣時可以采用不同尺度和長寬比,然后利用CNN提取特征后直接進行分類和回歸,整個過程只需要一部,所以其優勢是速度快。

均勻的密集采樣的一個重要缺點是訓練比較困難,這主要是因為正樣本與負樣本極其不平衡,導致模型准確度稍低,不同算法的性能如圖:

SSD英文名是(Single Shot MultiBox Detector),single shot指的是SSD算法屬於one-stage方法,MultiBox說明SSD是多框預測

上圖可以看出SSD在准確度和速度(除了SSD512)上都比YOLO要好很多。

下圖是不同算法的基本框架圖,對於Faster R-CNN,其先通過CNN得到候選框,然后再進行分類和回歸,而Yolo與SSD可以一步到位完成檢測。相比於YOLO,SSD采用CNN來直接進行檢測,而不是像YOLO那樣在全連接層之后再做檢測。

其實采用卷積直接做檢測只是SSD相比於YOLO的其中一個不同點,另外還有兩個重要的改變,一是SSD提取不同尺度的特征圖來做檢測,大尺度特征圖(較靠前的特征圖)用來檢測小物體,小尺度特征圖(較靠后的特征圖,感受野大)用來檢測大物體;二是SSD采用了不同尺度和長寬比的先驗框(Prior boxes, Default boxes,在Faster R-CNN中叫做錨,Anchors)。Yolo算法的缺點是難以檢測小目標,而且定位不准,但是這幾點重要的改進使得SSD在一定程度上克服這些缺點。

設計理念

SSD和YOLO都是采用一個CNN網絡來進行檢測,但是卻采用了多尺度的特征圖,其基本架構如下圖,下面將SSD核心設計理念總結為以下三點:

(1)采用多尺度特征圖用於檢測

所謂多尺度采用大小不同的特征圖,CNN網絡一般前面的特征圖比較大,后面會逐漸采用stride=2的卷積或者pool來降低特征圖大小,下圖所示,一個比較大的特征圖和一個比較小的特征圖,他們都用來做檢測。這樣做的好處是比較大的特征圖用來檢測相對較小的目標,而小的特征圖負責檢測大目標,8x8的特征圖可以划分更多的單元,但是其每個單元的default box尺度比較小。

(2)采用卷積進行檢測

與Yolo最后采用全連接層不同,SSD直接采用卷積對不同的特征圖來進行提取檢測結果。對於形狀為的特征圖,只需要采用這樣比較小的卷積核得到檢測值。

(3)設置先驗框default boxes

在YOLO中,每個單元預測多個邊界框,但是其都是相對這個單元本身(正方塊),但是真實目標的形狀是多變的,Yolo需要在訓練過程中自適應目標的形狀。而SSD借鑒了Faster R-CNN中anchor的理念,每個單元設置尺度或者長寬比不同的default boxes預測的邊界框(bounding boxes)是以這些先驗框為基准的,在一定程度上減少訓練難度。

一般情況下,每個單元會設置多個default boxes,其尺度和長寬比存在差異,如下圖所示,可以看到每個單元使用了4個不同的default boxes,圖片中貓和狗分別采用最適合它們形狀的先驗框來進行訓練,后面會詳細講解訓練過程中的先驗框匹配原則。

SSD的檢測值也與YOLO不太一樣,對於每個單元cell的每個先驗框default box,其都輸出一套獨立的檢測值,對於一個bouding box,主要分為兩個部分:

  • 第一個部分是各個類別的置信度或者評分
    • 值得注意的是SSD將背景也當做了一個特殊的類別,如果檢測目標共有c個類別,SSD其實需要預測c+1個置信度值,其中第一個置信度是不含目標或者屬於背景的評分。后面當我們說c個類別置信度時,請記住里面包含背景那個特殊的類別,即真實的檢測類別只有c-1個。
    • 在預測過程中,置信度最高的那個類別就是邊界框所屬的類別。特別的,當第一個置信度最高時,表示邊界框中並不包含目標。
  • 第二個部分就是邊界框的location,包含4個值,分別表示邊界框的中心坐標以及寬高。但是真實預測其實只是預測邊界框相對於先驗框的轉換值(offset)
    • 先驗框(anchor)位置用表示,其對應預測的邊界框表示,那么邊界框的預測值l其實是b相對於d的轉換值:

習慣上,我們稱上面這個過程為邊界框的編碼(encode),預測時,你需要反向這個過程,即進行解碼(decode),從預測值l中得到邊界框的真實值b:

然而,在SSD的caffe源碼實現中還有trick,那就是設置variance超參數來調整檢測值,通過bool參數variance_encoded_in_target來控制兩種模式。當其為true時,表示variance(方差)被包含在預測值中,就是上面那種情況,如果是false(大部分采用這種方式,訓練更容易),就需要手動設置超參數variance,用來對l的4個值進行放縮,此時邊界框需要這樣解碼:

綜上所述,對於一個大小的特征圖,共有m x n 個單元,每個單元設置的先驗框數目記為k,那么每個單元共需要個預測值,所有的單元共需要個預測值,由於SSD采用卷積做檢測,所以就需要個卷積核來完成這個特征圖的檢測過程。(卷積核參數共享)。

網絡結構

SSD采用VGG16作為基礎模型,然后在VGG16的基礎上新增了卷幾層來獲得更多的特征圖以用於檢測。SSD網絡結構如圖所示:

很明顯可以看出SSD利用了多尺度的特征圖做檢測,模型的輸入圖片大小是(還可以是),其與前者網絡結構沒有差別,只是最后新增一個卷積層。

采用VGG16做基礎模型,首先VGG16是在ILSVRC CLS-LOC數據集預訓練。然后借鑒了DeepLab-LargeFOV,分別將VGG16的全連接層fc6和fc7轉換成 3\times3 卷積層 conv6和 1\times1 卷積層conv7,同時將池化層pool5由原來的stride=2的 2\times 2 變成stride=1的 3\times 3 (猜想是不想reduce特征圖大小),為了配合這種變化,采用了一種Atrous Algorithm,其實就是conv6采用擴展卷積或帶孔卷積(Dilation Conv),其在不增加參數與模型復雜度的條件下指數級擴大卷積的視野,其使用擴張率(dilation rate)參數,來表示擴張的大小,如下圖6所示,(a)是普通的 3\times3 卷積,其視野就是 3\times3 ,(b)是擴張率為1,此時視野變成 7\times7 ,(c)擴張率為3時,視野擴大為 15\times15 ,但是視野的特征更稀疏了。Conv6采用 3\times3 大小但dilation rate=6的擴展卷積。

 

然后移除dropout層和fc8層,並新增一系列卷積層,在檢測數據集上做finetuing。

其中VGG16中的Conv4_3層將作為用於檢測的第一個特征圖。conv4_3層特征圖大小是 38\times38 ,但是該層比較靠前,其norm(范數)較大,所以在其后面增加了一個L2 Normalization層(參見ParseNet),以保證和后面的檢測層差異不是很大,這個和Batch Normalization層不太一樣,其僅僅是對每個像素點在channle維度做歸一化,而Batch Normalization層是在[batch_size, width, height]三個維度上做歸一化。歸一化后一般設置一個可訓練的放縮變量gamma,使用TF可以這樣簡單實現:

1 # l2norm (not bacth norm, spatial normalization)
2 def l2norm(x, scale, trainable=True, scope="L2Normalization"):
3     n_channels = x.get_shape().as_list()[-1]
4     l2_norm = tf.nn.l2_normalize(x, [3], epsilon=1e-12)
5     with tf.variable_scope(scope):
6         gamma = tf.get_variable("gamma", shape=[n_channels, ], dtype=tf.float32,
7                                 initializer=tf.constant_initializer(scale),
8                                 trainable=trainable)
9         return l2_norm * gamma

從后面新增的卷積層中提取Conv7,Conv8_2,Conv9_2,Conv10_2,Conv11_2作為檢測所用的特征圖,加上Conv4_3層,共提取了6個特征圖,其大小分別是 (38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1) ,但是不同特征圖單元cell設置的先驗框數目不同同一個特征圖上每個單元設置的先驗框是相同的,這里的數目指的是一個單元的先驗框數目)。先驗框的設置,包括尺度(或者說大小)和長寬比兩個方面。對於先驗框的尺度,其遵守一個線性遞增規則:隨着特征圖大小降低,先驗框尺度線性增加

每一個feature map中的每一個小格子(cell)都包含多個default box,同時每個box對應loc(位置坐標)和conf(每個種類的得分)。

default box長寬比例默認有四個六個:

四個default box是長寬比(aspect ratios)為(1:1)、(2:1)、(1:2)、(1:1);六個則是添加了(1:3)、(3:1)

為什么會有兩個(1:1)呢。這時候就要講下論文中Choosing scales and aspect ratios for default boxes這段內容了。作者認為不同的feature map應該有不同的比例(一個大框一個小框,長寬比相同,大框是指不同feature map 相對於原圖的尺寸比例不同),這是什么意思呢,代表的是default box中這個1在原圖中的尺寸是多大的,計算公式如下所示:

Sk即代表在300*300輸入中的比例,表示先驗框大小相對於圖片的比例

m為當前的feature map是第幾層;   m=5,因為一共有6個feature map,但是第一層(Conv4_3層)是單獨設置的

k代表的是一共有多少層的feature map

Smin和Smax代表的是第一層和最后一層所占的比例,比例的最小值和最大值,在ssd300中為0.2-0.9。

計算:

第一個feature map 是 conv4_3:默認設置比例為0.2/2=0.1, 此時k=1

第二個feature map 是 conv7: k=2,s = 0.2 +(0.7/4) x (2-1) =0.375 ,最后300x0.375 = 112.5,這個就是在這個feature map中比例為1的這個default box 的尺寸相對於原圖300x300 的大小。

為什么default box的size有兩個1嗎?

作者在這有引入了一個s'_{k}=\sqrt{s_k s_{k+1}},也就是每個特征圖都設置了兩個長寬比為1大小不同的正方形default box。有的小伙伴可能會有疑問,這有了Sk+1則需要多出來一部分的Sk啊,是的沒錯,最后一個特征圖需要參考s_{m+1}=300\times105/100=315來計算s'_{m},因此每個特征圖(的每個cell)都有6個default box\{1,2,3,\frac{1}{2},\frac{1}{3},1'\}aspect ratios),但是在實現時, Conv4_3,Conv10_2,Conv11_2僅僅使用4個先驗框(default box),不使用長寬比為3,1/3的先驗框(default box)。作者的代碼中就添加了兩層,第一層取0.1最后一層取1

注:對於第一個特征圖,先驗框(default box)的尺度比例一般s_{min}/2=0.1,則尺度為300x0.1=30。

對於后面的特征圖,先驗框尺度比例按照上面公式線性增加,先將尺度比例放大100倍,然后再計算得到Sk,然后再將Sk除以100,再乘以圖片大小,就可以得到各個特征圖的先驗框的size30,60,111, 162,213,264

那么S怎么用呢?按如下方式計算先驗框的寬高(這里的Sk是上面求得的各個特征圖的先驗框的實際size,不再是尺度比例):

w^a_{k}=s_k\sqrt{a_r},\space h^a_{k}=s_k/\sqrt{a_r}

ar代表的是之前提到的default box(aspect ratios)比例,即a_r\in \{1,2,3,\frac{1}{2},\frac{1}{3}\}

對於default box中心點的值取值為:

(\frac{i+0.5}{|f_k|},\frac{j+0.5}{|f_k|}),i,j\in[0, |f_k|)

其中i,j代表在feature map中的水平和垂直的第幾格

fk代表的是feature map的size

每個單元的先驗框中心點分布在各單元的中心

得到特征圖后,需要對特征圖進行卷積得到檢測結果,下圖給出了一個5x5大小的特征圖檢測過程:

Priorbox是得到先驗框,生成規則前面已經講了。

檢測值包含兩個部分:類別置信度和邊界框位置,各采用一次3x3卷積來進行完成。

n_k是該特征圖所采用的先驗框數目,那么類別置信度需要的卷積核數量為n_k\times c,而邊界框位置需要的卷積核數量為n_k\times 4。由於每個先驗框都會預測一個邊界框,所以SSD300一共可以預測

    Conv4_3  得到的feature map大小為38*38:38*38*4 = 5776

  Conv7      得到的feature map大小為19*19:19*19*6 = 2166

  Conv8_2  得到的feature map大小為10*10:10*10*6 = 600

  Conv9_2  得到的feature map大小為5 * 5  :5 * 5 * 6 = 150

  Conv10_2得到的feature map大小為3 * 3  :3 * 3 * 4 = 36

  Conv11_2得到的feature map大小為1 * 1  :1 * 1 * 4 = 4

  最后結果為:8732

38\times38\times4+19\times19\times6+10\times10\times6+5\times5\times6+3\times3\times4+1\times1\times4=8732 個邊界框,這是一個相當龐大的數字,所以說SSD本質上是密集采樣。

訓練過程

(1)先驗框匹配

在訓練過程中,首先要確定訓練圖片中的ground truth(真實目標)與哪個先驗框來進行匹配,與之匹配的先驗框所對應的邊界框將負責預測它

Yolo中,ground truth的中心落在哪個單元格,該單元格中與其IOU最大的邊界框負責預測它。

SSD中,先驗框與ground truth的匹配原則又兩點:

1、每個ground truth找到與其IOU最大的先驗框,互相匹配。該先驗框稱為正樣本(先驗框對應的預測box)

若有個先驗框沒有與ground truth匹配,就只能與背景匹配,就是負樣本。(一個圖片中ground truth少,但先驗框多,這樣匹配,很多先驗框會是負樣本,正負樣本不均衡)。

2、對剩余未匹配先驗框,若某個ground truth的IOU大於某個閾值(一般是0.5),那么該先驗框也與這個ground truth進行匹配。

   這樣ground truth可能與多個先驗框匹配

FP:負樣本       TP:正樣本

盡管一個ground truth可以與多個先驗框匹配,但是ground truth相對於先驗框還是太少了,所以負樣本會很多。為保證正負樣本盡量均衡,SSD采用了hard negative mining,先將每一個物體位置上對應 predictions(default boxes)是 negative 的 boxes 進行排序,按照 default boxes 的 confidence 的大小。 選擇最高的幾個,保證最后 negatives、positives 的比例接近3:1

(2)損失函數

損失函數定義為位置誤差(locatization loss, loc)與置信度誤差(confidence loss, conf)的加權和:

L(x, c, l, g) = \frac{1}{N}(L_{conf}(x,c) + \alpha L_{loc}(x,l,g))

其中 N 是先驗框的正樣本數量。

這里 x^p_{ij}\in \{ 1,0 \} 為一個指示參數,當 x^p_{ij}= 1 時表示第 i 個先驗框與第 j 個ground truth匹配,並且ground truth的類別為 p 。

 c 為類別置信度預測值。

 l 為先驗框的所對應邊界框的位置預測值

 g 是ground truth的位置參數

對於位置誤差,其采用Smooth L1 loss,定義如下:

由於 x^p_{ij} 的存在,所以位置誤差僅針對正樣本進行計算。值得注意的是,要先對ground truth的 g 進行編碼得到 \hat{g} ,因為預測值 l 也是編碼值,若設置variance_encoded_in_target=True,編碼時要加上variance:

\hat{g}^{cx}_j = (g^{cx}_j - d^{cx}_i)/d^w_i/variance[0], \hat{g}^{cy}_j = (g^{cy}_j - d^{cy}_i)/d^h_i/variance[1]

\hat{g}^{w}_j = \log(g^{w}_j/d^w_i)/variance[2], \space \hat{g}^{h}_j = \log(g^{h}_j/d^h_i)/variance[3]

 對於置信度誤差,其采用softmax loss:

權重系數 \alpha 通過交叉驗證設置為1。

(3)數據擴增

采用數據擴增(Data Augmentation)可以提升SSD的性能,主要采用的技術有水平翻轉(horizontal flip)隨機裁剪加顏色扭曲(random crop & color distortion)隨機采集塊域(Randomly sample a patch)(獲取小目標訓練樣本),如下圖所示:

 

預測過程

確定預測框類別(置信度最大者)與置信度值,並且過濾掉屬於背景的預測框,過濾掉置信度閾值較低的預測框;

對留下的預測框進行編碼,得到真實的位置參數(解碼后還需要clip,防止預測框位置超出圖片);

解碼之后,根據置信度進行降序排列,保留top-k個預測框;

進行NMS算法,過濾掉那些重疊度比較大的預測框,最后剩余的預測框就是檢測結果了。

性能評估

首先整體看一下SSD在VOC2007,VOC2012及COCO數據集上的性能,如表1所示。相比之下,SSD512的性能會更好一些。加*的表示使用了image expansion data augmentation(通過zoom out來創造小的訓練樣本)技巧來提升SSD在小目標上的檢測效果,所以性能會有所提升。

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

文章還對SSD的各個trick做了更為細致的分析,表3為不同的trick組合對SSD的性能影響,從表中可以得出如下結論:

    • 數據擴增技術很重要,對於mAP的提升很大;
    • 使用不同長寬比的先驗框可以得到更好的結果;

 

同樣的,采用多尺度的特征圖用於檢測也是至關重要的,這可以從表4中看出:

 

 補充

1、L2 normalization

2、hard nevigating mining


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM