深度學習 SSD的理解和細節分析

2021-09-24 08:21:36 字數 3779 閱讀 6030

ssd github:請選擇分支 ssd

ssd *****:arxiv.org/abs/1512.02…

對於ssd來說,最有新意的就是它的多尺度特徵,而整個**中調整頻度最高的應該是它的prior_box,我們就從這些方面來分享一下我自己的理解。

##多尺度 先說一下多尺度特徵。在之前的faster-rcnn中,特徵向量都是從最後一層的feature maps上得到的,對於這種單一的特徵層而言,感受野是十分有限的,沒有完全利用好前面幾級的特徵網路。在ssd中,作者從conv4_3開始,利用多級feature maps的組合作為分類和回歸的依據,達到了**中提到的多尺度的效果。 借用**中的一張圖來說明,作者是拿yolo和ssd做的對比:

可以看出ssd 的特徵是從不同的卷積層提取出來(上圖紅線),進行組合再進行回歸和分類,而yolo只有一層,在yolo之後的版本中也借鑑了 ssd的這種多尺度的思想來提高map。也就是說,ssd就是faster-rcnn和yolo中做了一次的分類和檢測過程放在不同的影象大小上做了多次。

##prior_box 知道了ssd的特徵是從不同尺度上提取的,那麼**中所說的8732 boxes又是怎麼來的呢?用下面這張表來告訴你。

name

out_size

prior_box_num

total_num

conv4-3

38x38

45776

fc719x19

62166

conv5-2

10x10

6600

conv7-2

5x56

150conv8-2

3x36

36conv9-2

1x14

48732

和 faster-rcnn一樣,ssd也是特徵圖上的每乙個點對應一組預選框。然後每一層中每乙個點對應的prior box的個數,是由priorbox這一層的配置檔案決定的。拿conv4-3對應的priorbox來說,caffe的模型配置檔案如下:

那麼ssd是怎麼生成對應的四個priorbox的呢? 框的生成過程大概分為下面三種方式:

先以min_size為寬高生成乙個框。

如果存在max_size則用sqrt(min_size_ * max_size_),生成乙個框。

然後根據aspect_ratio,再去生成。如上面的配置檔案,aspect_ratio=2,那麼會自動的再新增乙個aspect_ratiod = 1/2,然後根據下面的計算方法:

分別生成兩個框,乙個對應 ar = 2 乙個對應 ar= 1/2。

直觀點說,就是min_size和max_size會分別生成乙個正方形的框,aspect_ratio引數會生成2個長方形的框。所以輸出框的個數 :

prior_box_num = count(min_size)*1+count(max_size)*1+count(aspect_ratio)*2。

ps:min_size是必須要有的引數,否則不會進入對應的框的生成過程。**跟實際**是有一些出入的,git上也有人在討論這個,基本都選擇無視**。。。

這裡還有乙個比較關鍵的引數,就是step,在conv4-3中設定為8,這個又是怎麼來的呢?還是用乙個表來看一下:

name

out_size

cal_scale

real_scale

conv4-3

38x38

7.88

fc719x19

15.78

16conv5-2

10x10

3032

conv7-2

5x560

64conv8-2

3x3100

100conv9-2

1x1300

300 cal_scale = 300/out_size 實際就是 原圖與特徵圖 大小的比值,比如conv4-3 width = 38 ,輸入的大小為300,那麼scale=7.8,所以這裡設定的step=8。**中實現如下:

這一部分的計算過程可以在 prior_box_layer.cpp的forward_cpu中看到。

##特徵的錶出形式 如果你看了ssd的網路結構會發現,每乙個 conv***x_mbox_loc 或者 conv***x_mbox_conf後面都會跟乙個permute+flatten layer,如下圖:

這是在幹什麼呢? 使用caffe的同學都知道 ,caffe的資料結構是 nchw的形式(n:樣本個數, c:通道數,h:高,w:寬),而ssd的 xx_conf 和 xx_loc層的輸出,是用通道來儲存特徵向量的,所以這裡需要將通道數調整到最後,也就是 permute所做的事情,通過該層後,資料的順序被換成了 nhwc,再通過 flatten拉成一列。

