深度學習筆記(七)SSD 論文閱讀筆記簡化

一. 算法概述

本文提出的SSD算法是一種直接預測目標類別和 bounding box 的多目標檢測算法。與 faster rcnn相比,該算法沒有生成 proposal 的過程,這就極大提升了檢測速度。針對不一樣大小的目標檢測,傳統的作法是先將圖像轉換成不一樣大小(圖像金字塔),而後分別檢測,最後將結果綜合起來(NMS)。而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層。算法

二. Default box

文章的核心之一是做者同時採用 lower 和 upper 的 feature map 作檢測。如圖Fig 1 所示,這裏假定有 8×8 和 4×4 兩種不一樣尺度的 feature map。第一個概念是feature map cell,feature map cell 是指 feature map 中每個小格子,如圖中分別有 64 和 16 個 cell。另外有一個概念:default box,是指在feature map的每一個小格(cell)上都有一系列固定大小的box,以下圖有4個(下圖中的虛線框,仔細看格子的中間有比格子還小的一個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卷積時卷積核的個數,包含兩部分:數量 c*k*m*n 是 confidence 輸出,表示每一個 default box 的 是某一類別的 confidence;數量4*k*m*n是 localization 輸出,表示每一個default box 迴歸後的座標)。訓練中還有一個東西:prior box,是指實際中選擇的 default box(你能夠認爲 default box 是抽象類,而 prior box 是具體實例)。訓練中對於每一個圖像樣本,須要先將 prior box 與 ground truth box 作匹配,匹配成功說明這個 prior box 所包含的是個目標,但離完整目標的 ground truth box 還有段距離,訓練的目的是保證default box 的分類 confidence 的同時將 prior box 儘量迴歸到 ground truth box。 舉個列子:假設一個訓練樣本中有2個ground truth box,全部的feature map中獲取的prior box一共有8732個。那個可能分別有十、20個prior box能分別與這2個ground truth box匹配上。訓練的損失包含定位損失和迴歸損失兩部分。網絡

做者的實驗代表default box的shape數量越多,效果越好。框架

這裏用到的 default box 和 Faster RCNN 中的 anchor 很像,在 Faster RCNN 中 anchor 只用在最後一個卷積層,可是在本文中,default box 是應用在多個不一樣層的feature map上。ide

那麼default box的 scale(大小)和aspect ratio(橫縱比)要怎麼定呢?假設咱們用 m 個 feature maps 作預測,那麼對於每一個featuer map而言其 default box 的 scale 是按如下公式計算的: 函數

 $\vee$學習

$S_k=S_{min} + \frac{S_{max} - S_{min}}{m-1}(k-1),  k\in{[1, m]}$google

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

至於aspect ratio,用$a_r$表示爲下式:注意這裏一共有5種aspect ratio spa

