文章目录
说明
基于caffe平台的,SSD、MobileNet SSD、ShuffleNet SSD目标检测模型。
SSD
可参考:
安装
下载 SSD源码, 修改配置文件, 构建编译即可.
使用
训练自己的数据
准备数据集
- VOC 格式数据集
- 生成数据集:
./create_list.sh
,./create_data.sh
MobileNet SSD
安装
下载源码,放入examples文件夹,重命名为 “MobileNetSSD” 即可。
使用
生成训练测试文件
执行 ./gen_model.sh CLASSNUM
会根据类别和模板文件,在“example”文件夹生成以下文件:
- MobileNetSSD_test.prototxt (测试用文件)
- MobileNetSSD_train.prototxt(训练用文件)
- MobileNetSSD_deploy_bn.prototxt(网络结构文件,含batchnorm)
- MobileNetSSD_deploy.prototxt(网络结构文件,不含batchnorm)
需要注意的是:
CLASSNUM
含背景类- 生成的deploy.prototxt文件,默认偏置都是有的,而训练文件里前几层是没有偏置的,因而会出现后文中的问题,可以修改模板中的参数,或者修改train中的参数。
- 模板文件中的卷积层参数
cls1x、cls3x、cls6x
与类别数有关
生存训练测试数据集
使用SSD源码目录下的“data”文件夹中提供的 create_list.sh
和 create_data.sh
脚本生成数据集,并将生成的 “XXX_trainval_lmdb” 文件链接到MobileNetSSD根目录即可。或者修改 “example/ MobileNetSSD_train.prototxt” 中的文件路径,如下:
data_param {
source: "trainval_lmdb/"
batch_size: 24
backend: LMDB
}
训练
终端执行如下命令训练
#!/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
../../build/tools/caffe train -solver="solver_train.prototxt" \
-weights="mobilenet_iter_73000.caffemodel" \
-gpu 0
批量测试
#!/bin/sh
#latest=snapshot/mobilenet_iter_73000.caffemodel
latest=$(ls -t snapshot/*.caffemodel | head -n 1)
if test -z $latest; then
exit 1
fi
../../build/tools/caffe train -solver="solver_test.prototxt" \
--weights=$latest \
-gpu 0
MobileNet SSDLite
安装
ShuffleNet SSD
Depthwise卷积
1.下载源码
从caffe-mobilenet或caffe官方库中下载 Depthwise卷积实现文件。
将以下文件放入caffe源码src文件夹 “caffeSSD/src/caffe/layers” 中。
conv_dw_layer.cpp
conv_dw_layer.cu
将以下文件放入caffe源码include文件夹 “caffeSSD/include/caffe/layers” 中。
conv_dw_layer.hpp
2.重新编译构建
该层不需要额外在caffe.proto文件中声明,所以直接编译构建
make clean
make all -j$(nproc)
# Make sure to include $CAFFE_ROOT/python to your PYTHONPATH.
make pycaffe -j$(nproc)
make test -j$(nproc)
# (Optional)
#make runtest -j$(nproc)
注:这里可以先不编译,可以跟下面的ShuffleNet一起编译构建。
ShuffleNet
1.下载源码
从这里 ShuffleNet 下载ShuffleNet层源码。
将以下文件放入caffe源码src文件夹 “caffeSSD/src/caffe/layers” 中。
shuffle_channel_layer.cpp
shuffle_channel_layer.cu
将以下文件放入caffe源码include文件夹 “caffeSSD/include/caffe/layers” 中。
shuffle_channel_layer.hpp
2.修改caffe.proto
修改 “/caffeSSD/src/caffe/proto/caffe.proto” 文件,在 LayerParameter
, ShuffleChannelParameter
分别添加:
message LayerParameter {
...
optional ShuffleChannelParameter shuffle_channel_param = 164;
...
}
...
message ShuffleChannelParameter {
optional uint32 group = 1[default = 1]; // The number of group
}
3.编译构建
重新编译构建即可:
make clean
make all -j$(nproc)
# Make sure to include $CAFFE_ROOT/python to your PYTHONPATH.
make pycaffe -j$(nproc)
make test -j$(nproc)
# (Optional)
#make runtest -j$(nproc)
使用
根据类别,修改 test.prototxt
, train.prototxt
228(38*6) --> 24(4*6)
114(38*3) --> 12(4*3) name: "conv13_mbox_conf"
问题
网络结构
权重与偏置
在测试时运行提示如下错误,卷积层0的blob数不一致,原来是1个,现在是2个,即训练的时候只有一个,现在变成了两个。什么问题呢?
Check failed: target_blobs.size() == source_layer.blobs_size() (2 vs. 1) Incompatible number of blob for layer conv0
这是因为训练时conv0有只有权重参数,没有偏置, 可以通过查看 train.prototxt
看到,而测试时,conv0既有权重参数,又有偏置, 可以通过查看 deploy.prototxt
看到,
重名层
当网络结构文件中,包含一样名字的层时,会提示类似如下错误:
Top blob 'detection_out' produced by multiple sources.
精度问题
需要注意以下问题:
- 训练与测试需要使用相同的参数:如都使用batchnorm或都不使用
源码参数设置解析
BatchNorm
在Caffe中, BatchNorm与Scale配合使用, 原因如下: