最近开始学习caffe,最开始应该是因为自己急功近利,想直接用caffe模型达到自己的目的,感觉有点无从下手。现在不得不踏实下来,扎实的一步步学习。看了大牛徐其华随笔分类 - caffe系列教程,收获颇丰。在这里记录下自己学习训练和测试模型的过程,可以说相关知识是完全来自Caffe学习系列(12):训练和测试自己的图片,只是记录一下自己实践中的问题和感悟。
在这里,再次对乐于分享的博主徐其华表示衷心的感谢,谢谢^_^!
原文如下(有更改):
一、准备数据
有条件的同学,可以去imagenet的官网http://www.image-net.org/download-images,下载imagenet图片来训练。但是我没有下载,一个原因是注册账号的时候,验证码始终出不来(听说是google网站的验证码,而我是上不了google的)。第二个原因是数据太大了。。。
我去网上找了一些其它的图片来代替,共有500张图片,分为大巴车、恐龙、大象、鲜花和马五个类,每个类100张。需要的同学,可到我的网盘下载:http://pan.baidu.com/s/1nuqlTnN
编号分别以3,4,5,6,7开头,各为一类。我从其中每类选出20张作为测试,其余80张作为训练。因此最终训练图片400张,测试图片100张,共5类。我将图片放在caffe根目录下的data文件夹下面。即训练图片目录:data/re/train/> ,测试图片目录: data/re/test/
二、转换为lmdb格式
首先,在examples下面创建一个myfile的文件夹,来用存放配置文件和脚本文件。然后编写一个脚本create_filelist.sh,用来生成train.txt和test.txt清单文件
# sudo mkdir examples/myfile
# sudo vi examples/myfile/create_filelist.sh
编辑此文件,写入如下代码,并保存
#!/usr/bin/env sh
DATA=data/re/
MY=examples/myfile
echo "Creating train.txt..."
rm -rf $MY/train.txt
for i in 3 4 5 6 7
do
find $DATA/train -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/train.txt
done
echo "Done."
echo "Creating test.txt..."
rm -rf $MY/test.txt
for i in 3 4 5 6 7
do
find $DATA/test -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/test.txt
done
echo "All done."
然后,运行此脚本(注意是在caffe根目录下)
sh examples/myfile/create_filelist.sh
成功的话,就会在examples/myfile/ 文件夹下生成train.txt和test.txt两个文本文件,里面就是图片的列表清单。
接着再编写一个脚本文件,调用convert_imageset命令来转换数据格式。
# sudo vi examples/myfile/create_lmdb.sh
插入:
#!/usr/bin/env sh
MY=examples/myfile
echo "Creating train lmdb..."
rm -rf $MY/img_train_lmdb
build/tools/convert_imageset \
--shuffle \
--resize_height=256 \
--resize_width=256 \
/home/gph/Desktop/caffe_cmake/caffe-master/data/re/ \
$MY/train.txt \
$MY/img_train_lmdb
echo "Done."
echo "Creating test lmdb.."
rm -rf $MY/img_test_lmdb
build/tools/convert_imageset \
--shuffle \
--resize_width=256 \
--resize_height=256 \
/home/gph/Desktop/caffe_cmake/caffe-master/data/re/ \
$MY/test.txt \
$MY/img_test_lmdb
echo "All Done."
因为图片大小不一,因此我统一转换成256*256大小。运行成功后,会在
examples/myfile下面生成两个文件夹img_train_lmdb和img_test_lmdb,分别用于保存图片转换后的lmdb文件。三、计算均值并保存
图片减去均值再训练,会提高训练速度和精度。因此,一般都会有这个操作。
caffe程序提供了一个计算均值的文件compute_image_mean.cpp,我们直接使用就可以了
# sudo build/tools/compute_image_mean examples/myfile/img_train_lmdb examples/myfile/mean.binaryproto
compute_image_mean带两个参数,第一个参数是lmdb训练数据位置,第二个参数设定均值文件的名字及保存路径。 运行成功后,会在
examples/myfile/ 下面生成一个mean.binaryproto的均值文件。四、创建模型并编写配置文件
模型就用程序自带的caffenet模型,位置在 models/bvlc_reference_caffenet/文件夹下,
将需要的两个配置文件,复制到myfile文件夹内
# sudo cp models/bvlc_reference_caffenet/solver.prototxt examples/myfile/
# sudo cp models/bvlc_reference_caffenet/train_val.prototxt examples/myfile/
修改其中的solver.prototxt
# sudo vi examples/myfile/solver.prototxt
net: "examples/myfile/train_val.prototxt"
test_iter: 2
test_interval: 50
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 100
display: 20
max_iter: 500
momentum: 0.9
weight_decay: 0.005
solver_mode: GPU
snapshot: 200
snapshot_prefix: "examples/myfile/minemodel"
100个测试数据,batch_size为50,因此test_iter设置为2,就能全cover了。在训练过程中,调整学习率,逐步变小。
修改train_val.protxt,只需要修改两个阶段的data层就可以了,其它可以不用管。
name: "CaffeNet"
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
mirror: true
crop_size: 227
mean_file: "examples/myfile/mean.binaryproto"
}
data_param {
source: "examples/myfile/img_train_lmdb"
batch_size: 256
backend: LMDB
}
}
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
mirror: false
crop_size: 227
mean_file: "examples/myfile/mean.binaryproto"
}
data_param {
source: "examples/myfile/img_test_lmdb"
batch_size: 50
backend: LMDB
}
}
实际上就是修改两个data layer的mean_file和source这两个地方,其它都没有变化 。
五、训练和测试
如果前面都没有问题,数据准备好了,配置文件也配置好了,这一步就比较简单了。
# sudo build/tools/caffe train -solver examples/myfile/solver.prototxt
运行时间和最后的精确度,会根据机器配置,参数设置的不同而不同。我的是gpu+cudnn运行500次,大约8分钟,精度为95%。
遇到的问题:
一、GPU显存不够
按照楼主的设置跑的话,很有可能会出现如下错误:
Check failed: error == cudaSuccess (2 vs. 0) out of memory
这就是显存不够的原因。修改train_val.prototxt中train层和test层中的batch_size为1(最小了,也可以适当改大点看看极限。楼主先是50不行,改成1了,写博客实验时发现改成50又行了。。。很是奇怪),对应的solver.prototxt中的test_iter改为100,进行测试。
二、没有.caffemodel模型出来
原博客solver.prototxt末尾将
snapshot: 200
snapshot_prefix: "examples/myfile/minemodel"
这两句话删除了,就不会生成训练好的模型。加上这两句,就会再examples/myfile/路径下生成minemodel_iter_200.caffemodel,minemodel_iter_200.solverstate等一系列文件。这两句话的作用就很明显了。
三、正确率
博主进行了多次实验,结果如下:
batch_size 4:
I1027 08:55:05.108747 3620 solver.cpp:317] Iteration 500, loss = 1.07896
I1027 08:55:05.108803 3620 solver.cpp:337] Iteration 500, Testing net (#0)
I1027 08:55:06.499388 3620 solver.cpp:404] Test net output #0: accuracy = 0.66
I1027 08:55:06.499451 3620 solver.cpp:404] Test net output #1: loss = 0.878872 (* 1 = 0.878872 loss)
I1027 08:55:06.499477 3620 solver.cpp:322] Optimization Done.
I1027 08:55:06.499495 3620 caffe.cpp:254] Optimization Done.
batch_size 25:
I1027 09:10:17.994113 3691 solver.cpp:317] Iteration 500, loss = 0.213029
I1027 09:10:17.994165 3691 solver.cpp:337] Iteration 500, Testing net (#0)
I1027 09:10:18.840204 3691 solver.cpp:404] Test net output #0: accuracy = 0.92
I1027 09:10:18.840255 3691 solver.cpp:404] Test net output #1: loss = 0.226978 (* 1 = 0.226978 loss)
I1027 09:10:18.840271 3691 solver.cpp:322] Optimization Done.
I1027 09:10:18.840282 3691 caffe.cpp:254] Optimization Done.
batch_size 40:
I1027 09:25:46.159993 3747 solver.cpp:317] Iteration 500, loss = 0.0773205
I1027 09:25:46.160049 3747 solver.cpp:337] Iteration 500, Testing net (#0)
I1027 09:25:47.182668 3747 solver.cpp:404] Test net output #0: accuracy = 0.933333
I1027 09:25:47.182724 3747 solver.cpp:404] Test net output #1: loss = 0.216487 (* 1 = 0.216487 loss)
I1027 09:25:47.182741 3747 solver.cpp:322] Optimization Done.
I1027 09:25:47.182752 3747 caffe.cpp:254] Optimization Done.
batch_size 50:
I1027 11:02:35.578799 6155 solver.cpp:317] Iteration 500, loss = 0.11367
I1027 11:02:35.578866 6155 solver.cpp:337] Iteration 500, Testing net (#0)
I1027 11:02:36.411149 6155 solver.cpp:404] Test net output #0: accuracy = 0.95
I1027 11:02:36.411223 6155 solver.cpp:404] Test net output #1: loss = 0.176876 (* 1 = 0.176876 loss)
I1027 11:02:36.411248 6155 solver.cpp:322] Optimization Done.
I1027 11:02:36.411267 6155 caffe.cpp:254] Optimization Done.
这里我明白了caffe学习之路任长道远啊。