在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

全面探究SSD原理與實現(xiàn)

新機器視覺 ? 來源:機器學(xué)習(xí)算法全棧工程師 ? 作者:機器學(xué)習(xí)算法全棧 ? 2021-04-26 13:59 ? 次閱讀

前言

目標(biāo)檢測近年來已經(jīng)取得了很重要的進展,主流的算法主要分為兩個類型(參考RefineDet):

(1)two-stage方法,如R-CNN系算法,其主要思路是先通過啟發(fā)式方法(selective search)或者CNN網(wǎng)絡(luò)(RPN)產(chǎn)生一系列稀疏的候選框,然后對這些候選框進行分類與回歸,two-stage方法的優(yōu)勢是準(zhǔn)確度高;

(2)one-stage方法,如Yolo和SSD,其主要思路是均勻地在圖片的不同位置進行密集抽樣,抽樣時可以采用不同尺度和長寬比,然后利用CNN提取特征后直接進行分類與回歸,整個過程只需要一步,所以其優(yōu)勢是速度快,但是均勻的密集采樣的一個重要缺點是訓(xùn)練比較困難,這主要是因為正樣本與負樣本(背景)極其不均衡(參見Focal Loss),導(dǎo)致模型準(zhǔn)確度稍低。不同算法的性能如圖1所示,可以看到兩類方法在準(zhǔn)確度和速度上的差異。

圖1 不同檢測算法的性能對比

本文講解的是SSD算法,其英文全名是Single Shot MultiBox Detector,名字取得不錯,Single shot指明了SSD算法屬于one-stage方法,MultiBox指明了SSD是多框預(yù)測。在上一篇文章中我們已經(jīng)講了Yolo算法,從圖1也可以看到,SSD算法在準(zhǔn)確度和速度(除了SSD512)上都比Yolo要好很多。圖2給出了不同算法的基本框架圖,對于Faster R-CNN,其先通過CNN得到候選框,然后再進行分類與回歸,而Yolo與SSD可以一步到位完成檢測。

相比Yolo,SSD采用CNN來直接進行檢測,而不是像Yolo那樣在全連接層之后做檢測。其實采用卷積直接做檢測只是SSD相比Yolo的其中一個不同點,另外還有兩個重要的改變,一是SSD提取了不同尺度的特征圖來做檢測,大尺度特征圖(較靠前的特征圖)可以用來檢測小物體,而小尺度特征圖(較靠后的特征圖)用來檢測大物體;

二是SSD采用了不同尺度和長寬比的先驗框(Prior boxes, Default boxes,在Faster R-CNN中叫做錨,Anchors)。Yolo算法缺點是難以檢測小目標(biāo),而且定位不準(zhǔn),但是這幾點重要改進使得SSD在一定程度上克服這些缺點。下面我們詳細講解SDD算法的原理,并最后給出如何用TensorFlow實現(xiàn)SSD算法。

圖2 不同算法的基本框架圖 設(shè)計理念

SSD和Yolo一樣都是采用一個CNN網(wǎng)絡(luò)來進行檢測,但是卻采用了多尺度的特征圖,其基本架構(gòu)如圖3所示。下面將SSD核心設(shè)計理念總結(jié)為以下三點:

圖3 SSD基本框架

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

所謂多尺度采用大小不同的特征圖,CNN網(wǎng)絡(luò)一般前面的特征圖比較大,后面會逐漸采用stride=2的卷積或者pool來降低特征圖大小,這正如圖3所示,一個比較大的特征圖和一個比較小的特征圖,它們都用來做檢測。

這樣做的好處是比較大的特征圖來用來檢測相對較小的目標(biāo),而小的特征圖負責(zé)檢測大目標(biāo),如圖4所示,8x8的特征圖可以劃分更多的單元,但是其每個單元的先驗框尺度比較小。

圖4 不同尺度的特征圖

(2)采用卷積進行檢測

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

(3)設(shè)置先驗框

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

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

圖5 SSD的先驗框

SSD的檢測值也與Yolo不太一樣。對于每個單元的每個先驗框,其都輸出一套獨立的檢測值,對應(yīng)一個邊界框,主要分為兩個部分。第一部分是各個類別的置信度或者評分,值得注意的是SSD將背景也當(dāng)做了一個特殊的類別,如果檢測目標(biāo)共有 個類別,SSD其實需要預(yù)測 個置信度值,其中第一個置信度指的是不含目標(biāo)或者屬于背景的評分。

