基於PaddlePaddle實現的目標檢測模型SSD

原文博客:Doi技術團隊
鏈接地址:https://blog.doiduoyi.com/authors/1584446358138
初心:記錄優秀的Doi技術團隊學習經歷
本文鏈接:基於PaddlePaddle實現的目標檢測模型SSD

PaddlePaddle-SSD

SSD,全稱Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一種目標檢測算法,截至目前是主要的檢測框架之一,相比Faster RCNN有明顯的速度優勢,相比YOLO V1又有明顯的mAP優勢。本開源是基於PaddlePaddle實現的SSD,參考了PaddlePaddle下的models的ssd ,包括MobileNetSSD,MobileNetV2SSD,VGGSSD,ResNetSSD。使用的是VOC格式數據集,同時提供了預訓練模型和VOC數據的預測模型。

快速使用

  1. 將圖像數據集存放在dataset/images目錄下,將標註數據存放在dataset/annotations目錄下。
  2. 執行create_data_list.py程序生成數據列表。
  3. 在下面的表格中下載預訓練模型,解壓到pretrained目錄下。
  4. 修改config.py參數,其中最重要的是class_numuse_modelpretrained_modelclass_num是分類數量加上背景一類。use_model是指使用的模型,分別有resnet_ssd、mobilenet_v2_ssd、mobilenet_v1_ssd、vgg_ssd四種選擇。pretrained_model是預訓練模型的路徑。
  5. 執行train.py程序開始訓練,每訓練一輪都會更新保存的模型,訓練過程中可以隨時停止訓練。
  6. 執行infer.py預測圖像,預測模型的路徑在config.py配置文件中查找。

模型下載

模型名稱 所用數據集 預訓練模型 預測模型
VGG_SSD網絡的VOC預訓練模型 pascalvoc 點擊下載 點擊下載
ResNet_SSD網絡的VOC預訓練模型 pascalvoc 點擊下載 點擊下載
MobileNet_V1_SSD網絡的VOC預訓練模型 pascalvoc 點擊下載 點擊下載
MobileNet_V2_SSD網絡的VOC預訓練模型 pascalvoc 點擊下載 點擊下載

SSD模型介紹

SSD全稱Single Shot MultiBox Detector,是2016年提出的一種one-stage目標檢測算法,相比two-stage目標檢測算法的Faster R-CNN來說,其特點是一步到位,速度相對較快。
SSD有以下幾個特點:

  1. 將bounding box的輸出空間離散化爲一系列不同縱橫比的default box, 並能夠調整box更好地匹配物體的形狀。
  2. 將多個不同分辨率的feature map上的預測結果結合,解決了物體不同大小的問題。
  3. 模型結構簡單,SSD模型把全部的計算都放在一個網絡模型上,大體上可以分爲兩部分,圖像特徵提取網絡和分類檢測網絡。

以下是SSD的結構圖,在原論文中主幹網絡爲VGG16,後面接着6個卷積層,用於提取出6個不同尺度的feature map,這樣可以提取出不同大小的bbox,以檢測到不同大小的目標對象。其中主幹網絡可以替換成其他的卷積網絡,所以SSD也產生了幾種衍生版,例如MobileNetV2 SSD、ResNet50 SSD等等。生成的6個feature map都輸入到分類檢測網絡中,分類檢測網絡分別對這6個feature map依次預測的,這個分類檢測網絡可以使用PaddlePaddle的fluid.layers.multi_box_head()接口實現。
在這裏插入圖片描述

針對6個feature map的更詳細圖如下。

以下是按照原論文的模型參數搭建的網絡模型,在各個衍生版參數設置也有所變動。如下的主幹網絡是使用VGG16,使用PaddlePaddle實現的代碼片段如下。

conv1 = self.conv_block(self.img, 64, 2)
conv2 = self.conv_block(conv1, 128, 2)
conv3 = self.conv_block(conv2, 256, 3)

6個feature map的實現代碼如下,按照論文中的,feature map1的shape爲38*38*512,feature map2的shape爲19*19*1024,feature map3的shape爲10*10*512,feature map4的shape爲5*5*256,feature map5的shape爲3*3*256,feature map6的shape爲1*1*256

# 38x38
module11 = self.conv_bn(conv3, 3, 512, 1, 1)
tmp = self.conv_block(module11, 1024, 5)
# 19x19
module13 = fluid.layers.conv2d(tmp, 1024, 1)
# 10x10
module14 = self.extra_block(module13, 256, 512, 1)
# 5x5
module15 = self.extra_block(module14, 128, 256, 1)
# 3x3
module16 = self.extra_block(module15, 128, 256, 1)
# 1x1
module17 = fluid.layers.pool2d(input=module16, pool_type='avg', global_pooling=True)

最後這個就是分類檢測模型,在PaddlePaddle上只需一個接口即可完成,在參數inputs參數中把6個feature map的輸出都作爲參數輸入。按照論文中設置先驗框的長度和base_size的最小比率min_ratio爲20%,先驗框的長度和base_size的最大比率max_ratio爲90%,其中base_size是輸入圖片的大小。

