1. 程式人生 > >caffe-ssd訓練測試自己的資料

caffe-ssd訓練測試自己的資料

前記:這篇文章記錄的是本人基於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

出現如下結果表明正常:
在這裡插入圖片描述
可能的問題:

  1. 訓練loss=nan
    對模型進行調參比如降低一下學習率,具體可見使用caffe訓練時Loss變為nan的原因