caffe-ssd訓練測試自己的資料
阿新 • • 發佈:2019-01-03
前記:這篇文章記錄的是本人基於caffe框架使用自己的資料訓練ssd的實現過程,若想用tensorflow框架實現,詳見SSD-Tensorflow 訓練記錄
一,caffe-ssd安裝編譯
進入個人主目錄下
git clone https://github.com/weiliu89/caffe.git #注意下載的是ssd版本而非master版本
cd caffe
git checkout ssd #切換到ssd分支
開始編譯配置caffe相關檔案,具體實現過程與編譯caffe一樣,詳見伺服器caffe安裝配置檔案
二,資料集準備
我沒有對VOC資料集進行訓練和測試,直接就上手自己的資料集,對於我們自己的資料集需要設定成VOC格式,為了方便起見,我將個人的資料命名為VOC2007,在VOC2007資料夾下新建三個資料夾,分別為Annotations(用於存放xml的標註檔案),ImageSets(資料夾存放的是txt檔案,該目錄下具體情況如下圖
其中Layout和Segmentation資料夾為空,test.txt,train.txt,val.txt分別記錄了測試,訓練,驗證資料集的名稱,trainval.txt存放的則為訓練和驗證資料集綜合的名稱。
具體VOC資料集的生成網上有很多demo可以參考。
三,資料集轉化
需要將資料轉化成lmbd格式
1.在data目錄下新建一個資料夾VOCdevkit用於存放自己的資料集,對我而言即VOC2007,再新建一個資料夾VOC_XDF將VOC0721目錄下所有的檔案拷貝到該資料夾下。
2. 在examples下建立VOC_XDF資料夾用於存放後續生成的lmbd檔案
3. 修改create_list.sh和create_data.sh檔案的相關路徑
create_list.sh修改如下
#!/bin/bash root_dir=$HOME/caffe-ssd/data/VOCdevkit/ #資料集目錄 sub_dir=ImageSets/Main bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" for dataset in trainval test do dst_file=$bash_dir/$dataset.txt if [ -f $dst_file ] then rm -f $dst_file fi for name in VOC2007 #根據自己的資料集名稱修改 do if [[ $dataset == "test" && $name == "VOC2012" ]] then continue fi echo "Create list for $name $dataset..." dataset_file=$root_dir/$name/$sub_dir/$dataset.txt img_file=$bash_dir/$dataset"_img.txt" cp $dataset_file $img_file sed -i "s/^/$name\/JPEGImages\//g" $img_file sed -i "s/$/.jpg/g" $img_file label_file=$bash_dir/$dataset"_label.txt" cp $dataset_file $label_file sed -i "s/^/$name\/Annotations\//g" $label_file sed -i "s/$/.xml/g" $label_file paste -d' ' $img_file $label_file >> $dst_file rm -f $label_file rm -f $img_file done # Generate image name and size infomation. if [ $dataset == "test" ] then $HOME/caffe-ssd/build/tools/get_image_size $root_dir $dst_file $bash_dir/$dataset"_name_size.txt" fi # Shuffle trainval file. if [ $dataset == "trainval" ] then rand_file=$dst_file.random cat $dst_file | perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' > $rand_file mv $rand_file $dst_file fi done
create_data.sh修改如下
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$HOME/caffe-ssd
cd $root_dir
redo=1
data_root_dir="$HOME/caffe-ssd/data/VOCdevkit"
dataset_name="VOC_XDF"
mapfile="$root_dir/data/$dataset_name/labelmap_voc.prototxt"
anno_type="detection"
db="lmdb"
min_dim=0
max_dim=0
width=0
height=0
extra_cmd="--encode-type=jpg --encoded"
if [ $redo ]
then
extra_cmd="$extra_cmd --redo"
fi
for subset in test trainval
do
python $root_dir/scripts/create_annoset.py --anno-type=$anno_type --label-map-file=$mapfile --min-dim=$min_dim --max-dim=$max_dim --resize-width=$width --resize-height=$height --check-label $extra_cmd $data_root_dir $root_dir/data/$dataset_name/$subset.txt $data_root_dir/$dataset_name/$db/$dataset_name"_"$subset"_"$db examples/$dataset_name
done
修改labelmap_voc.prototxt為自己的類別,注意保留第一類background
全部修改完成後執行指令碼命令:
bash ./data/VOC_XDF/create_list.sh #該命令會生成三個檔案test_name_size.txt test.txt trainval.txt
bash ./data/VOC_XDF/create_data.sh #該命令會在examples/VOC_XDF/資料夾下生成兩個子資料夾, mydataset_trainval_lmdb, mydataset_test_lmdb;裡面均包含data.dmb和lock.dmb
至此,資料轉化完成
四,訓練資料
首先我們許需要下載預訓練好的模型VGG_ILSVRC_16_layers_fc_reduced.caffemodel,存放在./models/VGGNet下(如果沒有VGGNet,則新建一個)。
然後我們需要對examples/ssd/ssd_pascal.py進行相應修改,具體修改如下:
81 # The database file for training data. Created by data/VOC0712/create_data.sh
82 train_data = "examples/VOC_XDF/VOC_XDF_trainval_lmdb" #修改為自己的目錄
83 # The database file for testing data. Created by data/VOC0712/create_data.sh
84 test_data = "examples/VOC_XDF/VOC_XDF_test_lmdb" #修改為自己的目錄
-------------------------------------
234 # Modify the job name if you want.
235 job_name = "SSD_{}".format(resize)
236 # The name of the model. Modify it if you want.
237 model_name = "VGG_VOC_XDF_{}".format(job_name) #修改為自己模型的名稱
238
239 # Directory which stores the model .prototxt file.
240 save_dir = "models/VGGNet/VOC_XDF/{}".format(job_name) #生成的所有prototxt檔案存放路徑
241 # Directory which stores the snapshot of models.
242 snapshot_dir = "models/VGGNet/VOC_XDF/{}".format(job_name) #訓練得到的快照模型儲存路徑
243 # Directory which stores the job script and log file.
244 job_dir = "jobs/VGGNet/VOC_XDF/{}".format(job_name)
245 # Directory which stores the detection results.
246 output_result_dir = "{}/caffe-ssd/data/VOCdevkit/results/VOC2007/{}/Main".format(os.environ['HOME'], job_name) #該路徑儲存測試結果
-------------------------------------
258 # Stores the test image names and sizes. Created by data/VOC0712/create_list.sh
259 name_size_file = "data/VOC_XDF/test_name_size.txt" #修改為自己的路徑
260 # The pretrained model. We use the Fully convolutional reduced (atrous) VGGNet.
261 pretrain_model = "models/VGGNet/VGG_ILSVRC_16_layers_fc_reduced.caffemodel" #預訓練模型路徑
262 # Stores LabelMapItem.
263 label_map_file = "data/VOC_XDF/labelmap_voc.prototxt" #修改成自己的路徑
264
265 # MultiBoxLoss parameters.
266 num_classes = 2 #自己的類別+1
--------------------------------------
337 batch_size = 16 #修改batch_size的大小
338 accum_batch_size = 16
--------------------------------------
359 num_test_image = 421 #測試圖片數量
360 test_batch_size = 8 #測試batch_size大小
--------------------------------------
365 solver_param = {
366 # Train parameters
367 'base_lr': 0.0001, #設定初始學習率的大小
368 'weight_decay': 0.0005,
369 'lr_policy': "multistep",
370 'stepvalue': [10000, 30000, 50000],
371 'gamma': 0.1,
372 'momentum': 0.9,
373 'iter_size': iter_size,
374 'max_iter': 60000, #最大迭代輪次
375 'snapshot': 50000, #快照,將訓練出來的model和solver狀態進行儲存,snapshot用於設定訓練多少次後進行儲存
376 'display': 10, #訓練10次顯示結果
377 'average_loss': 10,
378 'type': "SGD", #優化演算法
379 'solver_mode': solver_mode,
380 'device_id': device_id,
381 'debug_info': False,
382 'snapshot_after_train': True,
383 # Test parameters
384 'test_iter': [test_iter],
385 'test_interval': 200, #200次進行一次測試
386 'eval_type': "detection",
387 'ap_version': "11point",
388 'test_initialization': False,
389 }
修改完成後執行:
python ./examples/ssd/ssd_pascal.py
出現如下結果表明正常:
可能的問題:
- 訓練loss=nan
對模型進行調參比如降低一下學習率,具體可見使用caffe訓練時Loss變為nan的原因