仅作笔记整理搬运使用,没有任何程序原创部分,主要给自己提个醒,避免重复搜索工作
ubuntu18.04 ,显卡驱动,cuda10.1,cudnn7.6.5
查看cuda版本:
cat /usr/local/cuda/version.txt
查看cudnn版本:
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
annaconda下创建caffe环境:conda create -n caffe2 python=2.7
opencv安装:pip install opencv-python
安装配置caffe-ssd
https://blog.csdn.net/CAU_Ayao/article/details/84000151
make runtest -j16 的时候会出错!
https://blog.csdn.net/Sunhansong/article/details/107281225
https://blog.csdn.net/la_fe_/article/details/84928958
caffe 使用的是 LMDB 数据集格式,使用 caffe 框架实现mobilenets-ssd训练,还需要将 VOC 数据集转换为 lmdb 格式。
(虽然用cucumber有点奇怪,但是就顺着人家作者来吧)
labelmap_voc_cucumber.prototxt 修改内容:
注意:"background"这个背景类别0标签不可以删掉
item {
name: "none_of_the_above"
label: 0
display_name: "background"
}
item {
name: "p"
label: 1
display_name: "p"
}
item {
name: "d"
label: 2
display_name: "d"
}
item {
name: "w"
label: 3
display_name: "w"
}
create_list_cucumber.sh 修改内容:
for name in cucumber # 修改此处为自己数据集的名字
do
if [[ $dataset == "test" && $name == "VOC2012" ]]
then
continue
fi
create_data_cucumber.sh 修改内容:
root_dir=/home/shs/caffe-ssd
… …
data_root_dir="$HOME/data/VOCdevkit" # 数据集路径
dataset_name="cucumber"
mapfile="$root_dir/data/$dataset_name/labelmap_voc_cucumber.prototxt"
./data/cucumber/create_list_cucumber.sh
./data/cucumber/create_data_cucumber.sh
ImportError:No module named caffe.proto
gedit ~/.bashrc
加入
export PYTHONPATH=~/caffe-ssd/python:$PYTHONPATH
source ~/.bashrc
在每次执行creat_data.sh生成lmdb的时候都需要进行上述操作。
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
./gen_model.sh 4
**注意:**这里的用法是:# usage: ./gen_model.sh CLASSNUM
,CLASSNUM是你的类别数,比如我的数据集有三类,应该再加上background这一类,所以CLASSNUM 类别数就为4
执行之后,得到 Mobilenet-SSD/examples 文件夹里面的3个prototxt就是从模板生成的正式网络定义,根据原作者设置,其中的deploy文件是已经合并过bn层的,需要后面配套使用
data_param {
# 第 24 行
source: "/home/shs/data/VOCdevkit/cucumber/lmdb/cucumber_test_lmdb/"
batch_size: 8
backend: LMDB
}
annotated_data_param {
batch_sampler {
}
# 第 31 行
label_map_file: "/home/shs/caffe-ssd/data/cucumber/labelmap_voc_cucumber.prototxt"
MobileNetSSD_train.prototxt:
data_param {
# 第 49 行
source: "/home/shs/data/VOCdevkit/cucumber/lmdb/cucumber_trainval_lmdb/"
batch_size: 24
backend: LMDB
..........................
max_sample: 1
max_trials: 50
}
# 第 136 行
label_map_file:
"/home/shs/caffe-ssd/data/cucumber/labelmap_voc_cucumber.prototxt"
}
Mobilenet-ssd目录下的 solver_train.prototxt 和 solver_test.prototxt
solver_mode: CPU
???为啥
#../../build/tools/caffe train -solver="solver_train.prototxt" \
../caffe-ssd/build/tools/caffe train -solver="solver_train.prototxt" \
./train.sh
train.sh里的内容解析:(根据自己的路径实际情况做微调)
第2行是train.prototxt的路径,第7行是snapshot保存中间模型的路径,第8行是slover文件的路径,第9行是预训练权重,第10行是用到的gpu编号,这些都可以按需修改。笔者将最后一行的gpu从0修改为0,1,可利用双GPU训练
solver_train.prototxt文件内容:
rain_net:“example/MobileNetSSD_train.prototxt” #训练用的网络文件
test_net:“example/MobileNetSSD_test.prototxt” #测试用的网络文件
test_iter: 673 #测试时的迭代次数
test_interval: 1000 #每训练1000次迭代一次
base_lr: 0.0005 #基准学习率
display: 5 #每5次迭代屏幕显示一次信息
max_iter: 20000 #最大迭代次数
lr_policy: “multistep” #学习率调整策略
gamma: 0.5
weight_decay: 0.00005 #权重衰减
snapshot: 1000 #每1000次迭代抓取一次快照
snapshot_prefix:“snapshot_power/mobilenet” #快照保存的前缀
solver_mode: GPU #这里一定要GPU
debug_info: false
snapshot_after_train: true
test_initialization: false #不做测试初始化
average_loss: 10 #每10次迭代平均下loss
stepvalue: 10000
stepvalue: 20000
iter_size: 1
type: “RMSProp” #一种优化方法,挖坑,以后填
eval_type: “detection” #这里一定要写检测,默认为classification
ap_version: “11point” #计算AP的方法
math_functions.cpp:250 Check failed: a (=b (0 vs -1.19209e-007)
training error: Data layer prefetch queue empty
// Figure out bbox dimension.
float bbox_width = scale * sqrt(aspect_ratio);
float bbox_height = scale / sqrt(aspect_ratio);
//renew
if(bbox_width>=1.0)
{
bbox_width=1.0;
}
if(bbox_height>=1.0)
{
bbox_height=1.0;
}
// Figure out top left coordinates.
float w_off, h_off;
caffe_rng_uniform(1, 0.f, 1 - bbox_width, &w_off);
caffe_rng_uniform(1, 0.f, 1 - bbox_height, &h_off);
!! 记得 make py
(3)Check failed: error == cudaSuccess (2 vs. 0) out of memory
https://blog.csdn.net/menglanzeng/article/details/97616685
我把train.prototxt中第50行的batch_size改为1
data_param {
source: "trainval_lmdb/"
batch_size: 1
backend: LMDB
}
更改
-weights="mobilenet_iter_73000.caffemodel" \
为:
-snapshot="snapshot/mobilenet_iter_XXXX.solverstate" \
这里XXXX是你以前停止训练的迭代次数。
如果您不知道要XXXX运行
ls -ltr snapshot/
则可以在底部找到最后的迭代。
然后接着上次训练
./train_resume.sh
理论上可以,但没成功。
python2 merge_bn.py --model ./example/MobileNetSSD_deploy.prototxt --weights ./snapshot/mobilenet_iter_10000.caffemodel
运行以下命令,MobileNet-SSD中多出 no_bn.prototxt 和 no_bn.caffemodel,这就是我们想要获得的模型文件和参数文件。
caffe_root = '/home/shs/caffe-ssd/'
……
#net_file= 'deploy.prototxt'
net_file= 'no_bn.prototxt'
#caffe_model='mobilenet_iter_73000.caffemodel'
caffe_model='no_bn.caffemodel'
#test_dir = "images" #测试的就是images文件夹里的图片
test_dir = "images"
……
CLASSES = ('background','p','d','w')
注意:测试的时候,终端运行时按回车键切换下一张图片,测完images文件夹里所有图片就退出终端了,要是点叉号关窗口,终端就退不出去了,Ctrl+C也不好使。
train_net: "example/MobileNetSSD_train.prototxt"
test_net: "example/MobileNetSSD_test.prototxt"
修改test.sh
#../../build/tools/caffe train -solver="solver_test.prototxt" \
../caffe-ssd/build/tools/caffe train -solver="solver_test.prototxt" \
./test.sh
查看loss值和detection_eval(mAP)评测模型效果
修改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
export GLOG_logtostderr=0
export GLOG_log_dir='../MobileNet-SSD/' #log存放位置
#../../build/tools/caffe train -solver="solver_train.prototxt" \
../caffe-ssd/build/tools/caffe train -solver="solver_train.prototxt" \
-weights="mobilenet_iter_73000.caffemodel" \
-gpu 0
训练完成后发现在我们保存的目录下生成了两个上锁log文件caffe.INFO和caffe.ubuntu.root.log.INFO.20170611-103712.5383。点击打开后我们可以看到我们所训练的日志文件。
利用生成的log文件绘制accuary loss曲线图
首先绘制图,caffe中其实已经自带了这样的小工具 caffe-master/tools/extra/parse_log.sh 和caffe-master/tools/extra/extract_seconds.py还有 caffe-master/tools/extra/plot_training_log.py.example;拷贝以上文件到当前训练模型的目录下。
然后我们到你保存的log文件目录下将1中保存的log文件解锁,解锁命令:
sudo chmod -R 777 ./caffe.ubuntu.root.log.INFO.20170611-103712.5383
解锁后我们就可以更改该log文件名为123.log(注意:要画图一定是.log文件,所以不改名不可以画)。
然后复制该xxx.log文件到你训练模型所在目录下。
然后就可以利用命令画图了:在模型所在目录下命令: ./plot_training_log.py.example y 0.png 123.log
./plot_training_log.py.example y 0.png 123.log
0.png是你保存的绘制出的图片名称,123.log是你保存的log文件名称。
y表示的是你的所绘制的图片到底是什么图片,具体解释如下:
y的数字代表意义(0~7):
Supported chart types: 0: Test accuracy vs. Iters (准确率与迭代次数图)
1: Test accuracy vs. Seconds (准确率与时间图)
2: Test loss vs. Iters (测试损失与迭代次数图)
3: Test loss vs. Seconds (测试损失与时间图)
4: Train learning rate vs. Iters (学习率与迭代次数图)
5: Train learning rate vs. Seconds (学习率与时间图)
6: Train loss vs. Iters (训练损失与迭代次数图)
7: Train loss vs. Seconds (训练损失与时间图)
运行后生成的文件有:log-data.log.test和log-data.log.test和xxx.png
参考网址:
https://blog.csdn.net/la_fe_/article/details/84928958
https://blog.csdn.net/nimo_cap/article/details/82888196
https://cloud.tencent.com/developer/article/1020066
https://zhuanlan.zhihu.com/p/95904525?from_voters_page=true