windows下caffe+CPUOnly实现MNIST手写分类

本文详细介绍了如何在Windows环境下搭建Caffe深度学习框架,并通过手写数字数据集MNIST进行模型训练与测试的过程。从环境配置到数据集处理,再到模型训练与评估,提供了完整的实践指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

工具下载

微软官方移植的Caffe:https://github.com/Microsoft/caffe

对属性表的操作

需要把实例属性表的后缀改成vs可用的.props

打开同一个文件夹下的Caffe.sln,查看其中的属性表

<CpuOnlyBuild>true</CpuOnlyBuild>

       <UseCuDNN>false</UseCuDNN>

分别指的是只利用CPU的环境和利用GPU进行CUDA编程,只能二选一,保持一个为true。

如果想进行CUDA编程首先要确保自己的GPU是英伟达NVIDIA的,然后在https://developer.nvidia.com/cudnn下载cuDNN(CUDA Deep Neural Network library),一个专门为深度神经网络提供GPU加速的库。下载好解压缩之后,

 <!-- CuDNN 4 and 5 are supported -->

       <CuDnnPath></CuDnnPath>

要填写cuDNN的路径。

解决方案

可以看到,解决方案中有16个项目(不用数,有显示)。我们最关注的是caffe和libcaffe。

对caffe:

右击“解决方案‘Caffe’”,选择“属性”,将“配置属性”-“配置”修改成Release和x64

(这一步是使用Release来进行编译,若用Debug,则之后每次都要打开vs,会不方便)

注意:在上图顶部工具栏中的“解决方案配置”和“解决方案平台”框,若你的vs2013中将这两个框在工具栏中显示,则要在工具栏中将配置改成Release和x64,否则直接右击“解决方案Caffe”来更改配置是无效的。

对libcaffe:

右击解决方案中的libcaffe项目,选择“属性”,在打开的属性页中选择“C/C++”-“常规”,将“将警告视为错误”设为“否。然后右击libcaffe项目,生成。期间会利用NuGet对caffe的一些依赖文件进行自动还原。同时会在caffe-master的同级目录生成文件夹NugetPackages。里面是一些依赖库(包括OpenCV),这也是选择windows版caffe的好处。

这时候就可以生成解决方案了。但是打开解决方法的属性可以看到默认的是只编译libcaffe。我们可以选择编译其他项目。

此时在\caffe-master目录下会生成Build文件夹,即为我们编译成功的文件夹,而\caffe-master\Build\x64\Release目录下则会有我们编译出的caffe.exe执行文件。

MINIST下载、转换和训练

这是一个手写数字数据集,有60,000个训练样本,10,000个测试样本,测试集和训练集是没有交集的。数字尺寸都已经标准化,并且保证数字在图像中心。数字是20x20像素的,图像是28x28像素大小。

下载地址:http://yann.lecun.com/exdb/mnist/

train-images-idx3-ubyte.gz:  training set images (9912422 bytes)

train-labels-idx1-ubyte.gz:  training set labels (28881 bytes)

t10k-images-idx3-ubyte.gz:   test set images (1648877 bytes)

t10k-labels-idx1-ubyte.gz:   test set labels (4542 bytes)

图像是以矩阵在一个特殊的格式中存储的,所以是无法直接打开查看的。若发现下载的文件比官方给出的大,则说明浏览器已经自动解压缩了。这个时候只需要重命名就可以移除.gz文件了。

这四个文件不能直接用于caffe的训练和测试。需要利用生成的Release中的convert_mnist_data.exe把四个文件转换为caffe所支持的leveldb或lmdb文件。lmdb是lightning(闪电的) memory-mapped database manager的缩写,能够把原始数据通过更为高效的存储方式存储,从而加快读取和训练速度(lmdb比leveldb更快,可以看看刚刚的NugetPackages文件夹,当中就包含着对应的库)。具体转换方法如下:

a)      四个文件放到 . \examples\mnist\mnist_data文件夹下。

b)      在caffe-windows安装的根目录下,新建一个convert-mnist-data-train.bat文件转换为训练数据,并在文件中添加代码:

Build\x64\Release\convert_mnist_data.exe--backend=lmdbexamples\mnist\mnist_data\train-images.idx3-ubyteexamples\mnist\mnist_data\train-labels.idx1-ubyteexamples\mnist\mnist_data\mnist_train_lmdb 

Pause

再新建一个convert-mnist-data-test.bat转换测试数据,代码为:

Build\x64\Release\convert_mnist_data.exe--backend=lmdb examples\mnist\mnist_data\t10k-images.idx3-ubyteexamples\mnist\mnist_data\t10k-labels.idx1-ubyteexamples\mnist\mnist_data\mnist_test_lmdb 

Pause

运行

a)      转换好的训练\测试数据集(mnist_train_lmdb\ mnist_train_lmdb或mnist_train_leveldb\mnist_train_leveldb)文件夹放在.\examples\mnist中。

b)      修改lenet_solver.prototxt 中solver_mode: CPU;修改lenet_train_test.prototxt中