后面當(dāng)我們說 個類別置信度時,請記住里面包含背景那個特殊的類別,即真實的檢測類別只有 個。在預(yù)測過程中,置信度最高的那個類別就是邊界框所屬的類別,特別地,當(dāng)?shù)谝粋€置信度值最高時,表示邊界框中并不包含目標(biāo)。

第二部分就是邊界框的location,包含4個值 ,分別表示邊界框的中心坐標(biāo)以及寬高。但是真實預(yù)測值其實只是邊界框相對于先驗框的轉(zhuǎn)換值(paper里面說是offset,但是覺得transformation更合適,參見R-CNN)。先驗框位置用 表示,其對應(yīng)邊界框用 lbd$ 的轉(zhuǎn)換值:

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

然而,在SSD的Caffe源碼實現(xiàn)中還有trick,那就是設(shè)置variance超參數(shù)來調(diào)整檢測值,通過bool參數(shù)variance_encoded_in_target來控制兩種模式,當(dāng)其為True時,表示variance被包含在預(yù)測值中,就是上面那種情況。但是如果是False(大部分采用這種方式,訓(xùn)練更容易?),就需要手動設(shè)置超參數(shù)variance,用來對 的4個值進行放縮,此時邊界框需要這樣解碼:

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

網(wǎng)絡(luò)結(jié)構(gòu)

SSD采用VGG16作為基礎(chǔ)模型,然后在VGG16的基礎(chǔ)上新增了卷積層來獲得更多的特征圖以用于檢測。SSD的網(wǎng)絡(luò)結(jié)構(gòu)如圖5所示。上面是SSD模型,下面是Yolo模型,可以明顯看到SSD利用了多尺度的特征圖做檢測。模型的輸入圖片大小是 (還可以是 ,其與前者網(wǎng)絡(luò)結(jié)構(gòu)沒有差別,只是最后新增一個卷積層,本文不再討論)。

圖5 SSD網(wǎng)絡(luò)結(jié)構(gòu)

采用VGG16做基礎(chǔ)模型,首先VGG16是在ILSVRC CLS-LOC數(shù)據(jù)集預(yù)訓(xùn)練。然后借鑒了DeepLab-LargeFOV,分別將VGG16的全連接層fc6和fc7轉(zhuǎn)換成 卷積層 conv6和 卷積層conv7,同時將池化層pool5由原來的stride=2的 變成stride=1的 (猜想是不想reduce特征圖大小),為了配合這種變化,采用了一種Atrous Algorithm。

其實就是conv6采用擴展卷積或帶孔卷積(Dilation Conv),其在不增加參數(shù)與模型復(fù)雜度的條件下指數(shù)級擴大卷積的視野,其使用擴張率(dilation rate)參數(shù),來表示擴張的大小,如下圖6所示,(a)是普通的 卷積,其視野就是 ,(b)是擴張率為2,此時視野變成 ,(c)擴張率為4時,視野擴大為 ,但是視野的特征更稀疏了。Conv6采用 大小但dilation rate=6的擴展卷積。

圖6 擴展卷積

然后移除dropout層和fc8層,并新增一系列卷積層,在檢測數(shù)據(jù)集上做finetuing。

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

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

從后面新增的卷積層中提取Conv7,Conv8_2,Conv9_2,Conv10_2,Conv11_2作為檢測所用的特征圖,加上Conv4_3層,共提取了6個特征圖,其大小分別是 ,但是不同特征圖設(shè)置的先驗框數(shù)目不同(同一個特征圖上每個單元設(shè)置的先驗框是相同的,這里的數(shù)目指的是一個單元的先驗框數(shù)目)。先驗框的設(shè)置,包括尺度(或者說大?。┖烷L寬比兩個方面。對于先驗框的尺度,其遵守一個線性遞增規(guī)則:隨著特征圖大小降低,先驗框尺度線性增加:

其中 指的特征圖個數(shù),但卻是 ,因為第一層(Conv4_3層)是單獨設(shè)置的, 表示先驗框大小相對于圖片的比例,而 和 表示比例的最小值與最大值,paper里面取0.2和0.9。對于第一個特征圖,其先驗框的尺度比例一般設(shè)置為 ,那么尺度為 。

對于后面的特征圖,先驗框尺度按照上面公式線性增加,但是先將尺度比例先擴大100倍,此時增長步長為 ,這樣各個特征圖的 為 ,將這些比例除以100,然后再乘以圖片大小,可以得到各個特征圖的尺度為 ,這種計算方式是參考SSD的Caffe源碼。

綜上,可以得到各個特征圖的先驗框尺度 。對于長寬比,一般選取 ,對于特定的長寬比,按如下公式計算先驗框的寬度與高度(后面的 均指的是先驗框?qū)嶋H尺度,而不是尺度比例):

