一.概述
caffe使用c++实现,架构精简,可移植性非常好,而本人对c++比较熟悉,就选了这个框架.caffe的运行提供三种接口:c++ ,python接口和matlab接口.
二.基础命令
caffe的c++主程序(caffe.cpp)放在根目录下的tools文件夹内, 当然还有一些其它的功能文件,如:convert_imageset.cpp, train_net.cpp, test_net.cpp等也放在这个文件夹内。经过编译后,这些文件都被编译成了可执行文件,放在了 ./build/tools/ 文件夹内。因此我们要执行caffe程序,都需要加 ./build/tools/ 前缀,也可以增加环境变量,可以直接运行caffe -help
如:
# sudo sh ./build/tools/caffe train --solver=examples/mnist/train_lenet.sh
caffe程序的命令行执行格式如下:
caffe <command> <args>
其中的<command>有这样四种:
- train
- test
- device_query
- time
对应的功能为:
train----训练或finetune模型(model),
test-----测试模型
device_query---显示gpu信息
time-----显示程序执行时间
其中的<args>参数有:
- -solver
- -gpu
- -snapshot
- -weights
- -iteration
- -model
- -sighup_effect
- -sigint_effect
注意前面有个-符号。对应的功能为:
-solver:必选参数。一个protocol buffer类型的文件,即模型的配置文件。如:
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt
-gpu: 可选参数。该参数用来指定用哪一块gpu运行,根据gpu的id进行选择,如果设置为'-gpu all'则使用所有的gpu运行。如使用第二块gpu运行:
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 2
-snapshot:可选参数。该参数用来从快照(snapshot)中恢复训练。可以在solver配置文件设置快照,保存solverstate。如:
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -snapshot examples/mnist/lenet_iter_5000.solverstate
-weights:可选参数。用预先训练好的权重来fine-tuning模型,需要一个caffemodel,不能和-snapshot同时使用。如:
# ./build/tools/caffe train -solver examples/finetuning_on_flickr_style/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
-iterations: 可选参数,迭代次数,默认为50。 如果在配置文件文件中没有设定迭代次数,则默认迭代50次。
-model:可选参数,定义在protocol buffer文件中的模型。也可以在solver配置文件中指定。
-sighup_effect:可选参数。用来设定当程序发生挂起事件时,执行的操作,可以设置为snapshot, stop或none, 默认为snapshot
-sigint_effect: 可选参数。用来设定当程序发生键盘中止事件时(ctrl+c), 执行的操作,可以设置为snapshot, stop或none, 默认为stop
刚才举例了一些train参数的例子,现在我们来看看其它三个<command>:
test参数用在测试阶段,用于最终结果的输出,要模型配置文件中我们可以设定需要输入accuracy还是loss. 假设我们要在验证集中验证已经训练好的模型,就可以这样写
# ./build/tools/caffe test -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 100
这个例子比较长,不仅用到了test参数,还用到了-model, -weights, -gpu和-iteration四个参数。意思是利用训练好了的权重(-weight),输入到测试模型中(-model),用编号为0的gpu(-gpu)测试100次(-iteration)。
time参数用来在屏幕上显示程序运行时间。如:
# ./build/tools/caffe time -model examples/mnist/lenet_train_test.prototxt -iterations 10
这个例子用来在屏幕上显示lenet模型迭代10次所使用的时间。包括每次迭代的forward和backward所用的时间,也包括每层forward和backward所用的平均时间。
# ./build/tools/caffe time -model examples/mnist/lenet_train_test.prototxt -gpu 0
这个例子用来在屏幕上显示lenet模型用gpu迭代50次所使用的时间。
# ./build/tools/caffe time -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 10
利用给定的权重,利用第一块gpu,迭代10次lenet模型所用的时间。
device_query参数用来诊断gpu信息。
# ./build/tools/caffe device_query -gpu 0
最后,我们来看两个关于gpu的例子
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 0,1
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -gpu all
这两个例子表示: 用两块或多块GPU来平行运算,这样速度会快很多。但是如果你只有一块或没有gpu, 就不要加-gpu参数了,加了反而慢。
最后,在linux下,本身就有一个time命令,因此可以结合进来使用,因此我们运行mnist例子的最终命令是(一块gpu):
$ sudo time ./build/toos/caffe train -solver examples/mnist/lenet_solver.prototxt
使用自己的网络训练:
1./examples/mynet/create_imagenet.sh
#!/usr/bin/env sh
# Create the imagenet lmdb inputs
# N.B. set the path to the imagenet train + val data dirs
set -e
EXAMPLE=examples/mynet #网络位置
DATA_HOME=/media/psf/Ubuntu/4.openSource/ai/faceData/VOCdevkit/myfacedetect/LMDB#数据位置
DATA=$DATA_HOME
TOOLS=build/tools
TRAIN_DATA_ROOT=$DATA/train/ #训练数据位置
VAL_DATA_ROOT=$DATA/val/#测试数据位置
# Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
RESIZE=true
if $RESIZE; then
RESIZE_HEIGHT=256 #图片大小重改
RESIZE_WIDTH=256 #图片大小重改
else
RESIZE_HEIGHT=0
RESIZE_WIDTH=0
fi
if [ ! -d "$TRAIN_DATA_ROOT" ]; then
echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet training data is stored."
exit 1
fi
if [ ! -d "$VAL_DATA_ROOT" ]; then
echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet validation data is stored."
exit 1
fi
echo "Creating train lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$TRAIN_DATA_ROOT \
$DATA/train.txt \
$EXAMPLE/mynet_train_lmdb
echo "Creating val lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$VAL_DATA_ROOT \
$DATA/val.txt \
$EXAMPLE/mynet_val_lmdb
echo "Done."
生成train ldb 和测试val ldb
注意:一定要仔细小心的路径要写对了,目录确定是在的
2.使用ldb生成mynet_mean.binaryproto
制作均值文件。
这个是为了图片归一化而生成的图片平均值文件,把所有的图片相加起来,做平均,具体的脚本如下:
#!/usr/bin/env sh
# Compute the mean image from the imagenet training lmdb
# N.B. this is available in data/ilsvrc12
EXAMPLE=examples/mynet
DATA=data/mynet
TOOLS=build/tools
$TOOLS/compute_image_mean $EXAMPLE/mynet_train_lmdb \
$DATA/mynet_mean.binaryproto
echo "Done."
./examples/mynet/imagenet/make_imagenet_mean.sh
生成mynet_mean.binaryproto
目录不对报错
jerry@ubuntu:~/work/3.project/1.ai/caffe/caffe$ ./examples/mynet/imagenet/make_imagenet_mean.sh
I1214 16:46:25.026000 3699 db_lmdb.cpp:35] Opened lmdb examples/mynet/mynet_train_lmdb
I1214 16:46:25.028149 3699 compute_image_mean.cpp:70] Starting iteration
I1214 16:46:25.042284 3699 compute_image_mean.cpp:101] Processed 51 files.
I1214 16:46:25.043436 3699 compute_image_mean.cpp:108] Write to data/mynet/mynet_mean.binaryproto
F1214 16:46:25.049476 3699 io.cpp:69] Check failed: proto.SerializeToOstream(&output)
*** Check failure stack trace: ***
@ 0x7ff0c43fa5cd google::LogMessage::Fail()
@ 0x7ff0c43fc433 google::LogMessage::SendToLog()
@ 0x7ff0c43fa15b google::LogMessage::Flush()
@ 0x7ff0c43fce1e google::LogMessageFatal::~LogMessageFatal()
@ 0x7ff0c48ea415 caffe::WriteProtoToBinaryFile()
@ 0x4029b2 main
@ 0x7ff0c336a830 __libc_start_main
@ 0x402bb9 _start
@ (nil) (unknown)
Aborted (core dumped)
Done.
jerry@ubuntu:~/work/3.project/1.ai/caffe/caffe$ ./examples/mynet/imagenet/make_imagenet_mean.sh
I1214 16:58:52.339138 6476 db_lmdb.cpp:35] Opened lmdb examples/mynet/mynet_train_lmdb
I1214 16:58:52.363159 6476 compute_image_mean.cpp:70] Starting iteration
I1214 16:58:52.382580 6476 compute_image_mean.cpp:101] Processed 51 files.
I1214 16:58:52.383329 6476 compute_image_mean.cpp:108] Write to data/mynet/mynet_mean.binaryproto
I1214 16:58:52.386101 6476 compute_image_mean.cpp:114] Number of channels: 3
I1214 16:58:52.386500 6476 compute_image_mean.cpp:119] mean_value channel [0]: 102.964
I1214 16:58:52.386674 6476 compute_image_mean.cpp:119] mean_value channel [1]: 109.14
I1214 16:58:52.386775 6476 compute_image_mean.cpp:119] mean_value channel [2]: 110.487
examples/mynet/train_caffenet.sh
jerry@ubuntu:~/work/3.project/1.ai/caffe/caffe$./examples/mynet/train_caffenet.sh
I1214 18:44:05.357269 22592 data_layer.cpp:73] Restarting data prefetching from start.