https://github.com/chuanqi305/rscnn
VOC数据集制作在yolo 学习系列(二):训练自己的数据集中已经介绍过了,
但是 caffe 使用的是 LMDB 数据集格式,使用 caffe 框架实现SSD与mobilenets-ssd训练,还需要将 VOC 数据集转换为 lmdb 格式。
SSD提供了VOC数据到LMDB数据的转换脚本 ,位于caffe/data/VOC0712目录下的 create_list.sh 和 create_data.sh,这两个脚本是完全针对VOC0712目录下的数据进行的转换。
实现中为了不破坏VOC0712目录下的数据内容,针对我们自己的数据集,修改了上面这两个脚本,
将脚本中涉及到VOC0712的信息替换成我们自己的目录信息。
在处理我们的数据集时,将VOC0712替换成indoor
labelmap_voc_cucumber.prototxt 修改内容:
item {
name: "none_of_the_above"
label: 0
display_name: "background"
}
item {
name: "sea cucumber"
label: 1
display_name: "cucumber"
}
create_list_cucumber.sh 修改内容:
for name in cucumber # 修改此处
do
if [[ $dataset == "test" && $name == "VOC2012" ]]
then
continue
fi
create_data_cucumber.sh 修改内容:
data_root_dir="$HOME/data/VOCdevkit" # 数据集路径
dataset_name="cucumber"
mapfile="$root_dir/data/$dataset_name/labelmap_voc_cucumber.prototxt"
在 home/chris/ssd/caffe/ 目录下分别运行:
./data/indoor/create_list_indoor.sh
./data/indoor/create_data_indoor.sh
生成的数据集位于 home/chris/ssd/caffe/examples/cucumber 和 /home/chris/data/VOCdevkit/cucumber/lmdb 两个目录下。
其中,makefile.config 修改参考caffe里的makefile.config文件
git clone https://github.com/weiliu89/caffe.git
cd caffe
git checkout ssd
cp Makefile.config.example Makefile.config
mkdir build
cd build
cmake ..
make all -j16
make install
make runtest
make pycaffe
git clone https://github.com/chuanqi305/MobileNet-SSD.git
文件结构
template 存放4个网络定义的公用模板,可以由gen.py脚本修改并生成
MobileNetSSD_deploy.prototxt 运行网络定义文件
solver_train.prototxt 网络训练超参数定义文件
solver_test.prototxt 网络测试超参数定义文件
train.sh 网络训练脚本
test.sh 网络测试脚本
gen_model.sh 生成自定义网络脚本(调用template文件夹内容)
gen.py 生成公用模板脚本(暂不用)
demo.py 实际检测脚本(图片存于images文件夹)
merge_bn.py 合并bn层脚本,用于生成最终的caffemodel
最后打开 demo.py 脚本,根据个人情况修改以下路径:
caffe_root = '/home/chris/ssd/caffe/'
net_file= 'MobileNetSSD_deploy.prototxt'
caffe_model='MobileNetSSD_deploy.caffemodel'
test_dir = "images"
若报错,应该是 python 路径问题
gedit ~/.bashrc # 在最后添加使用的caffe路径
source ~/.bashrc
由于VOC数据集是21类(加上背景),而这里只有1类,因此,我们需要重新生成训练、测试和运行网络文件,这里就要用到gen_model.sh脚本,它会调用template文件夹中的模板,按照我们指定的参数,生成所需的训练网络模型。
# usage: ./gen_model.sh CLASSNUM
./gen_model.sh 2
执行之后,得到 Mobilenet-SSD/examples 文件夹里面的3个prototxt就是从模板生成的正式网络定义,根据作者设置,其中的deploy文件是已经合并过bn层的,需要后面配套使用。
将 Mobilenet-SSD/examples 下网络文件的路径修改为自己的路径.
MobileNetSSD_test.prototxt:
data_param {
# 第 24 行
source: "/home/chris/data/VOCdevkit/cucumber/lmdb/cucumber_test_lmdb/"
batch_size: 8
backend: LMDB
}
annotated_data_param {
batch_sampler {
}
# 第 31 行
label_map_file: "/home/chris/ssd/caffe/data/cucumber/labelmap_voc_cucumber.prototxt"
MobileNetSSD_train.prototxt:
data_param {
# 第 49 行
source: "/home/chris/data/VOCdevkit/cucumber/lmdb/cucumber_trainval_lmdb/"
batch_size: 24
backend: LMDB
..........................
max_sample: 1
max_trials: 50
}
# 第 136 行
label_map_file: "/home/chris/ssd/caffe/data/cucumber/labelmap_voc_cucumber.prototxt"
}
Mobilenet-ssd目录下的 solver_train.prototxt 和 solver_test.prototxt
solver_mode: CPU
运行 train.sh 脚本
#!/bin/sh
if ! test -f example/MobileNetSSD_train.prototxt ;then
echo "error: example/MobileNetSSD_train.prototxt does not exist."
echo "please use the gen_model.sh to generate your own model."
exit 1
fi
mkdir -p snapshot
../ssd/caffe/build/tools/caffe train -solver="solver_train.prototxt" \
-weights="mobilenet_iter_73000.caffemodel" \
运行以下命令,得到 no_bn.prototxt 和 no_bn.caffemodel
python2 merge_bn.py --model ./example/defults/MobileNetSSD_deploy.prototxt --weights ./snapshot/defults-A/mobilenet_iter_14000.caffemodel
最终使用的是没有 BN 层的模型,在 CPU 模式下,含有 BN 层的模型检测帧数为 8 帧,而去除 BN 层的模型检测帧数为 20 帧。
./build/tools/caffe time -gpu 0 -model examples/MobileNet-SSD/squeezenet-ssd/defults/squeezenet_ssd_voc_deploy.prototxt
问题
理论上Mobilenet的运行速度应该是VGGNet的数倍,但实际运行下来并非如此,即使是合并bn层后的MobileNet-SSD也只比VGG-SSD快那么一点点,主要的原因是Caffe中暂时没有实现depthwise convolution,目前都是用的group。这里group相当于一个for循环,需要依次计算,如果能使用深度卷积,那就可以一次性计算完,节省不少时间。
用上了depthwise convolution layer,对于mobilenet的提速十分明显,可以说是立竿见影。下面简单介绍使用方法.
1.下载项目
$ git clone https://github.com/yonghenglh6/DepthwiseConvolution.git
注意到项目中的caffe文件夹,将其中的depthwise_conv_layer.hpp,depthwise_conv_layer.cpp和depthwise_conv_layer.cu这三个文件放到SSD(即caffe)的相应位置中,这里的操作是从基础卷积类中派生了深度卷积这个类,此处并不需要对caffe.proto文件进行修改。稍后,需要重新编译Caffe,这样才能识别新增的depthwise convolution layer。
2.修改deploy.prototxt文件
接下来我们需要修改MobileNetSSD_deploy.prototxt,将其中所有名为convXX/dw(XX代指数字)的type从”Convolution”替换成”DepthwiseConvolution”,总共需要替换13处,从conv1/dw到conv13/dw,然后把“engine: CAFFE”都注释掉,这个新的网络文件可以另存为MobileNetSSD_deploy_depth.prototxt。在运行网络的时候,caffemodel模型不用动,只需要指定新的prototxt文件和含有depthwise convolution layer的Caffe即可。