tensorflow SSD實戰:基於深度學習的多目標識別

SSD(SSD: Single Shot MultiBox Detector)是採用單個深度神經網絡模型實現目標檢測和識別的方法。如圖2所示,該方法是綜合了Faster R-CNN的anchor box和YOLO單個神經網絡檢測思路(YOLOv2也採用了類似的思路,詳見YOLO升級版:YOLOv2和YOLO9000解析),既有Faster R-CNN的準確率又有YOLO的檢測速度,可以實現高準確率實時檢測。在300*300分辨率,SSD在VOC2007數據集上準確率爲74.3%mAP,59FPS;512*512分辨率,SSD獲得了超過Fast R-CNN,獲得了80%mAP/19fps的結果,如圖0-2所示。SSD關鍵點分爲兩類:模型結構和訓練方法。模型結構包括:多尺度特徵圖檢測網絡結構和anchor boxes生成;訓練方法包括:ground truth預處理和損失函數。本文解析的是SSD的tensorflow實現源碼,來源balancap/SSD-Tensorflow。本文結構如下:

1,多尺度特徵圖檢測網絡結構;

2,anchor boxes生成;

3,ground truth預處理;

4,目標函數;

5,總結

 

2 SSD與MultiBox,Faster R-CNN,YOLO原理

(此圖來源於作者在eccv2016的PPT)

 

圖0-2 SSD檢測速度與精確度。(此圖來源於作者在eccv2016的PPT)

1 多尺度特徵圖檢測網絡結構

SSD的網絡模型如圖3所示。

3 SSD模型結構。(此圖來源於原論文)

模型建立源代碼包含於ssd_vgg_300.py中。模型多尺度特徵圖檢測如圖1-2所示。模型選擇的特徵圖包括:38×38(block4),19×19(block7),10×10(block8),5×5(block9),3×3(block10),1×1(block11)。對於每張特徵圖,生成採用3×3卷積生成 默認框的四個偏移位置和21個類別的置信度。比如block7,默認框(def boxes)數目爲6,每個默認框包含4個偏移位置和21個類別置信度(4+21)。因此,block7的最後輸出爲(19*19)*6*(4+21)。

 

 

所需的環境:

  • Anaconda3(64bit)

  • CUDA-9.2

  • CuDNN-7.15

  • Python-3.6

  • TensorFlow 或者 TensorFlow-gpu由於考慮到項目工程量比較大,所以本文選用GPU版本進行訓練

步驟:

安裝Anaconda3:在anaconda官網下下載對應windows版本的anaconda安裝包,下載完成後按照提示進行安裝,anaconda3裏包含很多python IDE。

 

圖4

 

安裝cuda和cuDNN:安裝Tensorflow-gpu版本必須先把cuda環境配置好,這樣才能成功安裝,如何查看cuda安裝成功呢?可以在vs2017裏面進行查看。

  1. 數據集製作:利用LabelImg工具對預先得到的需要訓練的圖片進行框選目標的最小包圍框,LabelImg會自動將框選的目標生成所需要的xml文件

  2.  

 

圖5

Xml文件中記錄了人和帽子以及馬甲的最小包圍框。

  1. 格式轉換:由於SSD-TensorFlow不能直接對圖片進行訓練,需要先將得到的圖片轉換爲.tfrecord格式,在轉換的過程中可以選擇將多少張圖片轉爲一個.tfrecord。

啓動訓練:在訓練之前需要修改pascalvoc_2007.py和ssd_300_vgg.py文件中的識別目標數,改成自己需要識別的種類,然後在train_ssd_network.py文件中修改相應的參數。修改完成即可運行train_ssd_network.py文件,在console窗口可以查看相關的運行信息,當然在運行期間也可以查看tensorboard下的各個參數指標。

檢驗模型:模型檢驗在eval_ssd_network.py文件下進行檢驗,得到的輸出信息mAP,爲模型檢驗的準確率。

詳細流程

Pascal voc2007數據集:

使用SSD-tensorflow的標準數據集包括Pascal voc2007和Pascal voc2012可以選擇一起訓練,也可以對兩種數據集分開訓練。在對視頻進行處理時利用Matlab可以很容易將視頻按自己選擇的幀數截成圖片。

得到圖片後將圖片以統一格式命名,放在JPEGImages文件夾下,接着將圖片中的目標框選出來,框選圖片有兩種方法,一種是利用代碼得到xml文件,不過這種方法每次都要改變代碼裏邊框的大小信息,比較麻煩。還有一張使用自動化工具LabelImg。

 

Step1:點擊open打開需要框選的圖片的路徑:。

Step2:點擊Create RectBox,在圖片上框選人所在位置。

Step3:在彈出的對話框中輸入person。

Step4:對於hat,以及vest的框選重複步驟1,2,3即可直到所有的圖片框選完。

注意:對同一幅圖片.jpg文件和.xml命名要一樣。

ssd-tensorflow-model工程相關參數修改:

  1. 轉換爲tfrecord格式:

