官网地址:http://caffe.berkeleyvision.org/gathered/examples/mnist.html
一.准备数据
首先,我们需要从网上下载数据,在caffe根目录下运行一下命令
./data/mnist/get_mnist.sh
./examples/mnist/create_mnist.sh
运行完后,会出现如下两个文件:
mnist_train_lmdb, and mnist_test_lmdb
这两个文件的目的是下载mnist数据集,并产生lmdb的数据集格式,关于lmdb的内容在教程中有提及。
get_mnist.sh内容:
#!/usr/bin/env sh
# This scripts downloads the mnist data and unzips it.
DIR="$( cd "$(dirname "$0")" ; pwd -P )"
cd $DIR
echo "Downloading..." #下载手写数据集,http后面是手写数据集的网址
wget --no-check-certificate http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
wget --no-check-certificate http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
wget --no-check-certificate http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
wget --no-check-certificate http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
echo "Unzipping..." # 下载完成后解压
gunzip train-images-idx3-ubyte.gz
gunzip train-labels-idx1-ubyte.gz
gunzip t10k-images-idx3-ubyte.gz
gunzip t10k-labels-idx1-ubyte.gz
# Creation is split out because leveldb sometimes causes segfault
# and needs to be re-created.
echo "Done."
create_mnist.sh内容:
#!/usr/bin/env sh
# This script converts the mnist data into lmdb/leveldb format,
# depending on the value assigned to $BACKEND.
EXAMPLE=examples/mnist
DATA=data/mnist
BUILD=build/examples/mnist
BACKEND="lmdb"
echo "Creating ${BACKEND}..."
rm -rf $EXAMPLE/mnist_train_${BACKEND}
rm -rf $EXAMPLE/mnist_test_${BACKEND}
$BUILD/convert_mnist_data.bin $DATA/train-images-idx3-ubyte \
$DATA/train-labels-idx1-ubyte $EXAMPLE/mnist_train_${BACKEND} --backend=${BACKEND} #训练数据
$BUILD/convert_mnist_data.bin $DATA/t10k-images-idx3-ubyte \
$DATA/t10k-labels-idx1-ubyte $EXAMPLE/mnist_test_${BACKEND} --backend=${BACKEND} #测试数据
echo "Done."
convert_mnist_data.bin是由convert_minst_data.cpp编译生成的可执行文件,这个编译过程就是在caffe安装的时候完成的,这个函数接受四个参数:
1.$DATA/train-images-idx3-ubyte: 手写数字源文件
2.$DATA/train-labels-idx1-ubyte: 手写数字标签文件
3.$EXAMPLE/mnist_train_${BACKEND}
: 转换后数据的存储位置
4.–backend=${BACKEND} : 宏定义,转换数据的格式lmdb或leveldb
二. 网络模型
这个实验中使用的模型是LeNet,其模型结构如下:
首先,给出网络名称
name: "LeNet"
读入数据,构建数据层:
layer {
name: "mnist" //层名称
type: "Data" // 层类型:数据层
top: "data" //该层产生两个blobs,: data blobs
top: "label" //label blobs
include {
phase: TRAIN // 仅用于训练阶段
}
transform_param {
scale: 0.00390625 //将图像的像素值归一化,=1/256
}
data_param {
source: "examples/mnist/mnist_train_lmdb" //数据所在的文件路径
batch_size: 64 //批尺寸,是每次迭代时输入样本的数量
backend: LMDB //输入数据的类型为lmdb
}
}
然后是卷积层:
layer {
name: "conv1"
type: "Convolution" //层类型: 卷积层
bottom: "data" //该层的输入为data blobs, 由数据层产生
top: "conv1" //输出为卷积特征conv1
param {
lr_mult: 1 //权重w的学习率倍数
}
param {
lr_mult: 2 //权重b的学习率倍数,
}
convolution_param { //卷积参数
num_output: 20 //输出为20个特征图,其规模为(data_size-kernel_size + stride)*(data_size -kernel_size + stride)
kernel_size: 5 //卷积核为5x5
stride: 1 //卷积核的移动间隔为1
weight_filler {
type: "xavier" //权值初始化方法,这里用xavier......
}
bias_filler {
type: "constant" //偏置初始化为常量,默认为0
}
}
}
接着是池化层
layer {
name: "pool1"
type: "Pooling" //层类型:池化层
bottom: "conv1" // 该层的输入为conv1的输出结果
top: "pool1" //输出为pooling后的特征
pooling_param {
pool: MAX //pooling方式:最大值
kernel_size: 2 //pooling核为2x2
stride: 2 //间隔为2
}
}
全连接层
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2" //该层输入为上个池化层的输出
top: "ip1" //输出
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500 //500个输出
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
非线性层
layer {
name: "relu1"
type: "ReLU" //ReLU,限制线性单元,是一种激活函数,与sigmoid作用类似
bottom: "ip1"
top: "ip1"
}
准确率层
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST //仅用于测试数据,计算算法准确度
}
}
损失估计层
layer {
name: "loss"
type: "SoftmaxWithLoss" //多分类使用softMax回归计算损失
bottom: "ip2"
bottom: "label" //需要用到数据层产生的lable;
top: "loss"
}
完整网络结构可以在caffe根目录/examples/mnist/lenet.prototxt
中看到
三.需要创建solver文件进行模型优化
这个文件在$CAFFE_ROOT/examples/mnist/lenet_solver.prototxt
# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt" #网络模型文件路径
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100 #test的迭代次数,批处理大小为100, 100*100为测试集个数
# Carry out testing every 500 training iterations.
test_interval: 500 #训练时每迭代500次测试一次
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01 #学习率
momentum: 0.9 #动量
weight_decay: 0.0005 #权重衰减
# The learning rate policy#学习率策略
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# Display every 100 iterations #每迭代100次显示
display: 100
# The maximum number of iterations
max_iter: 10000 #最大迭代次数
# snapshot intermediate results#我感觉可能是每迭代5000次存储一次参数什么的。
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
# solver mode: CPU or GPU
solver_mode: GPU #使用GPU 训练
四.训练模型
在caffe根目录下输入:./examples/mnist/train_lenet.sh
train_lenet.sh文件内容如下:
#!/usr/bin/env sh
set -e
./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt $
目前为止就可以开始训练了。