mbox_locs, mbox_confs, box, box_var = fluid.layers.multi_box_head(
    inputs=[module11, module13, module14, module15, module16, module17],
    image=self.img,
    num_classes=self.num_classes,
    min_ratio=20,
    max_ratio=90,
    min_sizes=[60.0, 105.0, 150.0, 195.0, 240.0, 285.0],
    max_sizes=[[], 150.0, 195.0, 240.0, 285.0, 300.0],
    aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2., 3.], [2., 3.]],
    base_size=self.img_shape[2],
    offset=0.5,
    flip=True)

min_sizesmax_sizes分別是每層提取的先驗框的最小長度和最大長度,當輸入個數len(inputs) > 2,並且min_sizemax_size爲None時,通過baze_size, min_ratiomax_ratio來計算出min_sizemax_size,計算公式如下:

min_sizes = []
max_sizes = []
step = int(math.floor(((max_ratio - min_ratio)) / (num_layer - 2)))
for ratio in six.moves.range(min_ratio, max_ratio + 1, step):
    min_sizes.append(base_size * ratio / 100.)
    max_sizes.append(base_size * (ratio + step) / 100.)
    min_sizes = [base_size * .10] + min_sizes
    max_sizes = [base_size * .20] + max_sizes

同樣PaddlePaddle也提供了SSD的損失函數,使用的接口時fluid.layers.ssd_loss()。通過給定位置偏移預測,置信度預測,候選框和真實框標籤,返回的損失是或迴歸損失和分類損失的加權和。

loss = fluid.layers.ssd_loss(locs, confs, gt_box, gt_label, box, box_var)
loss = fluid.layers.reduce_sum(loss)

代碼詳解

本項目中最重要的是config.py配置文件,這裏包含了所有的訓練配置信息,開發者在使用本項目訓練自己的數據集時,一定要留意該配置是否符合當前的數據集和訓練環境,以下筆者針對幾個重要的參數進行解析。

  • image_shape輸入訓練的現狀,默認是[3, 300, 300],也可以設置大小爲512*512
  • batch_size訓練數據的batch大小,根據自己的硬件環境修改,充分使用硬件資源。
  • epoc_num訓練的輪數,每一輪都會保存預測模型和訓練的參數。
  • lr初始化學習率。
  • class_num分類的數量,通常還要加上背景一類,例如VOC類別是20類,那該值爲21。
  • use_model使用的SSD的模型,分別有resnet_ssd、mobilenet_v2_ssd、mobilenet_v1_ssd、vgg_ssd,更加自己的需求選擇不同的模型,如何開發者是希望嵌入到移動設備的,那麼可以考慮mobilenet_v2_ssd、mobilenet_v1_ssd。如何開發者希望有更好的識別準確率,可以使用resnet_ssd。
  • label_file分類的標籤對應的名稱,由create_data_list.py生成,通常不需要修改。
  • train_list訓練數據的數據列表,每一行數據對應的是他們的圖片和標註文件的路徑,,由create_data_list.py生成,通常不需要修改。
  • test_list測試數據的數據列表,每一行數據對應的是他們的圖片和標註文件的路徑,,由create_data_list.py生成,通常不需要修改。
  • persistables_model_path訓練過程中保存的模型參數,可以用於再次訓練,恢復之前的訓練。
  • infer_model_path訓練過程中保存的預測模型,可以用於之後的預測圖像,不需要再依賴模型代碼。
  • pretrained_model預訓練模型路徑,預訓練模型文件在上面模型下載中下載,需要指定解壓的文件夾路徑。
  • use_gpu是否使用GPU進行訓練。
  • use_multiprocess是否使用多線程讀取數據,在Windows系統下不能使用,否則會出錯。

create_data_list.py代碼是生成數據類別和數據標籤的,本項目目前僅支持VOC標註格式的數據。如果開發者把數據集分爲imagesannotations,並且存放在dataset/imagesdataset/annotations目錄下,還有他們的文件名是一樣的,那麼這個代碼是不需要修改的。如果開發者的數據格式有差別,請修改代碼生成如下的數據列表,每一行第一個爲圖像的路徑,第二個是VOC格式的標註文件,他們中間有製表符\t分開。

dataset/images/00001.jpg	dataset/annotations/00001.xml
dataset/images/00002.jpg	dataset/annotations/00002.xml

train.py爲訓練代碼,基本上的訓練配置都在config.py


infer.py爲預測代碼,這代碼可以單獨運行,不再需要網絡模型代碼。預測是可以在圖像上畫框和類別名稱並顯示。

  • label_file是標籤文件,由create_data_list.py生成,在畫框的時候顯示類別名稱。
  • score_threshold爲預測得分閾值,小於該閾值的結果不顯示。
  • infer_model_path指定預測模型的路徑。

utils/reader.py是將圖像和標籤數據生成訓練和測試數據的生成器,圖像預處理和生成SSD模型的預選框也會在這個過程完成。但是生成SSD模型的預選框是調用了utils/image_util.py完成,這個代碼包含了生成預選框和數據增強,增強方式請仔細閱讀該代碼。


四種模型的代碼存放在nets文件夾下,包括mobilenet_v1_ssd.pymobilenet_v2_ssd.pyvgg_ssd.pyresnet_ssd.py模型,模型代碼介紹請查看上面的SSD模型介紹


源碼開源地址: https://github.com/yeyupiaoling/PaddlePaddle-SSD

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