ssd 目標檢測 入門 實例 源碼修改

目錄

 

1、環境搭建

2、ssd-tensorflow 項目下載

3、文件夾建立

4、數據標註

5、標註數據整理

6、源程序修改

7、生成訓練數據

8、訓練模型

9、訓練中

10、tensorboard監控

11、測試驗證

12、tips


1、環境搭建

win7_64

NVIDIA K620顯卡

安裝軟件:

anaconda4.40

Python 3.6.1

tensorflow -gpu 1.14.0

CUDA  10.0.130

cudnn  v7.6.3.30

上述顯卡的驅動官網可以下載,但是速度比較慢,我會傳一份到網盤。

因爲後續cmd使用很多,建議上GitHub 下載 cmder ,用來執行cmd命令,提高效率。

2、ssd-tensorflow 項目下載

從GitHub上下載項目源文件即可。

3、文件夾建立

下載後,在項目根目錄中需要手動建立幾個文件夾:

VOC2007
├─test
│  ├─Annotations
│  ├─ImageSets
│  │  └─Main
│  └─JPEGImages
└─train
    ├─Annotations
    ├─ImageSets
    │  └─Main
    └─JPEGImages

文件夾作用說明:(在數據標註後用到)

將用於train的xml,放入train\Annotations ,並將對應jpg,放入train\ImageSets
將用於test的xml,放入test\Annotations ,並將對應jpg,放入test\ImageSets

4、數據標註

在GitHub上下在 labelimg軟件進行標註。

tips:

1、標註時原始圖像大小不一定是300*300或512*512的。對原始圖大小沒有要求。

2、標註後每個圖片有自己的xml描述文件。

3、標註工作的作業目錄對後面的訓練沒有影響,可以將標註完成後的文件拷貝到訓練的文件夾下。因爲最終是用的與Annotations 同級別的ImageSets中的同名字的img。

5、標註數據整理

將標註後的數據手動分成2類,一部分爲train文件,一部分爲test。

將用於train的圖片放入\train\ImageSets,用於train的圖片的xml放入\train\Annotations

同理處理test的圖片。

我是 159個訓練照片,40個test照片。

每個照片內基本都是3個目標。這3個目標可以是不同的類別。

6、源程序修改

主要目的有幾個:1、修改部分bug。2、因爲分類數量不同,要修改成自己的項目需要的狀態

修改bug:

修改dateset中的pascalvoc_to_tfrecords.py 83行: image_data = tf.gfile.FastGFile(filename, 'r').read()
爲: image_data = tf.gfile.FastGFile(filename, 'rb').read()