默認情況下,每個特征圖會有一個 且尺度為 的先驗框,除此之外,還會設(shè)置一個尺度為 且 的先驗框,這樣每個特征圖都設(shè)置了兩個長寬比為1但大小不同的正方形先驗框。注意最后一個特征圖需要參考一個虛擬 來計算 。

因此,每個特征圖一共有 個先驗框 ,但是在實現(xiàn)時,Conv4_3,Conv10_2和Conv11_2層僅使用4個先驗框,它們不使用長寬比為 的先驗框。每個單元的先驗框的中心點分布在各個單元的中心,即 ,其中 為特征圖的大小。

得到了特征圖之后,需要對特征圖進行卷積得到檢測結(jié)果,圖7給出了一個 大小的特征圖的檢測過程。其中Priorbox是得到先驗框,前面已經(jīng)介紹了生成規(guī)則。檢測值包含兩個部分:類別置信度和邊界框位置,各采用一次 卷積來進行完成。

令 為該特征圖所采用的先驗框數(shù)目,那么類別置信度需要的卷積核數(shù)量為 ,而邊界框位置需要的卷積核數(shù)量為 。由于每個先驗框都會預(yù)測一個邊界框,所以SSD300一共可以預(yù)測 個邊界框,這是一個相當(dāng)龐大的數(shù)字,所以說SSD本質(zhì)上是密集采樣。

圖7 基于卷積得到檢測結(jié)果 訓(xùn)練過程

(1)先驗框匹配

在訓(xùn)練過程中,首先要確定訓(xùn)練圖片中的ground truth(真實目標(biāo))與哪個先驗框來進行匹配,與之匹配的先驗框所對應(yīng)的邊界框?qū)⒇撠?zé)預(yù)測它。在Yolo中,ground truth的中心落在哪個單元格,該單元格中與其IOU最大的邊界框負責(zé)預(yù)測它。但是在SSD中卻完全不一樣,SSD的先驗框與ground truth的匹配原則主要有兩點。

首先,對于圖片中每個ground truth,找到與其IOU最大的先驗框,該先驗框與其匹配,這樣,可以保證每個ground truth一定與某個先驗框匹配。通常稱與ground truth匹配的先驗框為正樣本(其實應(yīng)該是先驗框?qū)?yīng)的預(yù)測box,不過由于是一一對應(yīng)的就這樣稱呼了),反之,若一個先驗框沒有與任何ground truth進行匹配,那么該先驗框只能與背景匹配,就是負樣本。

一個圖片中g(shù)round truth是非常少的, 而先驗框卻很多,如果僅按第一個原則匹配,很多先驗框會是負樣本,正負樣本極其不平衡,所以需要第二個原則。第二個原則是:對于剩余的未匹配先驗框,若某個ground truth的 大于某個閾值(一般是0.5),那么該先驗框也與這個ground truth進行匹配。

這意味著某個ground truth可能與多個先驗框匹配,這是可以的。但是反過來卻不可以,因為一個先驗框只能匹配一個ground truth,如果多個ground truth與某個先驗框 大于閾值,那么先驗框只與IOU最大的那個ground truth進行匹配。

第二個原則一定在第一個原則之后進行,仔細考慮一下這種情況,如果某個ground truth所對應(yīng)最大 小于閾值,并且所匹配的先驗框卻與另外一個ground truth的 大于閾值,那么該先驗框應(yīng)該匹配誰,答案應(yīng)該是前者,首先要確保某個ground truth一定有一個先驗框與之匹配。

