原
【SSD】用caffe-ssd框架MobileNet网络训练自己的数据集
置顶 2017年11月02日 13:33:00 阅读数:9798 更多 个人分类: SSD 版权声明:本文为博主Hans原创文章,未经博主Hans允许不得转载。http://blog.csdn.net/renhanchi https://blog.csdn.net/renhanchi/article/details/78423343
前言
上一篇博客写了用作者提供的VGG网络完整走完一遍流程后,马上开始尝试用MobileNet训练。
还有两个问题待解决:
1.均值问题。【2017.11.20 解决此问题】
2.无法用MobileNet提供的caffemodel做finetune。 【2017.11.3解决此问题】
【2017.11.03更新】成功转换成ncnn格式。
一、数据集收集、整理
参考:http://blog.csdn.net/renhanchi/article/details/78411095
用的到的东西如图:
二、下载MobileNet相关文件
https://github.com/chuanqi305/MobileNet-SSD
路径自己看着弄。
三、生成train.prototxt、test.prototxt、deploy.prototxt
这里哦,我需要提前说点事儿。
1. 默认有一个MobileNet_deploy.prototxt,没有batch_norm层。可以跟官网提供的caffemodel一起用。
2. template里面有四个文件。两个deploy,一个train,一个test。
经验证,train和test跟一会我们自己生成的网络结构一致。
但我们不用template目录中的东西,因为后面几层num_output需要自己手动改。麻烦!
作者提供了两个工具用于生成prototxt文件。一个是gen.py一个是gen_model.sh。
我倾向用后者,操作简单点。
运行命令:
sh gen_model.sh
后面接的数字是类别数+1。
生成的文件在example目录下。
这里有一点哦,如果你的数据集里面不完全是RGB三通道的。
那么你要修改train.prototxt和test.prototxt文件:
- transform_param {
- scale:
- force_color: true ###添加
- mean_value:
- mean_value:
- mean_value:
具体报错内容可以看我上一篇博客 http://blog.csdn.net/renhanchi/article/details/78411095。
然后再分别修改文件中source和label_map_file的路径,尽量用绝对路径。
四、修改solver.prototxt文件
我直接拿来solver_train.prototxt用的,路径改好,尽量用绝对路径。其他参数自己看着改吧。
这里说一下坑了半天的一个问题吧。
一开始为了排错,我习惯性设置test_initialization为true。
然后就一直提示Couldn’t find ant detections。
但是训练阶段没问题的。
后来明白问题所在,因为我没有finetune,所以一开始val阶段并不能检测到任何东西。
将test_initialization 设置为false后,先训练一段时间后再val,就不会提示找不到东西了。
五、训练脚本
- #!/bin/sh
- /home/hans/caffe-ssd/build/tools/caffe train \
- --solver= "/home/hans/data/ImageNet/Detection/cup/MobileNet-SSD/doc/solver_train.prototxt \
- -gpu 6 2>&1 | tee /home/hans/data/ImageNet/Detection/cup/MobileNet-SSD/MobileNet-SSD.log
根据下面2017.11.03更新的内容可以看出,训练结束后,要通过作者提供的工具将bn层和conv层参数merge到一起,以加快计算速度。
修改merge_bn.py中路径和文件名。
新生成的模型应该会比原始模型稍微小一点。
六、训练输出可视化(2017.11.02)
参考: http://blog.csdn.net/renhanchi/article/details/78411095
七、测试模型效果(2017.11.03)
参考:http://blog.csdn.net/renhanchi/article/details/78411095
后记
为什么一用pre_trained model做finetune就报错!!!!!说conv0输入数量不对(1 vs. 2)。应该是1,结果传入2个???我各种对比检查了train.prototxt和test.prototxt文件,然并卵!!!!
——-【2017.11.3解决不能finetune的问题】——-
终于找到原因!
我把现在能做finetune的模型和deploy文件放出来。
https://pan.baidu.com/s/16dw-dJ779By9AWdiSOxSuQ
github上作者放出两个caffemodel,一个是训练时候的,这个模型bn层和cnov层参数是分开的。一个是deploy的,这个模型将bn层和conv层参数merge到一起了。
作者的原话是merge后的模型速度会快一点。
——-【2017.11.3成功转换成ncnn格式】———
https://github.com/arlose/ncnn-mobilenet-ssd
.param文件建议就用上面作者提供的吧。如果是自己训练的数据的话,把类别数改一下就好了,一共要改八处。
自己转换过来的有两个问题,
一是缺少头两层Input和Split,这个问题要修改deploy.prototxt文件开头为:
- layer {
- name: "data"
- type: "Input"
- top: "data"
- input_param { shape: { dim: dim: dim: dim: } }
- }
二是后面几层的处理像素变成了600*600。
.bin 文件一定要用经过merge.py处理过的caffemodel转换!
——-【2017.11.16更新】———
晕了我之前一直在用6月刚发布的ncnn,
这两天移植工作交给我才发现官方的ncnn已经加入ssd的支持。
并且还加入的模型压缩,虽然只是从计算位数上做的压缩,并且对效果会有折扣,但也是很实用的。
——-【2017.11.20更新】———
自带make_mean.sh并不能求均值,发现有两个转lmdb工具,一个带annotation,一个不带。
ssd用的带annotation工具中detection方法转换的。
我就用老方法求了均值,使用build/tools/convert_imageset 和 build/tools/compute_iamge_mean
shell脚本代码:
先把图片转换成普通lmdb格式
- #!/bin/sh
- set -e
- size=
- TOOLS=/home/hans/caffe/build/tools
- cur_dir=$(cd $( dirname ${BASH_SOURCE[<span class="hljs-number">0</span>]} ) && pwd )</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DATA_ROOT=<span class="hljs-string">"${cur_dir}/data/"
- FILE_PATH= "${cur_dir}/doc"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">echo <span class="hljs-string">"Creating train lmdb..."</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">GLOG_logtostderr=<span class="hljs-number">1</span> $TOOLS/convert_imageset \
- --resize_height=$size \</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="17"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> --resize_width=$size \
- --shuffle=false \
- $DATA_ROOT \</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="20"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> $FILE_PATH/train.txt \
- $FILE_PATH/train_lmdb_mean</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="22"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li></ol></code><div class="hljs-button" data-title="复制"></div></pre><br>计算均值,并将输出保存到mean.txt中<p></p><p></p><pre οnclick="hljs.copyCode(event)"><code class="language-python hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">#!/bin/sh</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">TOOLS=/home/hans/caffe/build/tools</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$TOOLS/compute_image_mean doc/train_lmdb_mean doc/mean.binaryproto >& | tee doc/mean.txt
- echo "Done."