前记:这篇文章记录的是本人基于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();' > $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