但是,這種情況我覺得基本上是不存在的。由于先驗框很多,某個ground truth的最大 肯定大于閾值,所以可能只實施第二個原則既可以了,這里的TensorFlow版本就是只實施了第二個原則,但是這里的Pytorch兩個原則都實施了。圖8為一個匹配示意圖,其中綠色的GT是ground truth,紅色為先驗框,F(xiàn)P表示負樣本,TP表示正樣本。

圖8 先驗框匹配示意圖

盡管一個ground truth可以與多個先驗框匹配,但是ground truth相對先驗框還是太少了,所以負樣本相對正樣本會很多。為了保證正負樣本盡量平衡,SSD采用了hard negative mining,就是對負樣本進行抽樣,抽樣時按照置信度誤差(預(yù)測背景的置信度越小,誤差越大)進行降序排列,選取誤差的較大的top-k作為訓(xùn)練的負樣本,以保證正負樣本比例接近1:3。

(2)損失函數(shù)

訓(xùn)練樣本確定了,然后就是損失函數(shù)了。損失函數(shù)定義為位置誤差(locatization loss, loc)與置信度誤差(confidence loss, conf)的加權(quán)和:

其中 是先驗框的正樣本數(shù)量。這里 為一個指示參數(shù),當(dāng) 時表示第 個先驗框與第 個ground truth匹配,并且ground truth的類別為 。 為類別置信度預(yù)測值。 為先驗框的所對應(yīng)邊界框的位置預(yù)測值,而 是ground truth的位置參數(shù)。對于位置誤差,其采用Smooth L1 loss,定義如下:

由于 的存在,所以位置誤差僅針對正樣本進行計算。值得注意的是,要先對ground truth的 進行編碼得到 ,因為預(yù)測值 也是編碼值,若設(shè)置variance_encoded_in_target=True,編碼時要加上variance:

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

權(quán)重系數(shù) 通過交叉驗證設(shè)置為1。

(3)數(shù)據(jù)擴增

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

圖9 數(shù)據(jù)擴增方案

其它的訓(xùn)練細節(jié)如學(xué)習(xí)速率的選擇詳見論文,這里不再贅述。

預(yù)測過程

預(yù)測過程比較簡單,對于每個預(yù)測框,首先根據(jù)類別置信度確定其類別(置信度最大者)與置信度值,并過濾掉屬于背景的預(yù)測框。然后根據(jù)置信度閾值(如0.5)過濾掉閾值較低的預(yù)測框。對于留下的預(yù)測框進行解碼,根據(jù)先驗框得到其真實的位置參數(shù)(解碼后一般還需要做clip,防止預(yù)測框位置超出圖片)。

解碼之后,一般需要根據(jù)置信度進行降序排列,然后僅保留top-k(如400)個預(yù)測框。最后就是進行NMS算法,過濾掉那些重疊度較大的預(yù)測框。最后剩余的預(yù)測框就是檢測結(jié)果了。

性能評估

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

表1 SSD在不同數(shù)據(jù)集上的性能

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

表2 SSD與其它檢測算法的對比結(jié)果(在VOC2007數(shù)據(jù)集)

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

數(shù)據(jù)擴增技術(shù)很重要,對于mAP的提升很大;

使用不同長寬比的先驗框可以得到更好的結(jié)果;

表3 不同的trick組合對SSD的性能影響

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

表4 多尺度特征圖對SSD的影響 TensorFlow上的實現(xiàn)

SSD在很多框架上都有了開源的實現(xiàn),這里基于balancap的TensorFlow版本來實現(xiàn)SSD的Inference過程。這里實現(xiàn)的是SSD300,與paper里面不同的是,這里采用 。首先定義SSD的參數(shù):