這裡還有還是要說一下 xx_loc 和 xx_conf 層的輸出通道的規則,xx_loc層是用來回歸框的,所以需要4個座標資訊,而xx_conf是用來做分類的,所以需要class_num個資訊,同時每個點會有多個prior_box ,我們令k = count(prior_box),那麼相應的xx_loc的輸出的通道個數應為4*k,而xx_conf的輸出通道個數應為class_num*k,作為驗證,我們還是看一下針對於voc的模型的引數設定,

還是看conv4_3,這一層對應了4個prior_box ,voc的分類個數是21(20個分類+1個背景),所以對應的conv4_3_norm_mbox_loc 的num output = 16 = 4*4 ,而 conf的 num_output = 84 = 21*4。所以,如果針對的是自己的訓練集,一定要記著修改 xx_conf的輸出通道數。

其實簡單點理解,就是ssd的最後幾層的輸出資訊都是儲存在channel這一維度的,而乙個loc+conf+prior的模組可以認為等效於乙個 faster-rcnn的最後的回歸+分類過程,通過將這些子模組的特徵拼接起來,得到一組特徵向量,達到提取多尺度特徵的目的(多個f-rcnn同時工作於同一的不同尺度上)。

#####再看一下為什麼乙個特徵點要對應幾個prior_box。 原圖中的某乙個片區域,在經過幾層的提取後,會抽象成特徵圖上的乙個點,那麼多對於多個prior_box而言,他們對應的都是同一組資訊,那麼多個prior_box的意義是什麼呢?看下圖:

該圖只是示意作用,我假設某一層的特徵輸出中的乙個點,在原圖中的感受野剛好是上圖左上角的區域,可以看出卡片遮擋了筆的部分特徵(橙色和藍色的框是我標註上去的,2根藍線是示意作用,可以忽略),如果沒有多個prioro_box的時候,這種場景就無法正確分類,要麼認為是卡片,要麼認為是筆。這時候多個prior_box的價值就來了,因為多個框都會輸出自己的座標回歸和分類,它們會去關注自己對應的特徵,然後不同的框給出不同的分類得分,個人覺得有點類似於乙個attention的結構。

##最後還是要提一下ssd的資料增強 ssd的資料增強有很多,隨機的剪裁,放縮,亮度,飽和度的調整,等等。引數也基本是見名知意的,所以最好自己跟著**看一下比較有效。如果自己需要做資料增強不妨學習一下他的用法。 這裡推薦乙個 git:

這個git的ssd版本是可以在 windows上跑的,這樣就能用宇宙最強ide——vs一步一步的跟著看的變化了。

基於深度學習的目標檢測演算法 SSD

ssd single shot multibox detector 問題引入 目前,常見的目標檢測演算法,如faster r cnn,存在著速度慢的缺點。該 提出的ssd方法,不僅提高了速度,而且提高了準確度。ssd 該 的核心思想 該 的主要貢獻 1.提出了ssd目標檢測方法,在速度上,比之前最快...

基於深度學習的目標檢測演算法 SSD

ssd single shot multibox detector 問題引入 目前,常見的目標檢測演算法,如faster r cnn,存在著速度慢的缺點。該 提出的ssd方法,不僅提高了速度,而且提高了準確度。ssd 該 的核心思想 該 的主要貢獻 1.提出了ssd目標檢測方法,在速度上,比之前最快...

《深度學習筆記》 loss函式的學習和理解

在南溪看來,loss函式是對目標target和 prediction之間的一種距離度量的公式 自身不變性指的是 當 prediction target時,loss函式的值為0 在數學上,我們可以認為是對映l ll的l ll函式矩陣為對稱矩陣 這一點是從蔡老師對 svm核函式有效性的證明 的論述中學習...