ubuntu下运行caffe下的“Hello World”——mnist手写体数字识别例程

前言

mnist例程几乎是所有深度学习入坑者首先要经历的,第一次跑是在windows下跑的,后来为了DL入坑Linux就没跑过了,因为几位小伙伴也有这方面需求,所以特意抽时间跑了一遍,将我的运行过程记录下来,希望可以帮到有希望的小伙伴。

环境说明:

笔者的系统环境为Ubuntu16.04,且默认大家已经安装配置好了caffe环境,如果有同学没有配置好caffe可以移步笔者的 另外一篇文章

主要步骤

1:下载mnist数据集
2:生成LMDB
3:网络配置
4:训练网络
5:测试网络
6:利用训练好的模型预测单张数字图片

下载mnist数据集

mnist数据集可以在caffe源码框架的data/mnist下用get_mnist.sh脚本下载,具体命令如下(在caffe根目录下执行):


1
./data/mnist/get_mnist.sh

生成LMDB

我们下载到的数据集为二进制文件,需要转化为LEVELDB或LMDB才能被caffe识别,转化命令如下(在caffe根目录下执行):


./examples/mnist/create_mnist.sh

执行完这条命令以后我们就会在examples/mnist下发现mnist_train_lmdb和mnist_test_lmdb两个文件夹,每个文件夹里都有data.lmdb和lock.lmdb两个文件。

网络配置

mnist使用的是lenet网络模型,其定义在mnist的lenet_train_test.prototxt文件中,只需要注意source参数文件路径:


layer {
name: “mnist”
type: “Data”
top: “data”
top: “label”
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: “examples/mnist/mnist_train_lmdb”
batch_size: 64
backend: LMDB
}
}
layer {
name: “mnist”
type: “Data”
top: “data”
top: “label”
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
//主要注意这里的路径为mnist_test_lmdb的路径就好(一般默认的路径都是对的)
source: “examples/mnist/mnist_test_lmdb”
batch_size: 100
backend: LMDB
}
}

训练网络

确保mnist的网络模型没有问题后我们在caffe根目录下输入以下命令开始训练网络:


./examples/mnist/train_lenet.sh

然后就是等待,大概十分钟左右就可以训练完毕,毕竟数据量小。

测试网络

利用训练好的lenet-5模型权值文件(examples/mnist/lenet_iter_10000.caffemodel)可以对测试数据集(或外部数据集)进行预测,在caffe根目录下运行如下命令:


./build/tools/caffe.bin test -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -iterations 100

命令行解释:

  • ./build/tools/caffe.bin test ,表示只做预测(forward前向传播计算),不进行参数更新(backward后向传播计算)
  • -model examples/mnist/lenet_train_test.prototxt ,指定模型描述文本文件
  • -weights examples/mnist/lenet_iter_10000.caffemodel ,指定模型预先训练好的权值文件
  • -iterations 100 ,指定测试迭代次数。参与测试的样例数目为(iterations*batch_size),batch_size在model
    prototxt中设定,为100时刚好覆盖10000个测试样本。

读者可运行上述命令,分析输出日志,与训练阶段输出做对比。

利用训练好的模型预测单张数字图片

参考: http://blog.csdn.net/xunan003/article/details/73126425
可能大家觉得上面的那些工作都没什么意思,就是敲一堆命令行+看一堆终端输出,所以我特意为大家准备了这部分测试预测自己的数字图片:

思路梳理

手写数字图片必须满足以下条件:

(1)必须是256位黑白色
(2)必须是黑底白字
(3)像素大小必须是28x28
(4)数字在中间,上下左右没有过多空白

利用模型lenet_iter_10000.caffemodel测试单张手写体数字所需要的文件:

(1)待测试图片(自己画的也行,网络上下的也行);

需要注意的是,不管是什么格式,都要转换为28*28大小的黑白灰度图像,具体转化方法请自行百度,不想转化的我这里提供给大家一组我转化好的图片资源供大家下载链接:https://pan.baidu.com/s/1boGHQzl 密码:qfd6
(2)deploy.prototxt(模型描述型文件);
(3)network.caffemodel(模型权值文件),在本例中就是lenet_iter_10000.caffemodel
(4)labels.txt(标签文件);
(5)mean.binaryproto(二进制图像均值文件);
(6)classification.bin(二进制程序名)。与二进制均值文件配合使用,只是均值文件不同的模型有不同的均值文件,而这个bin文件为通用的,就是任何模型都可以做分类使用。

所需文件生成

生成deploy.prototxt文件

deploy.prototxt文件和lenet_train_test.prototxt文件类似,或者说对后者改动可得到前者。在examples/mnist目录下复制一份lenet_train_test.prototxt修改并保存后得到deploy.prototxt如下:


name: “LeNet”
layer {
name: “data”
type: “Input”
top: “data”
input_param{shape:{dim:1 dim:1 dim:28 dim:28}}
}

layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  convolution_param {
    num_output: 20
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  convolution_param {
    num_output: 50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "ip1"
  type: "InnerProduct"
  bottom: "pool2"
  top: "ip1"
  inner_product_param {
    num_output: 500
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "ip1"
  top: "ip1"
}
layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  inner_product_param {
    num_output: 10
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "ip2"
  top: "prob"
}

生成labels.txt标签文件

在当前目录下新建一个txt文件,命名为synset_words.txt,里面内容为我们训练mnist的图片内容,共有0~9十个数,那么我们就建立如下内容的标签文件:

5 生成mean.binaryproto二进制均值文件

caffe作者为我们提供了一个计算均值的文件compute_image_mean.cpp,放在caffe根目录下的tools文件夹里面,运行下面命令生成mean.binaryproto二进制均值文件:

sudo build/tools/compute_image_mean examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto  

生成的mean.binaryproto均值文件保存在了examples/mnist目录下。

分类器classification.bin

在example文件夹中有一个cpp_classification的文件夹,打开它,有一个名为classification的cpp文件,这就是caffe提供给我们的调用分类网络进行前向计算,得到分类结果的接口。

开始测试

在caffe根目录下命令:


./build/examples/cpp_classification/classification.bin examples/mnist/deploy.prototxt examples/mnist/lenet_iter_10000.caffemodel examples/mnist/mean.binaryproto examples/mnist/synset_words.txt examples/images/3.jpg

然后就可以看到预测结果:
6

如果觉得有帮助就请我喝杯咖啡鼓励我继续创作吧^_^