SSD(Single Shot MultiBox Detector):ubuntu16安裝及訓練自己的資料集(VOC2007格式)過程記錄

SSD(Single Shot MultiBox Detector):ubuntu16安裝及訓練自己的資料集(VOC2007格式)過程記錄

安裝SSD

# SSD程式碼clone到 caffe-ssd資料夾下
git clone --recursive https://github.com/weiliu89/caffe.git caffe-ssd
cd caffe-ssd
# 選擇ssd分支
git checkout ssd

編譯caffe

對於一個新的ubuntu系統,編譯caffe需要安裝相應依賴庫,如果你成功編譯過caffe和faster rcnn,就不需要再安裝,這裡略過。
關於編譯caffe和faster rcnn的詳細過程參見我之前部落格《Ubuntu16:cmake生成Makefile編譯caffe過程(OpenBLAS/CPU GPU)》《cuda8 cuDNN Faster R-CNN安裝塈執行demo》

$cd caffe-ssd
#如果沒有cmake,要安裝cmake
#$sudo apt-get install cmake
mkdir build && cd build
# 執行cmake生成Makefile
#編譯CPU版本
#cmake -DCPU_ONLY=ON -DBLAS=Open .
#編譯GPU版本
$cmake -DBLAS=Open -DCUDA_NVCC_FLAGS=--Wno-deprecated-gpu-targets ..
$make -j 8

下載預訓練模型

下載預訓練模型VGG_ILSVRC_16_layers_fc_reduced.caffemodel,放在 ./models/VGGNet/路徑

下載地址
https://gist.github.com/weiliu89/2ed6e13bfd5b57cf81d6

訓練資料準備

我的訓練資料集是按VOC2007格式生成的,為了最少修改ssd的程式碼,我的做法是用我自己的VOC2007資料集替換SSD訓練用的VOC2007和VOC2012資料集。
在$home下建立一個data檔案

cd ~
mkdir data
mkdir data/VOCdevkit
mkdir data/VOCdevkit/VOC2007

將自己的資料集複製在 VOC2007

ll VOC2007
drwxrwxr-x 6 guyadong guyadong 4096 4月 14 09:19 ./
drwxr-xr-x 3 guyadong guyadong 4096 4月 14 09:01 ../
drwxrwxr-x 2 guyadong guyadong 3846144 4月 13 17:14 Annotations/
drwxrwxr-x 3 guyadong guyadong 4096 4月 13 17:14 ImageSets/
drwxrwxr-x 2 guyadong guyadong 3809280 4月 13 17:14 JPEGImages/

在examples資料夾下建立VOC2007資料夾

cd caffe-ssd
mkdir examples/VOC2007

(請注意VOC2007這個名字,你可以不使用這個名字,但如果你要使用別的名字,請注意本文後面所有涉及VOC2007的地方都必須換成同樣的名字)

修改lmdb生成指令碼

複製data/VOC0712檔案為VOC2007

 cd caffe-ssd/data
cp -r VOC0712 VOC2007

修改caffe-ssd/data/VOC2007/create_list.sh如下
create_list.sh

#!/bin/bash
root_dir=$HOME/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
$bash_dir/../../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_list.sh修改後版本與原版本的比對
這裡寫圖片描述
修改caffe-ssd/data/VOC2007/create_data.sh如下:
create_data.sh

cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/../..
cd $root_dir
redo=1
data_root_dir="$HOME/data/VOCdevkit"
dataset_name="VOC2007"
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

下圖是create_data.sh修改後版本與原版本的比對
這裡寫圖片描述
labelmap_voc.prototxt用於定義標籤(label),所以還要
根據你的目標檢測要求修改caffe-ssd/data/VOC2007/labelmap_voc.prototxt,比如我的專案中是檢測人臉,我的labelmap_voc.prototxt定義如下(label 0固定定義為背景):
labelmap_voc.prototxt

item {
name: "none_of_the_above"
label: 0
display_name: "background"
}
item {
name: "face"
label: 1
display_name: "face"
}

修改訓練指令碼

用vim或gedit等文字編輯器開啟 caffe-ssd/examples/ssd/ssd_pascal.py,將程式碼中所有的VOC0712替換為VOC2007,並儲存檔案,
找到num_classes = 21這一行,將數字改為1 類別數
這裡寫圖片描述
找到num_test_image = 4952 將數字改為你測試集(test.txt)的數量
這裡寫圖片描述
另外, 如果你只有一個GPU, 需要修改ssd_pascal.py ,找到gpus = "0,1,2,3”這一行改為 gpus = "0”,如果有兩塊GPU,則改為gpus = "0,1”,依此類推。
這裡寫圖片描述

修改測試指令碼

開啟caffe-ssd/examples/ssd/ssd_pascal_webcam.py
將程式碼中所有的VOC0712替換為VOC2007
找到num_classes = 21這一行,將數字改為1 類別數

這裡寫圖片描述

執行訓練程式碼

修改完成後開始執行訓練程式碼

python ./examples/ssd/ssd_pascal.py 

out of memory

訓練過程可能比較漫長,如果訓練過程出現out of memory錯誤,說明你的顯示卡視訊記憶體不夠,可以調整ssd_pascal.py中的來解決:找到batch_size = 32這一行,減少這個數字試試。
比如我的顯示卡GTX1060視訊記憶體是6G,改為batch_size = 8才能進行訓練。
這裡寫圖片描述

#參考資料
《SSD安裝及訓練自己的資料集》