source:"examples/mnist/mnist_train_lmdb"

source:"examples/mnist/mnist_test_lmdb"

backend: LMDB

保证训练集和测试集的路径正确。

c)      在caffe-windows根目录下新建一个run.bat,文件中代码:

Build\x64\Release\caffe.exe  train--solver=examples/mnist/lenet_solver.prototxt 

Pause

d)      保存并双击运行run.bat,会开始打印一些日志文件。当迭代次数达到lenet_solver.prototxt定义的max_iter时,就可以认为训练结束了。训练完成后会在examples/mnist生成 .caffemodel 文件和 .solverstate 文件。分别是训练一半和训练结束的结果。

Ps:lenet_solver.prototxt是examples/mnist下的.prototxt文件。定义了网络的结构。可以用vs打开。

solver.prototxt是solver配置文件,规定了如何优化求解loss function(非凸函数没有解析解)。比如最常用的方法是Stochastic Gradient Descent (type:"SGD")。

这两个文件很重要,因为它们决定了网络是如何设计的,可以自己设计网络,从而生成自己的.caffemodel 文件

Ps: 官方文档Lenet NIST tutorial 给出的方法:在Linux下,直接利用

./data/mnist/get_mnist.sh
./examples/mnist/create_mnist.sh
得到MNIST文件并且转换为Lmdb格式。.sh是Linux下的脚本文件

测试

虽然之前的步骤应该都成功了,但是没有结果感觉还是不踏实。现在终于可以开始测试了。测试手写数字就是机器学习中的hello world,还有点小兴奋呢。

训练集图片均值文件

第一步,仍然要通过一个根目录下的bat文件利用release下面的compute_image_mean.exe。

bat命令:Build\x64\Release\compute_image_mean.exeexamples\mnist\mnist_train_lmdb mean.binaryproto --backend=lmdb

然后就可以得到一个mean.binaryproto文件。含义是图片减去均值后的残差图片。

然后我们需要修改\examples\mnist\lenet_train_test.prototxt。预处理transform_param中要添加mean_file文件。如下图:

开始mnist测试

依然是通过bat,利用的是caffe.exe。

Build\x64\Release\caffe.exe test--model=examples\mnist\lenet_train_test.prototxt-weights=examples\mnist\lenet_iter_10000.caffemodel

Pause

批处理文件一不小心写错了好几回。在这里我们指定了测试模式,随后指定模型和训练出来的参数。

 

可以看到前面是时间和日期。测试是以batch为单位进行的,从0~49一共50个batch。分别给出了每个batch的accuracy和loss。准确率在99%左右。

问题1:但是重新保存修改之后的\examples\mnist\lenet_train_test.prototxt预处理transform_param,即使用减去均值的残差图像,准确率反而下降了。如上图,准确率只有92%。

连接https://blog.youkuaiyun.com/swj110119/article/details/53423957的测试结果和我一样。他认为是均值预处理之后相对于均值滤波,图像变模糊了。这里其实有两个问题,一个是都说利用均值文件是为了提高准确率,但是这里却下降了;一个是预处理是简单地对测试图像进行图像相减呢,还是会重新调整网络权重,生成一个新的网络?

问题2:50个batch是由上面决定的呢?:”从一到二”博客里面说是caffe.cpp中一个叫做FLAGS_iterations的变量指定的。但是看了一下代码也没有什么宏定义直接显示50

自己手写数据测试

刚才是以batch测试的,还是没有直观的感受。

1.画图和准备标签

开启画图,调整到像素大小为28x28.然后手写0~9的数字,保存为bmp格式。这里有一个问题,虽然利用classification.exe不再需要转换成lmdb格式,但是也要求是单通道的。

Ps:如果保存的格式为单色位图bmp格式,它与单通道有什么关系呢?单色位图是黑白二值图像;单通道是只有一个通道,灰度图,图像的色阶是0~255的。

事实证明是没什么关系的。完全是对图像的两个角度的衡量。三通道当然可以生成二值图像。只不过当imread以参数为0读入图像时就无需转换成gray了。

把转换好的单通道bmp图像放在\examples\mnist目录下。同时准备一个标签文件label.txt,里面是0~9的数字。

2. 通过test_personal.bat利用classification.exe去识别某张图片

Build\x64\Release\classification.exeexamples\mnist\lenet.prototxt examples\mnist\lenet_iter_10000.caffemodelmean.binaryproto examples\mnist\label.txt examples\mnist\8.bmp

Pause

下图是对“8”的识别情况


可惜“9”识别错了


Reference:

1.      Caffe编译https://blog.youkuaiyun.com/xierhacker/article/details/51834563

2.      Mnist转换https://blog.youkuaiyun.com/foreyang00/article/details/71122866

3.      prototxt文件的设置解读https://blog.youkuaiyun.com/u014696921/article/details/52166015

4.      从零到一http://www.cnblogs.com/yixuan-xu/p/5858595.html

5.      从一到二http://www.cnblogs.com/yixuan-xu/p/5862657.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值