self.ssd_params = SSDParams(img_shape=(300, 300), # 輸入圖片大小 num_classes=21, # 類別數(shù)+背景 no_annotation_label=21, feat_layers=[“block4”, “block7”, “block8”, “block9”, “block10”, “block11”], # 要進行檢測的特征圖name feat_shapes=[(38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1)], # 特征圖大小 anchor_size_bounds=[0.15, 0.90], # 特征圖尺度范圍 anchor_sizes=[(21., 45.), (45., 99.), (99., 153.), (153., 207.), (207., 261.), (261., 315.)], # 不同特征圖的先驗框尺度(第一個值是s_k,第2個值是s_k+1) anchor_ratios=[[2, .5], [2, .5, 3, 1. / 3], [2, .5, 3, 1. / 3], [2, .5, 3, 1. / 3], [2, .5], [2, .5]], # 特征圖先驗框所采用的長寬比(每個特征圖都有2個正方形先驗框) anchor_steps=[8, 16, 32, 64, 100, 300], # 特征圖的單元大小 anchor_offset=0.5, # 偏移值,確定先驗框中心 normalizations=[20, -1, -1, -1, -1, -1], # l2 norm prior_scaling=[0.1, 0.1, 0.2, 0.2] # variance )

然后構(gòu)建整個網(wǎng)絡(luò),注意對于stride=2的conv不要使用TF自帶的padding=“same”,而是手動pad,這是為了與Caffe一致:

def _built_net(self): “”“Construct the SSD net”“” self.end_points = {} # record the detection layers output self._images = tf.placeholder(tf.float32, shape=[None, self.ssd_params.img_shape[0], self.ssd_params.img_shape[1], 3]) with tf.variable_scope(“ssd_300_vgg”): # original vgg layers # block 1 net = conv2d(self._images, 64, 3, scope=“conv1_1”) net = conv2d(net, 64, 3, scope=“conv1_2”) self.end_points[“block1”] = net net = max_pool2d(net, 2, scope=“pool1”) # block 2 net = conv2d(net, 128, 3, scope=“conv2_1”) net = conv2d(net, 128, 3, scope=“conv2_2”) self.end_points[“block2”] = net net = max_pool2d(net, 2, scope=“pool2”) # block 3 net = conv2d(net, 256, 3, scope=“conv3_1”) net = conv2d(net, 256, 3, scope=“conv3_2”) net = conv2d(net, 256, 3, scope=“conv3_3”) self.end_points[“block3”] = net net = max_pool2d(net, 2, scope=“pool3”) # block 4 net = conv2d(net, 512, 3, scope=“conv4_1”) net = conv2d(net, 512, 3, scope=“conv4_2”) net = conv2d(net, 512, 3, scope=“conv4_3”) self.end_points[“block4”] = net net = max_pool2d(net, 2, scope=“pool4”) # block 5 net = conv2d(net, 512, 3, scope=“conv5_1”) net = conv2d(net, 512, 3, scope=“conv5_2”) net = conv2d(net, 512, 3, scope=“conv5_3”) self.end_points[“block5”] = net print(net) net = max_pool2d(net, 3, stride=1, scope=“pool5”) print(net)

# additional SSD layers # block 6: use dilate conv net = conv2d(net, 1024, 3, dilation_rate=6, scope=“conv6”) self.end_points[“block6”] = net #net = dropout(net, is_training=self.is_training) # block 7 net = conv2d(net, 1024, 1, scope=“conv7”) self.end_points[“block7”] = net # block 8 net = conv2d(net, 256, 1, scope=“conv8_1x1”) net = conv2d(pad2d(net, 1), 512, 3, stride=2, scope=“conv8_3x3”, padding=“valid”) self.end_points[“block8”] = net # block 9 net = conv2d(net, 128, 1, scope=“conv9_1x1”) net = conv2d(pad2d(net, 1), 256, 3, stride=2, scope=“conv9_3x3”, padding=“valid”) self.end_points[“block9”] = net # block 10 net = conv2d(net, 128, 1, scope=“conv10_1x1”) net = conv2d(net, 256, 3, scope=“conv10_3x3”, padding=“valid”) self.end_points[“block10”] = net # block 11 net = conv2d(net, 128, 1, scope=“conv11_1x1”) net = conv2d(net, 256, 3, scope=“conv11_3x3”, padding=“valid”) self.end_points[“block11”] = net

# class and location predictions predictions = [] logits = [] locations = [] for i, layer in enumerate(self.ssd_params.feat_layers): cls, loc = ssd_multibox_layer(self.end_points[layer], self.ssd_params.num_classes, self.ssd_params.anchor_sizes[i], self.ssd_params.anchor_ratios[i], self.ssd_params.normalizations[i], scope=layer+“_box”) predictions.append(tf.nn.softmax(cls)) logits.append(cls) locations.append(loc) return predictions, logits, locations

對于特征圖的檢測,這里單獨定義了一個組合層ssd_multibox_layer,其主要是對特征圖進行兩次卷積,分別得到類別置信度與邊界框位置:

# multibox layer: get class and location predicitions from detection layer def ssd_multibox_layer(x, num_classes, sizes, ratios, normalization=-1, scope=“multibox”): pre_shape = x.get_shape().as_list()[1:-1] pre_shape = [-1] + pre_shape with tf.variable_scope(scope): # l2 norm if normalization 》 0: x = l2norm(x, normalization) print(x) # numbers of anchors n_anchors = len(sizes) + len(ratios) # location predictions loc_pred = conv2d(x, n_anchors*4, 3, activation=None, scope=“conv_loc”) loc_pred = tf.reshape(loc_pred, pre_shape + [n_anchors, 4]) # class prediction cls_pred = conv2d(x, n_anchors*num_classes, 3, activation=None, scope=“conv_cls”) cls_pred = tf.reshape(cls_pred, pre_shape + [n_anchors, num_classes]) return cls_pred, loc_pred

對于先驗框,可以基于numpy生成,定義在ssd_anchors.py文件中,結(jié)合先驗框與檢測值,對邊界框進行過濾與解碼:

classes, scores, bboxes = self._bboxes_select(predictions, locations)

這里將得到過濾得到的邊界框,其中classes, scores, bboxes分別表示類別,置信度值以及邊界框位置。

基于訓(xùn)練好的權(quán)重文件在https://pan.baidu.com/s/1snhuTsT下載,這里對SSD進行測試:

ssd_net = SSD()classes, scores, bboxes = ssd_net.detections()images = ssd_net.images()

sess = tf.Session()# Restore SSD model.ckpt_filename = ‘。/ssd_checkpoints/ssd_vgg_300_weights.ckpt’sess.run(tf.global_variables_initializer())saver = tf.train.Saver()saver.restore(sess, ckpt_filename)

img = cv2.imread(‘。/demo/dog.jpg’)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img_prepocessed = preprocess_image(img) # 預(yù)處理圖片,主要是歸一化和resizerclasses, rscores, rbboxes = sess.run([classes, scores, bboxes], feed_dict={images: img_prepocessed})rclasses, rscores, rbboxes = process_bboxes(rclasses, rscores, rbboxes) # 處理預(yù)測框,包括clip,sort,nms

plt_bboxes(img, rclasses, rscores, rbboxes) # 繪制檢測結(jié)果

詳細的代碼放在GitHub,https://github.com/xiaohu2015/DeepLearning_tutorials/tree/master/ObjectDetections/SSD上了,然后看一下一個自然圖片的檢測效果:

如果你想實現(xiàn)SSD的train過程,你可以參考附錄里面的Caffe,TensorFlow以及Pytorch實現(xiàn)。

小結(jié)

SSD在Yolo的基礎(chǔ)上主要改進了三點:多尺度特征圖,利用卷積進行檢測,設(shè)置先驗框。這使得SSD在準(zhǔn)確度上比Yolo更好,而且對于小目標(biāo)檢測效果也相對好一點。由于很多實現(xiàn)細節(jié)都包含在源碼里面,文中有描述不準(zhǔn)或者錯誤的地方在所難免,歡迎交流指正。

參考文獻

1.SSD: Single Shot MultiBox Detector,http://arxiv.org/pdf/1611.10012.pdf)

2.SSD Slide,https://www.cs.unc.edu/~wliu/papers/ssd_eccv2016_slide.pdf

3.SSD Caffe,https://github.com/weiliu89/caffe/tree/ssd

4.SSD TensorFlow,https://github.com/balancap/SSD-Tensorflow

5.SSD Pytorch,https://github.com/amdegroot/ssd.pytorch

6.leonardoaraujosantos Artificial Inteligence online book,https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/single-shot-detectors/ssd.html

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • SSD
    SSD
    +關(guān)注

    關(guān)注

    21

    文章

    2931

    瀏覽量

    118905
  • 源碼
    +關(guān)注

    關(guān)注

    8

    文章

    665

    瀏覽量

    30046

原文標(biāo)題:目標(biāo)檢測|SSD原理與實現(xiàn)

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    明遠智睿SSD2351核心板在語音對講與HMI領(lǐng)域的創(chuàng)新應(yīng)用

    在現(xiàn)代智能設(shè)備中,語音對講和HMI(人機界面)作為重要的交互方式,直接影響著用戶體驗。明遠智睿SSD2351核心板憑借其獨特的硬件特性和豐富接口,在這兩個領(lǐng)域實現(xiàn)了諸多創(chuàng)新應(yīng)用。 在語音對講方面
    發(fā)表于 04-16 10:46

    明遠智睿SSD2351核心板助力智能監(jiān)控系統(tǒng)升級

    攝像頭云臺的轉(zhuǎn)動速度,實現(xiàn)對監(jiān)控區(qū)域的靈活監(jiān)控。 明遠智睿SSD2351核心板從視頻采集、處理、傳輸?shù)椒治龈鱾€環(huán)節(jié),為智能監(jiān)控系統(tǒng)提供了全面的性能提升方案。它憑借自身強大的硬件性能和豐富接口,助力智能監(jiān)控系統(tǒng)
    發(fā)表于 04-14 18:28

    多流技術(shù):不同壽命數(shù)據(jù)存在SSD的不同塊

    根據(jù)數(shù)據(jù)的壽命將數(shù)據(jù)存放在SSD的不同塊內(nèi)可以顯著提高SSD的GC效率、減少WAF、提高SSD的壽命和性能。
    的頭像 發(fā)表于 03-17 14:52 ?267次閱讀
    多流技術(shù):不同壽命數(shù)據(jù)存在<b class='flag-5'>SSD</b>的不同塊

    Mini SSD是什么

    ? 在全球數(shù)字化轉(zhuǎn)型加速的背景下,存儲設(shè)備已不再是單純的數(shù)據(jù)存儲工具,而是信息安全、提升運算效率和支持業(yè)務(wù)創(chuàng)新的關(guān)鍵基石。佰維存儲順應(yīng)行業(yè)趨勢,發(fā)布全新一代存儲解決方案——Mini SSD,突破
    的頭像 發(fā)表于 01-20 12:36 ?409次閱讀

    固態(tài)硬盤(SSD)對比機械硬盤(HDD)

    固態(tài)硬盤(SSD)對比機械硬盤(HDD),優(yōu)點眾多。首先是讀寫速度,SSD 讀寫超迅速,系統(tǒng)啟動、軟件加載轉(zhuǎn)瞬完成,開機時間大幅縮短,一般 10 秒內(nèi)就能進入系統(tǒng)桌面,而 HDD 通常需幾十
    的頭像 發(fā)表于 01-13 16:33 ?506次閱讀

    MVTRF:多視圖特征預(yù)測SSD故障

    固態(tài)硬盤( Solid State Drive,SSD )在大型數(shù)據(jù)中心中發(fā)揮著重要作用。SSD故障會影響存儲系統(tǒng)的穩(wěn)定性,造成額外的維護開銷。為了提前預(yù)測和處理SSD故障,本文提出了一種多視角
    的頭像 發(fā)表于 12-30 11:04 ?390次閱讀
    MVTRF:多視圖特征預(yù)測<b class='flag-5'>SSD</b>故障

    SSD硬盤對系統(tǒng)性能的影響

    隨著科技的不斷進步,存儲設(shè)備也在不斷地更新?lián)Q代。固態(tài)硬盤(SSD)作為一種新型的存儲設(shè)備,相較于傳統(tǒng)的機械硬盤(HDD),在性能上有著顯著的提升。 1. 啟動速度 SSD硬盤的啟動速度遠快于HDD
    的頭像 發(fā)表于 11-23 09:36 ?1221次閱讀

    什么是SSD硬盤 SSD硬盤的優(yōu)勢和劣勢

    快速讀寫速度、低功耗、抗震動等優(yōu)點。 SSD硬盤的優(yōu)勢 快速讀寫速度 :SSD硬盤的讀寫速度遠高于傳統(tǒng)HDD,這得益于其內(nèi)部沒有機械部件,數(shù)據(jù)傳輸完全依賴于電子信號,因此可以實現(xiàn)幾乎即時的數(shù)據(jù)訪問。 低功耗 :由于
    的頭像 發(fā)表于 11-23 09:34 ?1281次閱讀

    SSD硬盤和HDD硬盤的區(qū)別

    在計算機存儲領(lǐng)域,固態(tài)硬盤(SSD)和機械硬盤(HDD)是兩種主要的存儲解決方案。隨著技術(shù)的發(fā)展,SSD因其卓越的性能和可靠性逐漸成為市場的新寵,而HDD則以其大容量和較低的成本繼續(xù)在市場上
    的頭像 發(fā)表于 11-23 09:32 ?989次閱讀

    SSD故障排查與解決方案

    隨著固態(tài)硬盤(SSD)的普及,越來越多的用戶選擇使用SSD作為電腦的主要存儲設(shè)備。然而,SSD在使用過程中也可能會出現(xiàn)各種故障。 一、SSD故障的常見表現(xiàn) 系統(tǒng)啟動緩慢 :
    的頭像 發(fā)表于 11-11 11:11 ?2824次閱讀

    如何選擇適合的SSD SSD和HDD的區(qū)別

    隨著技術(shù)的發(fā)展,存儲設(shè)備也在不斷進步。SSD和HDD是兩種常見的存儲解決方案,它們各自有著不同的優(yōu)勢和局限性。 SSD和HDD的區(qū)別 1. 速度 SSD :固態(tài)硬盤使用閃存技術(shù),沒有移動部件,因此
    的頭像 發(fā)表于 11-11 10:57 ?1211次閱讀

    ICY DOCK M.2轉(zhuǎn)U.2 SSD轉(zhuǎn)接盒如何重新定義M.2 NVMe SSD

    ICY DOCK M.2轉(zhuǎn)U.2 SSD轉(zhuǎn)接盒如何重新定義M.2 NVMe SSD
    的頭像 發(fā)表于 10-21 18:08 ?507次閱讀
    ICY DOCK M.2轉(zhuǎn)U.2 <b class='flag-5'>SSD</b>轉(zhuǎn)接盒如何重新定義M.2 NVMe <b class='flag-5'>SSD</b>

    SSD基本架構(gòu)

    SSD?主要由控制單元和存儲單元(當(dāng)前主要是FLASH?閃存顆粒)組成,控制單元包括SSD?控制器、主機接口、DRAM?等,存儲單元主要是NAND閃存?顆粒。 主機接口:主機訪問SSD的協(xié)議和物理
    的頭像 發(fā)表于 08-14 09:05 ?596次閱讀

    聊聊下一代企業(yè)級SSD外形EDSFF #EDSFF #SSD #硬盤抽取盒

    硬盤SSD
    ICY DOCK硬盤盒
    發(fā)布于 :2024年06月13日 17:15:19
    主站蜘蛛池模板: 久久亚洲欧美成人精品 | 大蕉久久伊人中文字幕 | 国产在线综合网 | 在线天堂bt种子资源 | 国产男人午夜视频在线观看 | 又黄又涩的视频 | 国产精品任我爽爆在线播放6080 | 国产美女久久久久 | 失禁h啪肉尿出来高h男男 | 五月婷婷丁香综合 | 男人在线资源 | 日本三浦理惠子中文字幕 | 久久午夜网| 性欧美高清短视频免费 | 国产高清在线精品一区 | 婷婷五月小说 | 亚洲一区二区在线 | 色吧首页dvd | 51影院在线观看成人免费 | 在线播放ww | 天天摸天天碰成人免费视频 | 午夜视频免费看 | 人人看人人添人人爽 | 欧美8888 | 一区二区3区免费视频 | 伊人精品久久久大香线蕉99 | 亚洲香蕉久久一区二区三区四区 | 午夜影院免费入口 | 色妞干网| 手机看片国产在线 | 成人午夜亚洲影视在线观看 | 日本五十交尾在线观看 | 人人干人人搞 | avbobo在线 | 国产片一区二区三区 | 一区二区三区四区视频在线 | 在线看片成人免费视频 | 欧美一级黄色片在线观看 | 四虎影院久久久 | 特级片免费看 | 亚洲国产网 |