參考:https://blog.csdn.net/weixin_39881922/article/details/80569803
1 xml目标計算參考:https://blog.csdn.net/zjc910997316/article/details/100776527
2 生成tset.txt等檔案:https://blog.csdn.net/zjc910997316/article/details/100776527
3 VGG16模型下載下傳位址:連結:https://pan.baidu.com/s/1diWbdJdjVbB3AWN99406nA 密碼:ge3x
1下載下傳源碼
1.代碼位址:https://github.com/balancap/SSD-Tensorflow,下載下傳該代碼到本地
2.解壓ssd_300_vgg.ckpt.zip 到checkpoint檔案夾下
3. 測試一下看看,在notebooks中建立ssd_notebook.py,
格式這樣:notebooks/ssd_notebook.py
其實就是用jupyter notebook打開ssd_notebook.ipynb,儲存為ssd_notebook.py
該py檔案是完成對于單張圖檔的測試,對Jupyter不熟,就自己改了,感覺這樣要友善一些。
4. 19行是ipython格式(jupyter打開的)内容注釋掉即可
5. python ssd_notebook.py運作即可
2設定自己的資料集
1.将自己的資料集做成VOC2007格式放在該工程下面
2. 修改datasets檔案夾中pascalvoc_common.py檔案,将訓練類修改别成自己的
'''原始的
VOC_LABELS = {
'none': (0, 'Background'),
'aeroplane': (1, 'Vehicle'),
'bicycle': (2, 'Vehicle'),
'bird': (3, 'Animal'),
'boat': (4, 'Vehicle'),
'bottle': (5, 'Indoor'),
'bus': (6, 'Vehicle'),
'car': (7, 'Vehicle'),
'cat': (8, 'Animal'),
'chair': (9, 'Indoor'),
'cow': (10, 'Animal'),
'diningtable': (11, 'Indoor'),
'dog': (12, 'Animal'),
'horse': (13, 'Animal'),
'motorbike': (14, 'Vehicle'),
'person': (15, 'Person'),
'pottedplant': (16, 'Indoor'),
'sheep': (17, 'Animal'),
'sofa': (18, 'Indoor'),
'train': (19, 'Vehicle'),
'tvmonitor': (20, 'Indoor'),
}
'''
#修改後的第一種思路:所有動物算一類
'''
VOC_LABELS = {
'none': (0, 'Background'),
'animal':(1,'Vehicle'),
}
'''
#修改後的第二種思路:14種動物
VOC_LABELS = {
'none': (0, 'Background'),
'antelope': (1, 'Animal'),
'blood_male': (2, 'Animal'),
'golden_monkey': (3, 'Animal'),
'gr-tailed_pheasant': (4, 'Animal'),
'panda': (5, 'Animal'),
'rock_sheep': (6, 'Animal'),
'sambar(female)': (7, 'Animal'),
'sambar(male)': (8, 'Animal'),
'small_muntjac': (9, 'Animal'),
'takin': (10, 'Animal'),
'tibetan_macaque': (11, 'Animal'),
'tufted_deer': (12, 'Animal'),
'wild_boar': (13, 'Animal'),
'yellow_marten': (14, 'Animal'),
}
存在疑問?這裡的Animal Background是什麼意思?是否在代碼裡面起作用了?
'none': (0, 'Background'),
'aeroplane': (1, 'Vehicle'),
'bicycle': (2, 'Vehicle'),
'bird': (3, 'Animal'),
3. 将圖像資料轉換為tfrecods格式,datasets/pascalvoc_to_tfrecords.py
修改datasets檔案夾中的pascalvoc_to_tfrecords.py檔案,
然後更改檔案的83行讀取方式為’rb‘,如果你的檔案不是.jpg格式,也可以修改圖檔的類型。
此外, 修改67行,可以修改幾張圖檔轉為一個tfrecords
200張預設
4.運作tf_convert_data.py檔案(通過腳本tf_convert_data.sh運作),但是需要傳給它一些參數:
linux下:
在SSD-Tensorflow-master檔案夾下建立腳本檔案nk_tf_conver_data.sh,
自己建立的儲存tfrecords資料的檔案夾nk_tfrecords
檔案寫入内容如下:
DATASET_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/VOC2007/
OUTPUT_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/nk_tfrecords/
python /home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/tf_convert_data.py \
--dataset_name=pascalvoc \
--dataset_dir=${DATASET_DIR} \
--output_name=voc_2007_test \
--output_dir=${OUTPUT_DIR}
注意:這種紅色反斜杠時出問題的(懷疑是4567前面的tab造成,需要從新寫一遍就可以了,建議從新寫一遍,建議使用絕對路徑)
正确的這樣:
但是還是報錯:ValueError: You must supply the dataset directory with --dataset_dir解決辦法:
1我改用絕對路徑,
2#!/bin/bash 也是建議添加的
3下面帶有講解
#filename = tf_convert_data.sh #!/bin/bash #This is a shell script to convert Pascal VOC datasets(2007 and 2012) into TF-Records only. #Directory where the original dataset is stored # /home/hp/zjc/Tensorflow/Deeplearning/dataset/VOCtest_06-Nov-2007/VOCdevkit/VOC2007/ DATASET_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/VOC2007/ #Output directory where to store TFRecords files # /home/hp/zjc/Tensorflow/Deeplearning/dataset/VOCtest_06-Nov-2007/VOCdevkit/VOC2007_tfrecord/ OUTPUT_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/nk_tfrecords/ #/home/hp/zjc/Tensorflow/Deeplearning/SSD-Tensorflow-master/tf_convert_data.py python /home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/tf_convert_data.py \ --dataset_name=pascalvoc \ --dataset_dir=${DATASET_DIR} \ --output_name=voc_2007_test \ --output_dir=${OUTPUT_DIR}
5. 通過指令bash tf_convert_data.sh 運作
四川王朗DW制作的資料集14070張圖檔,14070個xml檔案,200個轉化為一個tfrecord
bash tf_convert_data.sh
之後得到71個tfrecord
6. 訓練模型train_ssd_network.py檔案中修改
修改154行最大訓練步數,None可以改成50000 max-step為None時訓練會無限進行
train_ssd_network.py 檔案中網絡參數配置,若需要改,在此檔案中進行修改,如
3 其他需要修改的地方
a. nets/ssd_vgg_300.py (因為使用此網絡結構) ,修改96和97行的類别、
=>nets/ssd_vgg_300.py 96
修改後
b. train_ssd_network.py,修改類别120行,GPU占用量,學習率,batch_size等
GPU占用量
=>train_ssd_network.py 66
學習率0,001-0.0001,衰減率
=>train_ssd_network.py 113 115
batch_size(我這裡是21,圖中32是預設的),
batch_size=21 為了能被14070整除 14070/21 = 670 一般epoch訓練200輪次 200*670 =134000 需要訓練134000輪
物種數量(我這裡是15 = 14 + 1 因為14種動物加上背景),
=>train_ssd_network.py 151
c eval_ssd_network.py 修改類别,66行
=>eval_ssd_network.py 66
根據自己的資料修改為類别+1
d. datasets/pascalvoc_2007.py 根據自己的訓練資料修改整個檔案
=>datasets/pascalvoc_2007.py 89->109
'''原有代碼
TRAIN_STATISTICS = {
'none': (0, 0),
'aeroplane': (238, 306),
'bicycle': (243, 353),
'bird': (330, 486),
'boat': (181, 290),
'bottle': (244, 505),
'bus': (186, 229),
'car': (713, 1250),
'cat': (337, 376),
'chair': (445, 798),
'cow': (141, 259),
'diningtable': (200, 215),
'dog': (421, 510),
'horse': (287, 362),
'motorbike': (245, 339),
'person': (2008, 4690),
'pottedplant': (245, 514),
'sheep': (96, 257),
'sofa': (229, 248),
'train': (261, 297),
'tvmonitor': (256, 324),
'total': (5011, 12608),
}
TEST_STATISTICS = {
'none': (0, 0),
'aeroplane': (1, 1),
'bicycle': (1, 1),
'bird': (1, 1),
'boat': (1, 1),
'bottle': (1, 1),
'bus': (1, 1),
'car': (1, 1),
'cat': (1, 1),
'chair': (1, 1),
'cow': (1, 1),
'diningtable': (1, 1),
'dog': (1, 1),
'horse': (1, 1),
'motorbike': (1, 1),
'person': (1, 1),
'pottedplant': (1, 1),
'sheep': (1, 1),
'sofa': (1, 1),
'train': (1, 1),
'tvmonitor': (1, 1),
'total': (20, 20),
}
SPLITS_TO_SIZES = {
'train': 5011,
'test': 4952,
}
SPLITS_TO_STATISTICS = {
'train': TRAIN_STATISTICS,
'test': TEST_STATISTICS,
}
NUM_CLASSES = 20
'''
替換為如下: 注意這裡NUM_CLASSES=14,有多少類就是多少,無需+1(無需加背景類)
TRAIN_STATISTICS = {
'none': (0, 0),
'antelope': (500, 500), # (有這個動物的圖檔有多少張, 這個動物bbox一共多少個)
'blood_male': (1858, 5000),
'golden_monkey': (627, 991),
'gr-tailed_pheasant': (607, 607),
'panda': (864, 864),
'rock_sheep': (1599, 5000),
'sambar(female)': (3165, 5000),
'sambar(male)': (845, 845),
'small_muntjac': (536, 536),
'takin': (980, 1282),
'tibetan_macaque': (226, 331),
'tufted_deer': (1047, 1047),
'wild_boar': (908, 1014),
'yellow_marten': (308, 382),
'total': (14070, 23399),
}
TEST_STATISTICS = {
'none': (0, 0),
'antelope': (1, 1),
'blood_male': (1, 1),
'golden_monkey': (1, 1),
'gr-tailed_pheasant':(1, 1),
'panda': (1, 1),
'rock_sheep': (1, 1),
'sambar(female)': (1, 1),
'sambar(male)': (1, 1),
'small_muntjac': (1, 1),
'takin': (1, 1),
'tibetan_macaque': (1, 1),
'tufted_deer': (1, 1),
'wild_boar': (1, 1),
'yellow_marten': (1, 1),
'total': (14, 14),
}
SPLITS_TO_SIZES = {
'train': 14070,
'test': 2814,
}
SPLITS_TO_STATISTICS = {
'train': TRAIN_STATISTICS,
'test': TEST_STATISTICS,
}
NUM_CLASSES = 14
e 疊代次數150000
=>train_ssd_network.py 155
batch_size=21 為了能被14070整除
14070/21 = 670
一般epoch訓練200輪次
200*670 =134000 需要訓練134000輪 取整150000
4 通過.sh腳本訓練網絡(通過加載預訓練好的vgg16模型,微調網絡)
下載下傳預訓練好的vgg16模型,解壓放入checkpoint檔案中,如果找不到vgg_16.ckpt檔案,可以在下面的連結中點選下載下傳。
連結:https://pan.baidu.com/s/1diWbdJdjVbB3AWN99406nA 密碼:ge3x
(ubuntu解壓不友善, 在win下下載下傳解壓)
按照之前的方式,同樣,如果你是linux使用者,你可以建立一個.sh檔案,檔案裡寫入
DATASET_DIR=./tfrecords_/
TRAIN_DIR=./train_model/
CHECKPOINT_PATH=./checkpoints/vgg_16.ckpt
python3 ./train_ssd_network.py \
--train_dir=./train_model/ \ #訓練生成模型的存放路徑
--dataset_dir=./tfrecords_/ \ #資料存放路徑
--dataset_name=pascalvoc_2007 \ #資料名的字首
--dataset_split_name=train \
--model_name=ssd_300_vgg \ #加載的模型的名字
--checkpoint_path=./checkpoints/vgg_16.ckpt \ #所加載模型的路徑
--checkpoint_model_scope=vgg_16 \ #所加載模型裡面的作用域名
--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 \
--trainable_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 \
--save_summaries_secs=60 \ #每60s儲存一下日志
--save_interval_secs=600 \ #每600s儲存一下模型
--weight_decay=0.0005 \ #正則化的權值衰減的系數
--optimizer=adam \ #選取的最優化函數
--learning_rate=0.001 \ #學習率
--learning_rate_decay_factor=0.94 \ #學習率的衰減因子
--batch_size=24 \
--gpu_memory_fraction=0.9 #指定占用gpu記憶體的百分比
5 通過修改train_ssd network.py檔案訓練網絡(上述方法的替代方案)
1 在train_ssd_network.py檔案裡面直接修改(等效于用bash xxx.sh修改,)
(這裡記錄checkpoints和event logs)
(自己建立一個檔案夾tfmodel)
=>train_ssd_network.py 43
修改為
2 tfrecord存放位址
=>train_ssd_network.py 139
修改後
3 datasetname, pascalvoc_2007 #資料名的字首
=>train_ssd_network.py 133
修改後
4 ./checkpoints/vgg_16.ckpt \ #所加載模型的路徑
=>train_ssd_network.py 162
修改為 '/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/checkpoints/vgg_16.ckpt'
5 vgg_16 #所加載模型裡面的作用域名
=>train_ssd_network.py 166
修改後
6 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
=>train_ssd_network.py 170
修改後
7 trainable_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
=>train_ssd_network.py 175
修改後
8
save_summaries_secs=60 \ #每60s儲存一下日志
=>train_ssd_network.py 60
修改後
9 --save_interval_secs=600 \ #每600s儲存一下模型 (不用改,本來就是)
=>train_ssd_network.py 63
10 --weight_decay=0.0005 \ #正則化的權值衰減的系數
=>train_ssd_network.py 72
修改後為
11 --optimizer=adam \ #選取的最優化函數
=>train_ssd_network.py 74
修改後為
12 --learning_rate=0.001 \ #學習率(本來就是)
=>train_ssd_network.py 113 115
如下會比較好:0.001-0.0001
13 --learning_rate_decay_factor=0.94 \ #學習率的衰減因子 (本來就是)
=>train_ssd_network.py 120
14 --batch_size=21 \ (暫時就是32了不做修改)
=>train_ssd_network.py 152
修改為21,為了能被14070(張圖檔)整除
batch_size=21 為了能被14070整除
14070/21 = 670
一般epoch訓練200輪次
200*670 =134000 需要訓練134000輪
15 --gpu_memory_fraction=0.9 #指定占用gpu記憶體的百分比\ (暫時就是32了不做修改)
=>train_ssd_network.py 66