1. 程式人生 > >SSD:Single Shot MultiBox Detector

SSD:Single Shot MultiBox Detector

    本文提出的SSD演算法是一種直接預測目標類別和bounding box的多目標檢測演算法。與faster rcnn相比,該演算法沒有生成 proposal 的過程,這就極大提高了檢測速度。針對不同大小的目標檢測,傳統的做法是先將影象轉換成不同大小(影象金字塔),然後分別檢測,最後將結果綜合起來。而SSD演算法則利用不同卷積層的 feature map 進行綜合也能達到同樣的效果。演算法的主網路結構是VGG16,將最後兩個全連線層改成卷積層,並隨後增加了4個卷積層來構造網路結構。對其中5種不同的卷積層的輸出(feature map)分別用兩個不同的 3×3 的卷積核進行卷積,一個輸出分類用的confidence

,每個default box 生成21個類別confidence;一個輸出迴歸用的 localization,每個 default box 生成4個座標值(x, y, w, h)。此外,這5個feature map還經過 PriorBox 層生成 prior box(生成的是座標)。上述5個feature map中每一層的default box的數量是給定的(8732個)。最後將前面三個計算結果分別合併然後傳給loss層。

基礎

Ap:平均準確率

mAp:m個類別的Ap平均值。

feature map cell:是指feature map中每一個小格子,就是上圖中的每個小方格,上圖分別有64個feature map cell 和16個feature                               map cell 

default box:是指每個feature map cell上都有一系列固定大小的box,也就是上圖中的虛線框。

ground truth: 在機器學習中,資料是有標註的<x,t>, t是正確標註的ground truth。就好像上圖中x是框的資訊,t就是貓或者狗                          的資訊。

prior box:是指在實際選擇fdefault box 過程中(在實際選擇中我們並不是每個feature map cell的k個default box 都取)也就是說                   default box是一種概念,prior box則是實際的選取。

           訓練中一張完整的圖片送進網路獲得各個feature map,對於正樣本訓練來說,需要先將prior box與ground truth box做匹配(就是把一張圖片 輸入到 region network中,判斷有物體的區域就是prior box,可以看一下fast rcnn的解釋),匹配成功說明這個prior box所包含的是個目標,但離完整目標的ground truth box還有段距離,訓練的目的是保證default box的分類confidence的同時將prior box儘可能迴歸到ground truth box。

             舉個列子:在上圖中一個訓練樣本中有2個ground truth box,所有的feature map中獲取的default  box一共有8732個。那個可能分別有10、20個prior box能分別與這2個ground truth box匹配上。訓練的損失包含定位損失和迴歸損失兩部分。

             假設每個feature map cell有k個default box,那麼對於每個default box都需要預測c個類別score和4個offset,那麼如果一個feature map的大小是m×n,也就是有m*n個feature map cell,那麼這個feature map就一共有(c+4)*k * m*n 個輸出。這些輸出個數的含義是:採用3×3的卷積核對該層的feature map卷積時卷積核的個數,包含兩部分(實際code是分別用不同數量的3*3卷積核對該層feature map進行卷積):數量c*k*m*n是confidence輸出,表示每個default box的confidence,也就是類別的概率;數量4*k*m*n是localization輸出,表示每個default box迴歸後的座標

卷積核配置 :假設Feature Map通道數為P,SSD網路中每個Stage的卷積核大小統一為3*3*P。其中padding和stride都為1。                              保證卷積後的Feature Map和卷積前是一樣大小。

卷積濾波器 :每個Feature Map上mxn個大小的特徵點對應K個Default Boxes,假設類別數+背景=c,最終通過卷積濾波器得到                          c+4維特徵向量。那麼一個Feature Map上的每個點就需要使用kx(c+4)個這樣的濾波器。

論文貢獻

  1.  我們提出了SSD,一個多分類單杆檢測器(single-shot detector),比現在的單杆檢測器(YOLO)更快,和那些較慢技術精度一樣,並且超過了區域提議(region proposals)和池化(pooling)的方法,包括faster R-CNN.
  2.   SSD的核心部分是預測分類得分和一個固定集合的預設邊界框的框偏移,這些是通過使用卷積濾波器到特徵圖上實現的。 
  3. 為了獲得高檢測精度,我們會從不同比例的特徵圖來產生不用比例的預測,通過縱橫比來分開預測。
  4.  這些設計特徵可以進行端到端訓練,精度還很高,在輸入圖片解析度很低的情況下精度也能保持高精度。改進了速度和進度折中均衡的局面。
  5.  實驗包含模型之間速度和精度的分析,用了不同輸入大小,資料集為PASCALVOC,COCO和ILSVRC,比較了最近的最新的方法。

網路

Default Box

     default box在上文中已經介紹,那麼default box的scale(大小)和aspect ratio(橫縱比)要怎麼定呢?假設我們用m個feature maps做預測,那麼對於每個featuer map而言其default box的scale是按以下公式計算的: 

S_{k}=S_{min}+\frac{(S_{max}-S_{min})}{m-1}(k-1),k∈[1,m]

