参考:https://blog.csdn.net/alps1992/article/details/68491362
https://blog.csdn.net/fly_egg/article/details/53670047
https://blog.csdn.net/liuyan20062010/article/details/78032592
总体思路:
- 准备数据
- 生成txt清单
- 数据转换为lmdb格式
- 生成 meanfile 均值文件
- 配置网络
- 训练网络模型
- 调用模型进行分类识别
1. 准备数据
首先要准备自己的数据,就是你的图片,不同类别的图片,这些图片要分成两部分,多的部分作为训练集,少的部分作为测试集,然后留几张图片用来做最后的分类测试的。我在caffe根目录下建立一个文件夹myfile,用于存放数据文件和后面的caffe模型相关文件。即/home/qf/caffe/myfile,然后在myfile文件夹下建立build_lmdb和dataset两个文件夹,其中build_lmdb文件夹用于存放生成的lmdb文件,dataset文件夹存放图片数据。在dataset文件夹中新建两个文件夹,train和val分别放如训练集图片和验证集图片,均为15类场景图像。
2 生成train.txt 和val.txt清单
sudo vim /home/qf/caffe/myfile/dataset/ create_list.sh
#/usr/bin/env sh DATATRAIN=dataset/ DATATEST=dataset/ MY=dataset echo "create train.txt" rm -f $MY/train.txt for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 do find $DATATRAIN/train -name $i*.jpg| cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/train.txt done echo "create val.txt" rm -f $MY/val.txt for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 do find $DATATEST/val -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/test.txt done echo "all done"
运行此脚本
cd dataset
sudo sh dataset/create_list.sh
运行成功则在dataset文件夹下生成train.txt 和 val.txt
3 生成LMDB文件
在caffe root/examples/imagenet中有个create_imagenet.sh文件,我们将其复制到我们的build_lmdb文件夹下重命名为create_lmdb.sh,然后对其中需要修改的地方进行修改:
- 其中EXAMPLE=myfile/build_lmdb改为自己文件的路径
- DATA=myfile/dataset,改为自己的路径
- TRAIN_DATA_ROOT和TRAIN_DATA_ROOT修改到路径dataset,这里因为train.txt文件的路径是从dataset开始的
#!/usr/bin/env sh # Create the imagenet lmdb inputs # N.B. set the path to the imagenet train + val data dirs set -e EXAMPLE=myfile/build_lmdb DATA=myfile/dataset TOOLS=build/tools TRAIN_DATA_ROOT=/home/qf/caffe/myfile/dataset/train VAL_DATA_ROOT=/home/qf/caffe/myfile/dataset/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/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/val_lmdb echo "Done."
然后在终端里面执行
sudo sh build_lmdb /create_lmdb.sh
即可在build_lmdb文件夹下得到两个文件train_lmdb和val_lmdb
4 计算均值
利用刚才生成的 lmdb 文件生成均值文件,计算图像均值,使用的是examples/imagenet/make_imagenet_mean.sh
这个脚本,把它拷贝到自己的目录下:
cp examples/imagenet/make_imagenet_mean.sh myfile/build_lmdb/
然后修改该脚本:
EXAMPLE=/home/qf/git/myfile/build_lmdb
DATA=/home/qf/git/myfile/build_lmdb TOOLS=/home/qf/git/caffe/build/tools $TOOLS/compute_image_mean $EXAMPLE/train_lmdb \ $DATA/imagenet_mean.binaryproto echo "Done."
然后运行脚本
bash make_imagenet_mean.sh
在build_lmdb下生成均值文件
5 配置网络
编写参数的配置文件
首先拷贝网络
cp -r caffe/models/bvlc_reference_caffenet caffe/myfile
然后进入到这个网络文件夹下:
cd caffe/myfile/bvlc_reference_caffenet
修改 solver.prototxt,打开文件
vim solver.prototxt
net: "/home/qf/caffe/myfile/bvlc_reference_caffenet/train_val.prototxt" test_iter : 50 //测试迭代次数 test_interval : 100 //多少次迭代测试一次 base_lr : 0.01 //基础学习率 lr_policy : "step" gamma: 0.1 stepsize : 10000 display: 20 //多少次迭代显示一次 max_iter : 700 //一共迭代多少次 momentum : 0.9 weight_decay : 0.0005 snapshot : 700 //多少次迭代保存一次快照 snapshot_prefix : "/home/qf/caffe/myfile/bvlc_reference_caffenet/caffenet_train" //快照保存位置(也是结果的位置) solver_mode : CPU编写训练网络的配置文件
打开 train_val.prototxt文件:
vim train_val.prototxt
name: "CaffeNet" layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { mirror: true crop_size: 227 mean_file: "/home/qf/git/myfile/buile_lmdb/imagenet_mean.binaryproto" } # mean pixel / channel-wise mean instead of mean image # transform_param { # crop_size: 227 # mean_value: 104 # mean_value: 117 # mean_value: 123 # mirror: true # } data_param { source: "/home/qf/git/myfile/buile_lmdb/train_lmdb" batch_size: 256 backend: LMDB } } //下面的两处也要改
#最后一层 layer { name: "fc8_15" #修改名字,下面与之相关的都要改 type: "InnerProduct" bottom: "fc7" top: "fc8_15" param { lr_mult: 1 decay_mult: 1 } param { lr_mult: 2 decay_mult: 0 } inner_product_param { num_output: 15 #原来为1000,训练为n类,就写>=n,训练的为15类,我就写了15 weight_filler { type: "gaussian" std: 0.01 } bias_filler { type: "constant" value: 0 } } } layer { name: "accuracy" type: "Accuracy" bottom: "fc8_15" bottom: "label" top: "accuracy" include { phase: TEST } } layer { name: "loss" type: "SoftmaxWithLoss" bottom: "fc8_15" bottom: "label" top: "loss" }
6.训练网络
cd /home/qf/caffe
./build/tools/caffe train --solver=/home/qf/caffe/myfile/bvlc_reference_caffenet/solver.prototxt
说明:至此训练网络完成,文章中的路径可能存在问题,由于第一次弄得时候也是各种问题,所以参考的时候根据自己的路径具体设置
7.用训练的模型预测图片的类别
首先:
修改deploy.prototxt最后部分
layer { name: "fc8_15" type: "InnerProduct" bottom: "fc7" top: "fc8_15" inner_product_param { num_output: 15 #输出类别为15类,保持一致 } } layer { name: "prob" type: "Softmax" bottom: "fc8_15" top: "prob" }
其次:准备一张将要预测的图片,命名为1.jpg
然后:创建labels.txt:
在终端输入:
sudo caffe/build/examples/cpp_classification/classification.bin \
> caffe/myfile/deploy.prototxt \
> caffe/myfile/_iter_1000.caffemodel \
>caffe/myfile/mean.binaryproto \
>caffe/myfile/labels.txt \
> caffe/myfile/1.jpg
回车输出结果