修改項目差異:(參考:https://www.icode9.com/content-4-45616.html

1、/datasets/pascalvoc_common.py文件中,24-46行,第一類none不要動,其他的類修改爲自己數據集的類。我是判定鋼的不同等級,如下:一共12類。

VOC_LABELS = {
    'none': (0, 'Background'),
  	'STEEL_C05': (1, 'STEEL'),
	'STEEL_C10': (2, 'STEEL'),
	'STEEL_C20': (3, 'STEEL'),
	'STEEL_C30': (4, 'STEEL'),
	'STEEL_B05': (5, 'STEEL'),
	'STEEL_B10': (6, 'STEEL'),
	'STEEL_B20': (7, 'STEEL'),
	'STEEL_B30': (8, 'STEEL'),
	'STEEL_A05': (9, 'STEEL'),
	'STEEL_A10': (10, 'STEEL'),
    'STEEL_A20': (11, 'STEEL'),
    'STEEL_A30': (12, 'STEEL'),
}

2、/datasets/pascalvoc_to_tfrecords.py文件中67行,修改SAMPLES_PER_FILES爲幾張圖片轉爲一個tfrecord文件,我文件比較少,用的50個爲一組

# TFRecords convertion parameters.
RANDOM_SEED = 4242
#SAMPLES_PER_FILES = 200
SAMPLES_PER_FILES = 50

3、r/nets/ssd_vgg_300.py文件中,96-97行的num_classes和no_annotation_label改爲“類別數+1”  是13    none這個不算一類。

4、/eval_ssd_network.py 文件中,66行,修改num_classes爲“類別數+1”  是13  none這個不算一類。

5、nets/ssd_vgg_300.py   line 96,97:修改爲類別+1.

6、train_ssd_network.py 

line27: 數據格式改成 NHWC  這個是用CPU 計算,如果打算用GPU 計算,不需要改這一行。

line135: 類別個數: 類別數+1

line154: 訓練步數:這個自己改了,先給的小的訓練看下loss。

7、/datasets/pascalvoc_2007.py文件中,第31行和55行的none類不要動,其他類修改爲自己數據集的類,其中括號內的第一個數爲圖片數,第二個數爲目標數(也就是bonding box數,關於如何計算目標數,我寫了一個python文件,在附錄中),52行和76行的total是所有類的總和。

統計boxing 的Python程序:

# -*- coding: utf-8 -*-
import re
import os
 
 
classes='STEEL_C05,STEEL_C10,STEEL_C20,STEEL_C30,STEEL_B05,STEEL_B10,STEEL_B20,STEEL_B30,STEEL_A05,STEEL_A10,STEEL_A20,STEEL_A30'
classAry=classes.split(',')
print(classAry[0])
 
#創建字典
dic_class_img={}
dic_class_box={}
for cla in classAry:
    dic_class_box[cla]=0    
    dic_class_img[cla]=0 
print(dic_class_box)

annotation_folder = './VOC2007/test/Annotations'		#改爲自己標籤文件夾的路徑
list = os.listdir(annotation_folder)

img_count=0

for i in range(0, len(list)):
    img_count=img_count+1
    path = os.path.join(annotation_folder,list[i])
    filepath=annotation_folder + '/' + os.path.basename(path) 
    annotation_file =open(filepath,'rb').read().decode('utf8') 
    
    for cla in classAry:        
        count=len(re.findall(cla, annotation_file))
        dic_class_box[cla]=dic_class_box[cla]+ count
        if count>0:
            dic_class_img[cla]=dic_class_img[cla]+1

print('total img '+str(img_count))          
print("box:")
print(dic_class_box)
print("img")
print(dic_class_img)


img_total=0
box_total=0
# print train class
for cla in classAry:
    print("'"+cla+"':("+str(dic_class_img[cla])+","+str(dic_class_box[cla])+"),")
    img_total=img_total+dic_class_img[cla]
    box_total=box_total+dic_class_box[cla]
# cal total
# total 中的img 數量不能重複,就是train或test文件下的img數量,box數量是所有的box的總和
print("'total':("+str(img_count)+","+str(box_total)+"),")
    

源碼修改後的:

格式說明          '類別':(有多少個圖片含有這個類,一共有多少個是這個類的box)

所以,在total這一列:

圖片的數量 < 上面每個類的圖片數量的總和。 即 159 < 84+128+7+0+21+....

boxing的數量 = 上面每個圖片中的box數量的總和  即 476= 150+257+....

# (Images, Objects) statistics on every class.
TRAIN_STATISTICS = {
'STEEL_C05':(84,150),
'STEEL_C10':(128,257),
'STEEL_C20':(7,7),
'STEEL_C30':(0,0),
'STEEL_B05':(21,36),
'STEEL_B10':(16,26),
'STEEL_B20':(0,0),
'STEEL_B30':(0,0),
'STEEL_A05':(0,0),
'STEEL_A10':(0,0),
'STEEL_A20':(0,0),
'STEEL_A30':(0,0),
'total':(159,476), 
}
TEST_STATISTICS = {
'STEEL_C05':(20,43),
'STEEL_C10':(23,51),
'STEEL_C20':(2,2),
'STEEL_C30':(1,1),
'STEEL_B05':(12,23),
'STEEL_B10':(0,0),
'STEEL_B20':(0,0),
'STEEL_B30':(0,0),
'STEEL_A05':(0,0),
'STEEL_A10':(0,0),
'STEEL_A20':(0,0),
'STEEL_A30':(0,0),
'total':(40,120),
}
SPLITS_TO_SIZES = {
    #'train': 5011,
   # 'test': 4952,
	'train': 159,
    'test': 40,
}
SPLITS_TO_STATISTICS = {
    'train': TRAIN_STATISTICS,
    'test': TEST_STATISTICS,
}
#NUM_CLASSES = 20
NUM_CLASSES = 12   # 不包含背景的數量

7、生成訓練數據

注意文件目錄。

1、訓練的tfrecord。在cmd中執行:

python tf_convert_data.py \
    --dataset_name=pascalvoc \
    --dataset_dir=./VOC2007/train/ \
    --output_name=voc_2007_train \
    --output_dir=./tfrecords

2、測試的tfrecord 。在cmd中執行:

python tf_convert_data.py \
    --dataset_name=pascalvoc \
    --dataset_dir=./VOC2007/test/ \
    --output_name=voc_2007_test \
    --output_dir=./tfrecords

8、訓練模型

cmd執行:其中num_classes  是自己的  類數+1

下面是GPU 計算的啓動:

python train_ssd_network.py \
    --train_dir=./logs/ \
    --dataset_dir=./tfrecords \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=./checkpoints/ssd_300_vgg.ckpt \
    --save_summaries_secs=60 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.001 \
    --batch_size=6 \
    --ignore_missing_vars=True \
    --num_classes=13 \
    --checkpoint_exclude_scopes =ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \

下面是CPU 的啓動   要注意6.6 中的數據格式修改。

python train_ssd_network.py \
    --train_dir=./logs/ \
    --dataset_dir=./tfrecords \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=./checkpoints/ssd_300_vgg.ckpt \
    --save_summaries_secs=60 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.001 \
    --batch_size=6 \
	--ignore_missing_vars=True \
    --num_classes=13 \
	--checkpoint_exclude_scopes =ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box  \
	--device=CPU \
	--data_format=NHWC \

 

9、訓練中

下面是GPU 計算的截圖,CPU 計算的速度很慢

計算過程數據保存在 \logs 中

10、tensorboard監控

cmd執行 tensorboard --logdir= logs 文件夾路徑

打開瀏覽器:http://localhost:6006

11、測試驗證

 

 

12、tips

tensorflow 數據類型
NCHW  用於GPU
NHWC  用於CPU

 

 

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