這裡smin是0.2,表示最底層的scale是0.2;smax是0.9,表示最高層的scale是0.9。

至於aspect ratio,用a_{r}表示為下式:注意這裡一共有5種aspect ratio 

ar={1,2,3,1/2,1/3}

因此每個default box的寬的計算公式為: 

W_{k}^{a}=S_{k}\sqrt{a_{r}}

高的計算公式為:(很容易理解寬和高的乘積是scale的平方) 

h_{k}^{a}=S_{k}/\sqrt{a_{r}}

另外當aspect ratio為1時,作者還增加一種scale的default box: 

S^{'}_{k}=\sqrt{S_{k}S_{k+1}}

因此,對於每個feature map cell而言,一共有6種default box。 

可以看出這種default box在不同的feature層有不同的scale,在同一個feature層又有不同的aspect ratio,因此基本上可以覆蓋輸入影象中的各種形狀和大小的object!

正負樣本

prior box和 grount truth box 按照IOU(JaccardOverlap)進行匹配,匹配成功則這個prior box就是positive example(正樣本),如果匹配不上,就是negative example(負樣本),顯然這樣產生的負樣本的數量要遠遠多於正樣本。這裡將前向loss進行排序,選擇最高的num_sel個prior box序號集合 D。那麼如果Match成功後的正樣本序號集合P。那麼最後正樣本集為 P-D\cap P,負樣本集為 D-D\cap P同時可以通過規範num_sel的數量(是正樣本數量的三倍)來控制使得最後正、負樣本的比例在 1:3 左右。

jaccard overlap 就是交併比 ,也就是IOU

正樣本:

我們已經在圖上畫出了prior box,同時也有了ground truth,那麼下一步就是將prior box匹配到ground truth上。值得注意的是先是從groudtruth box出發給每個groudtruth box找到了最匹配的prior box放入候選正樣本集,然後再從prior box出發為prior box集中尋找與groundtruth box滿足IOU>0.5IOU>0.5的一個IOU最大的prior box(如果有的話)放入候選正樣本集,這樣顯然就增大了候選正樣本集的數量。

負樣本:

在生成一系列的 prior boxes 之後,會產生很多個符合 ground truth box 的 positive boxes(候選正樣本集),但同時,不符合 ground truth boxes 也很多,而且這個 negative boxes(候選負樣本集),遠多於 positive boxes。這會造成 negative boxes、positive boxes 之間的不均衡。訓練時難以收斂。

      因此,本文采取,先將每一個物體位置上對應 predictions(prior boxes)loss 進行排序。 對於候選正樣本集:選擇最高的幾個prior box與正樣本集匹配(box索引同時存在於這兩個集合裡則匹配成功),匹配不成功則刪除這個正樣本(因為這個正樣本不在難例裡已經很接近ground truth box了,不需要再訓練了);對於候選負樣本集:選擇最高的幾個prior box與候選負樣本集匹配,匹配成功則作為負樣本。

         這就是一個難例挖掘的過程,舉個例子,假設在這8732個prior box裡,經過FindMatches後得到候選正樣本P個,候選負樣本那就有8732−P個。將prior box的prediction loss按照從大到小順序排列後選擇最高的M個prior box。如果這P個候選正樣本里有a個box在這M個prior box裡,將這a個box從候選正樣本集中踢出去。如果這8732−P個候選負樣本集中包含的8732−P有M−a個在這M個prior box,則將這M−a個候選負樣本作為負樣本。SSD演算法中通過這種方式來保證 positives、negatives 的比例。實際程式碼中有三種負樣本挖掘方式:

Data augmentation

本文同時對訓練資料做了 data augmentation,資料增廣。

每一張訓練影象,隨機的進行如下幾種選擇:

  • 使用原始的影象
  • 隨機取樣多個 patch(CropImage),與物體之間最小的 jaccard overlap 為:0.1,0.3,0.5,0.7 與 0.9

取樣的 patch 是原始影象大小比例是 [0.3,1.0],aspect ratio 在 0.5 或 2。

當 groundtruth box 的 中心(center)在取樣的 patch 中且在取樣的 patch中 groundtruth box面積大於0時,我們保留CropImage。

在這些取樣步驟之後,每一個取樣的 patch 被 resize 到固定的大小,並且以 0.5 的概率隨機的 水平翻轉(horizontally flipped,翻轉不翻轉看prototxt,預設不翻轉)

這樣一個樣本被諸多batch_sampler取樣器取樣後會生成多個候選樣本,然後從中隨機選一個樣本送人網路訓練

LOSS

       和Faster RCNN的基本一樣,由分類和迴歸兩部分組成,可以參考Faster RCNN,這裡不細講。總之,迴歸部分的loss是希望預測的box和prior box的差距儘可能跟ground truth和prior box的差距接近,這樣預測的box就能儘量和ground truth一樣。

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

上面得到的8732個目標框經過Jaccard Overlap篩選剩下幾個了;其中不滿足的框標記為負數,其餘留下的標為正數框。緊隨其後:

定位損失是預測框L與真實框g之間的平滑l_{1}l損失,置信損失是softmax的多分類置信度。先學習重合度高的框的位置資訊在學習類別資訊。

網路結構

    SSD的結構在VGG16網路的基礎上進行修改,訓練時同樣為conv1_1,conv1_2,conv2_1,conv2_2,conv3_1,conv3_2,conv3_3,conv4_1,conv4_2,conv4_3,conv5_1,conv5_2,conv5_3(512),fc6經過3*3*1024的卷積(原來VGG16中的fc6是全連線層,這裡變成卷積層,下面的fc7層同理),fc7經過1*1*1024的卷積,conv6_1,conv6_2(對應上圖的conv8_2),conv7_1,conv7_2,conv,8_1,conv8_2,conv9_1,conv9_2,loss。然後一方面:針對conv4_3(4),fc7(6),conv6_2(6),conv7_2(6),conv8_2(4),conv9_2(4)(括號裡數字是每一層選取的default box種類)中的每一個再分別採用兩個3*3大小的卷積核進行卷積,這兩個卷積核是並列的(括號裡的數字代表prior box的數量,可以參考Caffe程式碼,所以上圖中SSD結構的倒數第二列的數字8732表示的是所有prior box的數量,是這麼來的38*38*4+19*19*6+10*10*6+5*5*6+3*3*4+1*1*4=8732)。

知道prior  box 如何產生的,下面分析如何使用。以conv4_3為例:

在conv4_3 feature map網路pipeline分為了3條線路

  1. 經過一次batch norm+一次卷積後,生成了[1, num_class*num_priorbox, layer_height, layer_width]大小的feature用於softmax分類目標和非目標(其中num_class是目標類別,SSD 300中num_class = 21)
  2. 經過一次batch norm+一次卷積後,生成了[1, 4*num_priorbox, layer_height, layer_width]大小的feature用於bounding box regression(即每個點一組[dxmin,dymin,dxmax,dymax])
  3. 生成了[1, 2, 4*num_priorbox]大小的prior box blob,其中2個channel分別儲存prior box的4個點座標和對應的4個variance

縮排後續通過softmax分類+bounding box regression即可從priox box中預測到目標,熟悉Faster RCNN的讀者應該對上述過程應該並不陌生。其實pribox box的與Faster RCNN中的anchor非常類似,都是目標的預設框,沒有本質的差異。區別是每個位置的prior box一般是4~6個,少於Faster RCNN預設的9個anchor;同時prior box是設定在不同尺度的feature maps上的,而且大小不同。 縮排還有一個細節就是上面prototxt中的4個variance,這實際上是一種bounding regression中的權重。在圖4線路(2)中,網路輸出[dxmin,dymin,dxmax,dymax],其中的dxmin等可以參考這篇文章http://lib.csdn.net/article/deeplearning/61641

Permute,Flatten And Concat Layers

上面以conv4_3 feature map分析瞭如何檢測到目標的真實位置,但是SSD 300是使用包括conv4_3在內的共計6個feature maps一同檢測出最終目標的。在網路執行的時候顯然不能像圖6一樣:一個feature map單獨計算一次softmax socre+box regression(雖然原理如此,但是不能如此實現)。那麼多個feature maps如何協同工作?這時候就要用到Permute,Flatten和Concat這3種層了

Permute是SSD中自帶的層,上面conv4_3_norm_mbox_conf_perm的的定義。Permute相當於交換caffe blob中的資料維度。在正常情況下caffe blob的順序為: bottom blob = [batch_num, channel, height, width]

經過conv4_3_norm_mbox_conf_perm後的caffe blob為: top blob = [batch_num, height, width, channel]

而Flattlen和Concat層都是caffe自帶層

那麼接下來以conv4_3和fc7為例分析SSD是如何將不同size的feature map組合在一起進行prediction。圖展示了conv4_3和fc7合併在一起的過程中caffe blob shape變化(其他層類似,考慮到圖片大小沒有畫出來,請腦補)。

對於conv4_3 feature map,conv4_3_norm_priorbox(priorbox層)設定了每個點共有4個prior box。由於SSD 300共有21個分類,所以conv4_3_norm_mbox_conf的channel值為num_priorbox * num_class = 4 * 21 = 84;而每個prior box都要回歸出4個位置變換量,所以conv4_3_norm_mbox_loc的caffe blob channel值為4 * 4 = 16。

fc7每個點有6個prior box,其他feature map同理。 經過一系列圖7展示的caffe blob shape變化後,最後拼接成mbox_conf和mbox_loc。而mbox_conf後接reshape,再進行softmax(為何在softmax前進行reshape,Faster RCNN有提及)。 最後這些值輸出detection_out_layer,獲得檢測結果 

訓練過程

訓練過程中的 prior boxes 和 ground truth boxes 的匹配,基本思路是:讓每一個 prior box 迴歸並且到 ground truth box,這個過程的調控我們需要損失層的幫助,他會計算真實值和預測值之間的誤差,從而指導學習的走向。