$a_r = \{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!

(訓練本身的樣本的時候能夠在 FindMatch() 以後檢查是否能覆蓋了全部的 ground truth box,其實是全覆蓋了,由於會至少找一個最大匹配

 源代碼中的 ssd_pascal.py 設計了上面幾個參數值,caffe 源碼 prior_box_layer.cpp 中Forward_cpu()實現。

最後會獲得(38*38*4 + 19*19*6 + 10*10*6 + 5*5*6 + 3*3*4 + 1*1*4)= 8732 個 prior box。

                                                               Fig.2 SSD 框架

三. 正負樣本

prior box 和 grount truth box 按照 IOU(JaccardOverlap)進行匹配,匹配成功則這個prior box就是 positive example(正樣本),若是匹配不上,就是negative example(負樣本),顯然這樣產生的負樣本的數量要遠遠多於正樣本。這裏默認作了難例挖掘:簡單描述起來就是,將全部的匹配不上的 negative prior box 按照前向 loss 進行排序,選擇最高的 num_sel 個 prior box 序號集合做爲最終的負樣本集。這裏就能夠利用 num_sel 來控制最後正、負樣本的比例在 1 : 3 左右。

 

                                                Fig.3 positive and negtive sample VS ground_truth box

1.正樣本得到

咱們已經在圖上畫出了prior box,同時也有了ground truth,那麼下一步就是將prior box匹配到ground truth上,這是在 src/caffe/utlis/bbox_util.cpp 的 FindMatches 以及子函數MatchBBox函數裏完成的。具體的:先從 groudtruth box 出發,爲每一個 groudtruth box 找到最匹配的一個 prior box 放入候選正樣本集;而後再嘗試從剩下的每一個 prior box 出發,尋找與 groundtruth box 知足 IOU>0.5IOU>0.5 的 最大匹配,若是找到了這樣的一個匹配結果就放入候選正樣本集。這個作的目的是保證每一個 groundtruth box 都至少有一個匹配正樣本。

2.負樣本獲

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

所以,本文采起,先將每個物體位置上對應 predictions(prior boxes)loss 進行排序。 對於候選正樣本集:選擇 loss 最高的幾個prior box集合與候選正樣本集進行匹配(box索引同時存在於這兩個集合裏則匹配成功),匹配不成功則刪除這個正樣本(由於這個正樣本不在難例裏已經很接近ground truth box了,不須要再訓練了);對於候選負樣本集:選擇 loss 最高的幾個 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$ 有 $b$ 個在這 $M$ 個prior box,則將這 $b$ 個候選負樣本做爲最終的負樣本。總歸一句話就是:選擇 loss 值高的難例做爲最後的負樣本參與 loss 反傳計算。SSD算法中經過這種方式來保證 positives、negatives 的比例。實際代碼中有三種負樣本挖掘方式:

若是選擇HARD_EXAMPLE方式(源於論文Training Region-based Object Detectors with Online Hard Example Mining),則默認$M = 64$,因爲沒法控制正樣本數量,這種方式就有點相似於分類、迴歸按比重不一樣交替訓練了。
若是選擇MAX_NEGATIVE方式,則$M = P*neg\_pos\_ratio$,這裏當$neg\_pos\_ratio = 3$的時候,就是論文中的正負樣本比例1:3了。

enum MultiBoxLossParameter_MiningType {
  MultiBoxLossParameter_MiningType_NONE = 0, MultiBoxLossParameter_MiningType_MAX_NEGATIVE = 1, MultiBoxLossParameter_MiningType_HARD_EXAMPLE = 2 };

3.Data augmentation

本文同時對訓練數據作了 data augmentation,數據增廣。

每一張訓練圖像,隨機的進行以下幾種選擇:

  • 使用原始的圖像
  • 隨機採樣多個 patch(CropImage),與物體之間最小的 jaccard overlap 爲:0.1,0.3,0.5,0.7 與 0.9

採樣的 patch 是原始圖像大小比例是 [0.31.0],aspect ratio 在 0.5 或 2。

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

在這些採樣步驟以後,每個採樣的 patch 被 resize 到固定的大小,而且以 0.5 的機率隨機的 水平翻轉(horizontally flipped,翻轉不翻轉看prototxt,默認不翻轉)

這樣一個樣本被諸多batch_sampler採樣器採樣後會生成多個候選樣本,而後從中隨機選一個樣本送人網絡訓練。

四. 網絡結構

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),這兩個3*3的卷積核一個是用來作localization的(迴歸用,若是prior box是6個,那麼就有6*4=24個這樣的卷積核,卷積後map的大小和卷積前同樣,由於pad=1,下同),另外一個是用來作confidence的(分類用,若是prior box是6個,VOC的object類別有20個,那麼就有6*(20+1)=126個這樣的卷積核)。以下圖是conv6_2的localizaiton的3*3卷積核操做,卷積核個數是24(6*4=24,因爲pad=1,因此卷積結果的map大小不變,下同):這裏的permute層就是交換的做用,好比你卷積後的維度是32×24×19×19,那麼通過交換層後就變成32×19×19×24,順序變了而已。而flatten層的做用就是將32×19×19×24變成32*8664,32是batchsize的大小。另外一方面結合conv4_3(4),fc7(6),conv6_2(6),conv7_2(6),conv8_2(4),conv9_2(4)中的每個和數據層(ground truth boxes)通過priorBox層生成prior box。

通過上述兩個操做後,對每一層feature的處理就結束了。對前面所列的5個卷積層輸出都執行上述的操做後,就將獲得的結果合併:採用Concat,相似googleNet的Inception操做,是通道合併而不是數值相加。 

 

                                                           Fig.5 SSD 流程

 

 

損失函數方面:和Faster RCNN的基本同樣,由分類和迴歸兩部分組成,能夠參考Faster RCNN,這裏不細講。總之,迴歸部分的loss是但願預測的box和prior box的差距儘量跟ground truth和prior box的差距接近,這樣預測的box就能儘可能和ground truth同樣。

 

上面獲得的8732個目標框通過Jaccard Overlap篩選剩下幾個了;其中不知足的框標記爲負數,其他留下的標爲正數框。緊隨其後:

 

 

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

SSD 訓練的目標函數(training objective)源自於 MultiBox 的目標函數,可是本文將其拓展,使其能夠處理多個目標類別。具體過程是咱們會讓每個 prior box 通過Jaccard係數計算和真實框的類似度,閾值只有大於 0.5 的才能夠列爲候選名單;假設選擇出來的是N個匹配度高於百分之五十的框吧,咱們令 表示第 i 個默認框,j 表示第 j 個真實框,p表示第p個類。那麼$x_{ij}^p$表示 第 i 個 prior box 與 類別 p 的 第 j 個 ground truth box 相匹配的Jaccard係數,若不匹配的話,則$x_{ij}^p=0$。總的目標損失函數(objective loss function)就由 localization loss(loc) 與 confidence loss(conf) 的加權求和:

  • N 是與 ground truth box 相匹配的 prior boxes 個數
  • localization loss(loc) 是 Fast R-CNN 中 Smooth L1 Loss,用在 predict box(l) 與 ground truth box(g) 參數(即中心座標位置,width、height)中,迴歸 bounding boxes 的中心位置,
    以及 width、height
  • confidence loss(conf) 是 Softmax Loss,輸入爲每一類的置信度 c
  • 權重項 α,可在protxt中設置 loc_weight,默認設置爲 1

五.使用注意

1. 使用batch_sampler作data argument時要注意是否crop的樣本只包含目標很小一部分。

2.檢查對於你的樣原本說迴歸和分類問題哪一個更難,以此調整multibox_loss_param中loc_weight進行訓練。

3.正負樣本比例,HARD_EXAMPLE方式默認只取64個最高predictions loss來從中尋找負樣本,檢查你的樣本集中正負樣本比例是否合適。

相關文章
相關標籤/搜索