700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > windows下caffe+CPUOnly实现MNIST手写分类

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

时间:2020-02-02 10:39:41

相关推荐

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

工具下载

微软官方移植的Caffe:/Microsoft/caffe

对属性表的操作

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

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

<CpuOnlyBuild>true</CpuOnlyBuild>

<UseCuDNN>false</UseCuDNN>

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

如果想进行CUDA编程首先要确保自己的GPU是英伟达NVIDIA的,然后在/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,会不方便)

注意:在上图顶部工具栏中的“解决方案配置”和“解决方案平台”框,若你的vs中将这两个框在工具栏中显示,则要在工具栏中将配置改成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像素大小。

下载地址:/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%。

连接/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编译/xierhacker/article/details/51834563

2.Mnist转换/foreyang00/article/details/71122866

3.prototxt文件的设置解读/u014696921/article/details/52166015

4.从零到一/yixuan-xu/p/5858595.html

5.从一到二/yixuan-xu/p/5862657.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。