首先將數據集保存在工程路徑下,方便進行數據格式轉換,以及模型訓練。

Step1:打開pascalvoc_to_tfrecords.py文件,修改畫框的參數,將SAMPLES_PER_FILES,改爲自己需要將多少張圖片轉換成一個.tfrecord文件

比如我將其改爲400,也就是是400張圖片轉換爲一個.tfrecord文件。

Step2:tf_convert_data.py中,dataset_dir改爲剛剛自己轉換的圖片所在的文件夾所在路徑。output_dir改爲自己需要保存的.tfrecord文件路徑。

Step3:開始運行此.py文件代碼,生成如下圖所示文件

 

相關.py文件參數修改:

數據格式處理好了之後,下一步就要根據自己的目標種數修改大量的.py文件了,由於原項目工程爲根據官網的標準數據集訓練的共有20種目標需要訓練,而自己的數據集訓練目標爲3種,所以對應的信息要修改。

Step1:修改pascalvoc2007.py相關信息,原項目21種目標,此處改爲自己的目標種數NUM_CLASSES = 3,TRAIN_STATISTICS 第一個參數爲目標出現在圖片的張數,第二個參數爲目標出現的總次數。SPLITS_TO_SIZES 爲將數據集劃分爲訓練數據集與測試數據集的張數。

Step2:修改pascalvoc_common.py相關信息

Step3:在ssd_vgg_300.py文件中修改如下參數。改爲目標數加一(加一爲背景還要算一種)。

  1. 開始訓練模型:

爲了開始訓練模型,首先要將train_ssd_network.py文件相關信息修改正確。

Step1:train_dir改爲自己需要將模型保存的路徑下。

Step2:log_every_n_steps改爲自己需要多少步保存顯示相關信息。

Step3:save_summaries_secs爲多少秒保存一次日誌。

Step4:save_interval_secs爲多少秒保存一次得到的模型。

Step5:gpu_memory_fraction爲訓練時需要佔用多少百分百的顯存。

Step6:leaning_rate爲設置需要多大的學習率,一般開始學習率大一點以便不困在局部最優解,當loss比較小時learning_rate設置小一點降低loss。

Step7:end_learning_rate爲訓練結束時的學習率。

Step8:dataset_name修改爲pascalvoc_2007,因爲數據集爲pascalvoc2007數據集。

Step9:num_classes爲自己的目標數加一。

Step10:dataset_split_name改爲train,劃分tfrecord文件。

Step11:dataset_dir爲轉換的tfrecord文件路徑。

Step12:model_name改爲ssd_300_vgg,因爲我們的圖片resize爲大小了。

Step13:batch_size根據自己顯卡內存大小適當修改,太大了會報顯存不足。

Step14:max_number_of_steps爲最大訓練步數,一般50000-100000均可。

Step15:checkpoint_path是否在預訓練模型的基礎上訓練,此處我們可以在ssd_300_vgg模型的基礎上訓練我們的模型。

訓練時輸出窗口得到如下信息:

當loss值比較穩定而且比較小時說明模型訓練的差不多了,可以停下來檢驗模型訓練的好壞。

本次訓練由於各種設備上的原因導致此次訓練時間較爲長,在ssd_300_vgg模型的基礎上我訓練了50000-60000次,得到了模型檢測效果還比較好,接着爲了得到更好的識別率,我將learning_rate改爲了0.00001,繼續訓練了50000-60000步,模型精度提高了20%左右。

 

 

下圖爲在tensorboard下看到的訓練過程中相關參數的變化,total_loss爲訓練過程中的損失度,可以看到損失度比較小,訓練比較順利。

 

 

圖片檢測效果分析:

ssd-tensorflow-model相比於Google API的缺點在於對小目標檢測效果比較差,而此次訓練得到的結果也能反映出這一點,當目標在圖片中所佔比例比較大時,訓練得到的模型在檢測時其效果比較好,尋找目標的位置較爲準確,目標識別概率正確度高,如下圖所示。

 

總結

 優點:SSD(Single Shot MultiBox Detector)在訓練時,這種算法對於不同橫縱比的object的檢測都有效,這是因爲算法對於每個feature map cell都使用多種橫縱比的default boxes,這也是此算法的核心。另外本文的default box做法是很類似Faster RCNN中的anchor的做法的。最後本文也強調了增加數據集的作用,包括隨機裁剪,旋轉,對比度調整等等,而且此模型訓練速度較YOLO更加迅速,可以獲得更加明顯的效果。 
  缺點:文中作者提到該算法對於小的object的detection比大的object要差。作者認爲原因在於這些小的object在網絡的頂層所佔的信息量太少,所以增加輸入圖像的尺寸對於小的object的檢測有幫助。另外增加數據集對於小的object的檢測也有幫助,原因在於隨機裁剪後的圖像相當於“放大”原圖像,所以這樣的裁剪操作不僅增加了圖像數量,也放大了圖像。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章