caffe笔记:测试自己的手写数字图片

2017-02-08 Lu Huang 更多博文 » 博客 » GitHub »

原文链接 https://hlthu.github.io/caffe/2017/02/08/caffe-mnist-my-picture.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


在前面的caffe笔记:运行手写数字识别例程一节中,我们已经运行了caffe的mnist例程,并且训练出了自己的模型,并用自己的模型对测试集进行了预测,结果还是比较理想的。本节主要阐述如何把自己的手写数字图片(28×28)送入到上一节训练得到的LeNet模型中进行预测,评估数字识别效果。

1. 准备数据

我们需要准备自己的手写数据,由于之前我们下载的是黑底白字且是28×28的图片,我们这里可以用画图软件画几个出来,为了简单,我就花了3个数字:0,1和7。如下图所示,读者也可以从我的github上下载

my-mnist

2. 准备相关设置

如想用自己的手写数字,通过训练好的模型来识别这个数字,可以使用caffe中build/examples/cpp_classification/classification.bin这个程序来实现。这个可执行文件地输入参数如下。

./build/examples/cpp_classification/classification.bin \
    deploy.prototxt    \   // 模型描述文件
    network.caffemodel \   // 模型权值文件
    mean.binaryproto   \   // 图像均值文件
    labels.txt         \   // 图像类别标签信息
    img.jpg                // 输入待分类图像

需要分别提供模型描述文件、模型权值文件、图像均值文件、图像类别标签信息和输入待分类图像。其中输入待分类图像在上一步已经准备好,模型权值文件在上一节已经训练好了,我们还需要提供模型描述文件、图像均值文件和图像类别标签信息。

2.1 图像类别标签信息

提供这个最简单,只需要新建一个label.txt,然后其内容为:

0
1
2
3
4
5
6
7
8
9

2.2 图像均值文件

caffe框架为我们提供了一个计算均值的文件compute_image_mean.cpp,放在caffe根目录下的tools文件夹里面。编译后的可执行体放在build/tools/下面,我们直接调用就可以了,并将结果保存。该命令的是:

./build/tools/compute_image_mean \
    examples/mnist/mnist_train_lmdb \
    my-mnist/mean.binaryproto

compute_image_mean的两个参数一次是:

  • examples/mnist/mnist_train_lmdb: 表示需要计算均值的数据,格式为lmdb的训练数据。
  • my-mnist/mean.binaryproto: 计算出来的结果保存文件。

2.3 模型描述文件

examples/mnist/lenet_train_test.prototxt复制一份修改如下,并保存成classificat_net.prototxt

// 将训练和测试用的mnist层删除,添加以下层
name: "LeNet"
layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 1 dim: 1 dim: 28 dim: 28 } }
}
......
// 中间的模型不改动,省略
......
// 将accuracy层和loss层删除,添加以下层
layer {
  name: "prob"
  type: "Softmax"
  bottom: "ip2"
  top: "prob"
}

自此数据和文件已经准备完毕,大致如下:

~/caffe/my-mnist$ ls -hl
total 24K
-rw-rw-r-- 1 huanglu huanglu  471  2月  8 15:42 0.png
-rw-rw-r-- 1 huanglu huanglu  306  2月  8 15:42 1.png
-rw-rw-r-- 1 huanglu huanglu  184  2月  8 15:41 7.png
-rw-rw-r-- 1 huanglu huanglu 1.7K  2月  8 16:29 classificat_net.prototxt
-rw-rw-r-- 1 huanglu huanglu   20  2月  8 16:19 label.txt
lrwxrwxrwx 1 huanglu huanglu   45  2月  8 16:29 lenet_iter_10000.caffemodel -> ../examples/mnist/lenet_iter_10000.caffemodel
-rw-rw-r-- 1 huanglu huanglu 3.1K  2月  8 16:23 mean.binaryproto

3. 开始测试

依次执行三条命令,得到的输出如下。

$ ./build/examples/cpp_classification/classification.bin \
> my-mnist/classificat_net.prototxt \
> my-mnist/lenet_iter_10000.caffemodel \
> my-mnist/mean.binaryproto \
> my-mnist/label.txt \
> my-mnist/7.png 
---------- Prediction for my-mnist/7.png ----------
1.0000 - "2"
0.0000 - "0"
0.0000 - "3"
0.0000 - "1"
0.0000 - "4"

$ ./build/examples/cpp_classification/classification.bin \
> my-mnist/classificat_net.prototxt \
> my-mnist/lenet_iter_10000.caffemodel \
> my-mnist/mean.binaryproto \
> my-mnist/label.txt \
> my-mnist/0.png 
---------- Prediction for my-mnist/0.png ----------
1.0000 - "0"
0.0000 - "1"
0.0000 - "3"
0.0000 - "4"
0.0000 - "2"

$ ./build/examples/cpp_classification/classification.bin \
> my-mnist/classificat_net.prototxt \
> my-mnist/lenet_iter_10000.caffemodel \
> my-mnist/mean.binaryproto \
> my-mnist/label.txt \
> my-mnist/1.png 
---------- Prediction for my-mnist/1.png ----------
1.0000 - "1"
0.0000 - "3"
0.0000 - "4"
0.0000 - "0"
0.0000 - "2"

可以发现1和0识别正确,而7被识别成了2,这是由于我的写法和mnist里老外的写法不太一致导致的。

但是细心的读者可能会发现,不管输入的是什么图片,预测的结果都是在0~4这5个中,至于原因我还没有找到,如果有读者找到了,请联系我:huanglu.th@gmail.com

参考

  1. ubuntu 16.04上配置cuda+caffe环境
  2. 深度学习——21天实战caffe:赵永科著,中国工信出版集团、电子工业出版社,2016年7月。
  3. caffe笔记:运行手写数字识别例程
  4. 深度学习框架Caffe学习笔记(6)-测试自己的手写数字图片