上一篇写了在windows下基于tensorflow的MNIST入门,这次用caffe,总之框架都先尝试一遍,了解一下
一、安装caffe
首先说明,这次是Ubuntu16.04上使用CPU模式
找到几个链接:
官网安装教程:官方安装文档
中文的一个详细安装链接:Ubuntu16.04安装Caffe(CPU Only)
CPU模式的安装还是很简单的,中文的安装教程已经很详细了,不再啰嗦,只有在安装python依赖库的时候出了点小问题,报出类似python-dateutil is incompatible的错误,这是版本太低导致的,可以进入caffe/python/目录下,执行
cat requirements.txt
查看安装依赖包的版本要求(如下图),哪个版本低就升级哪个,我当时的错误解决办法就是:
pip install python-dateutil --upgrade
在编译测试成功之后,准备导入MNIST数据
二、caffe网络结构简析
官网的详细教程:Training LeNet on MNIST with Caffe
简单翻译一下里面的内容,首先是数据处理层:
layer {
name: "mnist"
type: "Data"
transform_param {
scale: 0.00390625
}
data_param {
source: "mnist_train_lmdb"
backend: LMDB
batch_size: 64
}
top: "data"
top: "label"
}
使用64的批处理大小,把[0,1)区间划分为256个间隔,每个相差
0.00390625,该层会输出两个结果,一个是数据,一个是标签
其次是卷积层:
layer {
name: "conv1"
type: "Convolution"
param { lr_mult: 1 }
param { lr_mult: 2 }
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
bottom: "data"
top: "conv1"
}
卷积层以上一层的输出为输入,kernel size为5,stride为1,输出20个特征向量,权重采用xavier初始化(关于caffe权值初始化的文档可以参考:caffe中weight_filler),偏差采用constant初始化,默认为0,为了达到更快的收敛速度,将权重学习率和求解器在运行时给出的学习率设置成相同的值,偏差学习率设置成它们的两倍。
pooling 层:
layer {
name: "pool1"
type: "Pooling"
pooling_param {
kernel_size: 2
stride: 2
pool: MAX
}
bottom: "conv1"
top: "pool1"
}
pooling层的kernel size为2,stride也是2(可使得在相邻的pooling区域内无重叠)
全连接层:
layer {
name: "ip1"
type: "InnerProduct"
param { lr_mult: 1 }
param { lr_mult: 2 }
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
bottom: "pool2"
top: "ip1"
}
tensorflow最后的全连接层是连接了1024个神经元,这里是500
ReLU层:
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
innerproduct层:
layer {
name: "ip2"
type: "InnerProduct"
param { lr_mult: 1 }
param { lr_mult: 2 }
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
bottom: "ip1"
top: "ip2"
}
一开始看到这个ip层还是有点晕的,tensorflow里似乎没有类似的网络层次,后来找了几篇文档,并且在官方文档里找到了对它的描述(参考Inner Product / Fully Connected Layer),它实际就一个全连接层,将输入视为简单向量,并以单向量的形式生成输出,理解起来就是:IP层把输入blob的m个二维矩阵(图片)通过与权重矩阵的卷积运算,最终转化为了一个m*n的二维矩阵,这个二维矩阵感知了输入的m张图片的综合特征(参考关于caffe innerproduct层的理解)
Loss层:
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
}
没什么好解释的
另外就是mnist的solver相关,这些在$CAFFE_ROOT/examples/mnist/lenet_solver.prototxt文件里写的很详细,按照注释理解还是比较容易的
就是要记得把里面的GPU模式改成CPU模式(我用的是CPU),默认是GPU
三、训练和测试
进入caffe安装目录下,运行
./examples/mnist/train_lenet.sh
可以看到日志信息:
很详细的展示了每一层做了哪些操作,输入和输出的向量分别是多少(从这个角度来看,我还是更喜欢caffe的风格),然后开始迭代训练,先截取前500次迭代:
最后训练完成
测试:
在caffe/example/mnist目录下创建脚本:
vi test_lenet.sh
#写入以下内容:
#!/bin/bash
./build/tools/caffe test -model=examples/mnist/lenet_train_test.prototxt -weights=examples/mnist/lenet_iter_10000.caffemodel
保存退出后记得给一个执行权限,,然后回到caffe安装的目录,执行
./examples/mnist/test_lenet.sh
用上面训练的模型测试的结果如下: