【Caffe】用Caffe训练MobileNetv2-SSDLite

数据库文件LMDB的制作和Caffe环境配置请参考链接:【Caffe】用Caffe训练MobileNetSSD

一、获取源码

git clone https://github.com/chuanqi305/MobileNetv2-SSDLite

将下载的源码文件夹拷贝到caffe/examples下。

二、转换预训练模型

这里的caffe预训练权重是从tensorflow转换而来。

先下载tensorflow的预训练权重。

cd MobileNetv2-SSDLite/ssdlite/
wget http://download.tensorflow.org/models/object_detection/ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz
tar -zvxf ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz

然后转换成caffe模型。

打开MobileNetv2-SSDLite/ssdlite下的dump_tensorflow_weights.py文件,将graph_create里的pb文件的路径替换为自己存放文件的路径。

然后执行(这里要安装了tensorflow才行)

python3 dump_tensorflow_weights.py

会生成一个output文件夹,里面是dump出来的数据。

打开MobileNetv2-SSDLite/ssdlite下的load_caffe_weights.py文件,将caffe_root修改为自己的路径。

然后执行

python2 load_caffe_weight.py 

会在当前文件夹下生成deploy.caffemodel和deploy.prototxt两个文件。

三、训练自己的数据集

注意这里要用https://github.com/youngxiao/MobileNetv2-SSDLite/blob/master/ssdlite/gen_model.py这个脚本代替原来MobileNetv2-SSDLite/ssdlite文件夹下的gen_model.py文件。因为原来的gen_model.py生成的文件在训练时会报target_blobs.size() == source_layer_blobs.size() (1 vs. 2) - Incompatible number of blobs for layer Conv的错误。

执行下面的命令生成prototxt文件。

python gen_model.py -s train -c CLASS_NUM --tfpad --relu6 >train.prototxt
python gen_model.py -s test -c CLASS_NUM --tfpad --relu6 >test.prototxt
python gen_model.py -s deploy -c CLASS_NUM --tfpad --relu6 >deploy.prototxt

其中CLASS_NUM = 类别数 + 1。

然后我以自己的数据集名字在MobileNetv2-SSDLite/ssdlite下新建了一个文件夹,把生成的三个prototxt文件都拷贝了进去。

下面有几处需要修改的地方。

1. 打开train.prototxt,

data_param {
    source: "trainval_lmdb"
    batch_size: 24
    backend: LMDB
}

中的source修改为自己数据集lmdb文件的路径,并根据自己的显存大小调整batch_size的大小。

label_map_file: "labelmap_coco.prototxt"

换成自己数据集的labelmap文件。

对于test.prototxt做一样的处理。

把MobileNetv2-SSDLite/ssdlite/voc下的solver_train.prototxt拷贝到我新建的文件夹下面。

打开solver_train.prototxt,修改训练超参数。

如果不需要预训练权重,这时候就可以开始训练了。

#!/bin/sh
mkdir -p snapshot
/home/xxx/ssd/build/tools/caffe train \
-solver="/home/xxx/ssd/examples/MobileNetv2-SSDLite/ssdlite/mydata/solver_train.prototxt" \
-gpu 0

如果需要预训练权重,那么还需对(二)中得到的caffemodel做一次转换。因为它是针对coco 数据集的 caffemodel 90 个类别,这里还需转换成自己数据集的类别。

打开MobileNetv2-SSDLite/ssdlite下的coco2voc.py文件,将caffe_root修改为自己的路径。

对于这里的maps

maps = [0,5,2,16,9,44,6,3,17,62,21,67,18,19,4,1,64,20,63,7,72]

如果你的数据集是coco数据集的一个子集,那么最好像脚本里面这种和原coco数据集对应的label一致,这个需要事先查询到对应的标签类别。但是像我的数据集完全和coco里面的标签不一样,那我就直接从0开始直到我的类别数。

maps = [0,1,2,3,4,5,6,7,8,9,10]

第二个需要修改的地方是

neww = np.ones((x, 21, wt.shape[2]))

当中的21修改为自己的类别数+1的数字。

第三个需要修改的地方是

from_file = "deploy.prototxt"
from_model = "deploy.caffemodel"

修改为(二)中生成的那两个文件,注意如果不在当前路径要加上正确的路径。

net_file= 'voc/deploy.prototxt'  
save_model='deploy_voc.caffemodel'

net_file要修改成用gen_model.py生成的deploy.prototxt文件。这里如果不用自己生成的deploy.prototxt文件的话,生成的预训练模型在开始训练的时候会报conv_13/expand_mbox_conf shape mismatch错误。

save_model可以自由命名。

net_file= 'mydata/deploy.prototxt'  
save_model='mydata/deploy_mydata.caffemodel'

现在就可以使用预训练权重进行训练了。

#!/bin/sh
mkdir -p snapshot
/home/xxx/ssd/build/tools/caffe train \
-solver="/home/xxx/ssd/examples/MobileNetv2-SSDLite/ssdlite/mydata/solver_train.prototxt" \
-weights="/home/xxx/ssd/examples/MobileNetv2-SSDLite/ssdlite/mydata/deploy_mydata.caffemodel" \
-gpu 0

目前看来loss下降的不好,对小目标的检测效果很差。但是tensorflow那边训练的模型效果却很好。

发布了437 篇原创文章 · 获赞 590 · 访问量 61万+

猜你喜欢

转载自blog.csdn.net/heiheiya/article/details/103983941