今年开始接触深度学习,之前很多工作都没有写博客觉得很可惜,决定从这次实验开始记录过程。第一次写,缺点比较多,欢迎大家提建议,以后改正。
一、数据
数据是我从网上下载的,后期打算自己采集图片再进行一次实验。数据集由三类图片构成,分别是bike,person和both,每类200张,一共600张。需要的同学可以从我的网盘下载,也可以自己找图片进行训练。网盘链接:链接:http://pan.baidu.com/s/1mihxBnU 密码:61t6然后分成数据集和测试集,测试集450张,每类150张,训练集150张,每类50张。建两个文件夹分别存放,路径是caffe-master/data/mydata/train 和caffe-master/data/mydata/val。因为接下来的程序要求图片大小一致,所以第一步是图片预处理,把图片都处理成256*256的,具体程序如下:(这步也可以省略,用后面的脚本进行处理更加方便。)
/**********************************************
* 批量更改图片大小
* Win10 + VS2015 + Opencv 3.1.0
* Sun Ruiyun
* 2017 / 07 / 06
***********************************************/
#include "stdafx.h"
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
int k;
for (k = 1; k <= 9; k++)
{
char imageName[100];
char imageSave[100];
sprintf_s(imageName, "D:\\documents\\visual studio 2015\\Projects\\resize\\resize\\resize\\bikes\\both_00%d.bmp", k);
sprintf_s(imageSave, "D:\\documents\\visual studio 2015\\Projects\\resize\\resize\\resize\\aft_bikes\\both00%d.bmp", k);
Mat src_img = imread(imageName);//读入图片数据
Mat dst_img1;
resize(src_img, dst_img1, Size(256, 256), 0, 0, CV_INTER_LINEAR); // 双线性插值
imwrite(imageSave, dst_img1);
waitKey(0);
}
}
用程序处理完的图片如下图所示,都是256*256大小的图片。
二、转换成lmdb格式
首先,在examples下面创建一个mydata的文件夹,来用存放配置文件和脚本文件。然后编写一个脚本create_filelist.sh,用来生成train.txt和test.txt清单文件.
sudo mkdir examples/mydata
sudo vi examples/mydata/create_filelist.sh
图片清单由图片名称+空格+序号组成。可使用如下程序来生成,把代码写入文件并保存
#!/usr/bin/env sh
DATA=data/mydata/
echo "Create train.txt..."
rm -rf $DATA/train.txt
find $DATA/train -name bike*.bmp| cut -d '/' -f 5 | sed "s/$/ 0/">>$DATA/train.txt
find $DATA/train -name person*.bmp| cut -d '/' -f 5 | sed "s/$/ 1/">>$DATA/train.txt
find $DATA/train -name both*.bmp| cut -d '/' -f 5 | sed "s/$/ 2/">>$DATA/train.txt
echo "Create val.txt..."
rm -rf $DATA/val.txt
find $DATA/val -name bike*.bmp| cut -d '/' -f 5 | sed "s/$/ 0/">>$DATA/val.txt
find $DATA/val -name person*.bmp| cut -d '/' -f 5 | sed "s/$/ 1/">>$DATA/val.txt
find $DATA/val -name both*.bmp| cut -d '/' -f 5 | sed "s/$/ 2/">>$DATA/val.txt
echo "All done"
然后运行此脚本
sudo sh examples/mydata/create_filelist.sh
接下来就需要把图片转成lmdb格式了:
sudo vi examples/mydata/create_mydata_lmdb.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/mydata
DATA=data/mydata
TOOLS=build/tools
TRAIN_DATA_ROOT=/home/sun/caffe-master/data/mydata/train/
VAL_DATA_ROOT=/home/sun/caffe-master/data/mydata/val/
RESIZE=true
if $RESIZE; then
RESIZE_HEIGHT=256
RESIZE_WIDTH=256
else
RESIZE_HEIGHT=0
RESIZE_WIDTH=0
fi
echo "Creating train lmdb..."
rm -rf $EXAMPLE/mydata_train_lmdb
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$TRAIN_DATA_ROOT \
$DATA/train.txt \
$EXAMPLE/mydata_train_lmdb
echo "Creating val lmdb..."
rm -rf $EXAMPLE/mydata_val_lmdb
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$VAL_DATA_ROOT \
$DATA/val.txt \
$EXAMPLE/mydata_val_lmdb
echo "Done."
后来我才发现,上面这个脚本直接就可以resize 图片,所以大家也可以不用之前的程序进行resize,而直接用这个脚本。然后运行脚本
sudo sh examples/mydata/creat_mydata_lmdb.sh
运行结束会生成两个lmdb格式的文件,如下:
三、计算均值
图片减去均值再训练,会提高训练速度和精度。因此,一般都会有这个操作。
同样的,我们先创建一个脚本文件:
sudo vi examples/mydata/make_mydata_mean.sh
编辑
#!/usr/bin/env sh
EXAMPLE=examples/mydata
DATA=data/mydata
TOOLS=build/tools
rm -rf $DATA/mydata_mean.binaryproto
$TOOLS/compute_image_mean $EXAMPLE/mydata_train_lmdb \
$DATA/mydata_mean.binaryproto
echo "Done."
然后运行
sudo sh examples/mydata/make_mydata_mean.sh
运行成功后生成一个mydata_mean.binaryproto文件,在以后运用。生成文件如下
四、创建模型并编写配置文件
我们用caffe自带的caffenet模型进行实验,位置在 models/bvlc_reference_caffenet/文件夹下, 将需要的两个配置文件,复制到mydata文件夹内
sudo cp models/bvlc_reference_caffenet/solver.prototxt examples/mydata/
sudo cp models/bvlc_reference_caffenet/train_val.prototxt examples/mydata/
然后打开solver.prototxt进行修改:我的修改如下,大家可根据需要自己设置参数:
net: "/home/sun/caffe-master/examples/mydata/train_val.prototxt"
test_iter: 3
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
snapshot: 50
snapshot_prefix: "examples/mydata/caffenet_train"
solver_mode: CPU
再打开train_val.prototxt进行修改,只需要修改两个data层,把需要的文件路径改成自己的文件路径即可,其他的不需要修改。
name: "CaffeNet"
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
mirror: true
crop_size: 227
mean_file: "data/mydata/mydata_mean.binaryproto" //第一处
}
data_param {
source: "examples/mydata/mydata_train_lmdb" //第二处
batch_size:150 //第三处
backend: LMDB
}
}
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
mirror: false
crop_size: 227
mean_file: "data/mydata/mydata_mean.binaryproto" //第四处
}
data_param {
source: "examples/mydata/mydata_val_lmdb" //第五处
batch_size:50 //第六处
backend: LMDB
}
}
五、训练和测试
最后一步,输入训练命令,就开始训练啦!
sudo build/tools/caffe train -solver examples/mydata/solver.prototxt
训练的时间和精度与设备和参数有关,可通过调整提高。我的是仅CPU模式,所以运行的时间比较久。训练结果如下:
学习过程中参考了很多博客:
http://blog.csdn.net/maweifei/article/details/53024380
http://www.cnblogs.com/denny402/p/5083300.html