【caffe学习笔记——mnist】mnist手写数据集训练和测试
来源:互联网 发布:ie11浏览器修复软件 编辑:程序博客网 时间:2024/05/19 19:13
http://blog.csdn.NET/liumaolincycle/article/details/47336921
本文主要来自Caffe作者Yangqing Jia网站给出的examples。
- 1
- 2
- 3
- 4
- 5
- 6
1.准备数据集
首先从MNIST网站上下载数据集,运行:
- 1
- 2
下载到四个文件,从左至右依次是测试集图像、测试集标签、训练集图像、训练集标签:
转换数据格式:
- 1
在 examples/mnist下出现两个新的文件夹:
create_mnist.sh这个脚本是将训练集和测试集分别转换成了lmdb格式。
2.LeNet: MNIST分类模型
本实验用的网络模型是LeNet,它是公认在数字分类任务上效果很好的网络。实验中在原始 LeNet基础上做了一点改动,对于神经元的激活,用ReLU替换了sigmoid。
LeNet的设计包括一个卷积层,后随一个pooling层,再一个卷积层,后随一个pooling层,再两个全连接层,类似于传统的多层感知器。经典LeNet如图:
这些层的定义在examples/mnist/lenet_train_test.prototxt中。
3.定义MNIST网络
在定义自己的网络之前可以运行示例中给出的代码训练网络:
- 1
过程与CIFAR-10中的一样,所用solver是examples/mnist/lenet_solver.prototxt,在这个solver中可以看到对训练与测试的简单设置,所用的网络定义就是examples/mnist/lenet_train_test.prototxt。
下面详细学习examples/mnist/lenet_train_test.prototxt的模型定义,学习的基础是对Google Protobuf比较熟悉,可参考Google Protocol Buffer的使用和原理,还要读过Caffe使用的protobuf定义,这个定义在src/caffe/proto/caffe.proto中。
为了更深入地了解网络是怎么定义的,我们自己写一个caffe网络参数的protobuf。首先新建一个prototxt文件,我这里的命名是lenet_train_lml.prototxt。给网络取个名字:
- 1
3.1 写数据层
现在要从之前创建的lmdb中读取MNIST数据,定义如下的数据层:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
3.2 写卷积层
定义第一个卷积层:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
3.3 写pooling层
pooling层就好定义多了:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
然后就可以自己写第二个卷积层和pooling层了,细节参考examples/mnist/lenet_train_test.prototxt。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
3.4 写全连接层
全连接层也比较简单:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3.5 写ReLU层
- 1
- 2
- 3
- 4
- 5
- 6
因为ReLU是元素级操作,所以可以用一种叫做in-place(猜测可以翻译为在原位置,也就是不开辟新内存)的操作来节省内存,这是通过简单地把bottom blob和top blob设成同样的名字来实现,当然了,不要在其他类型的层中这么干。
然后再写一个全连接层:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3.6 写loss层
最后写一个loss层:
- 1
- 2
- 3
- 4
- 5
- 6
softmax_loss层实现了Softmax和多项Logistic损失(节省了时间,同时提高了数据稳定性)。它需要两个blob,第一个是预测,第二个是数据层生成的label。该层不产生输出,只是计算loss函数的值,在反向传播的时候使用,并初始化关于ip2的梯度。
3.7 写层次规则
层次定义包含的规则是这些层是否以及什么时候包含在网络定义中,像这样:
- 1
- 2
- 3
- 4
这个规则基于现有网络状态,控制网络中的层次包含关系,可以查看src/caffe/proto/caffe.proto来获取层次规则及模型概要的更多信息。
在上面的例子中,这个层只会包含在TRAIN阶段中,如果把TRAIN改为TEST,这个层就只会被用于TEST阶段。如果不写TRAIN或TEST的话,那么这个层TRAIN阶段和TEST阶段都会被用到,所以lenet_train_test.prototxt中定义了两个DATA层,我们参考它也分别定义两个DATA层:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
另外,TEST阶段有一个Accuracy层,它是用来每100次迭代报告一次模型准确率的,lenet_solver.prototxt中给出了定义,我们同样也把它加上:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
4.定义MNIST的solver文件
再看一下lenet_solver.prototxt中都定义了些什么:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
5.训练与测试模型
在写完网络定义和solver之后,就可以训练模型了,运行:
- 1
会在终端看到这样的消息,这些消息显示了每一层的细节,即连接关系与输出的形状,在调试的时候是很有用的:
初始化以后就开始训练了:
solver中设置每100次迭代打印出训练的loss,每1000次迭代打印出测试的loss:
迭代完结果就出来了:
最后的模型存储在一个二进制的protobuf文件lenet_iter_10000.caffemodel中,在训练其他数据集的时候可以把它作为基础模型。
6.其他
通过这个实验,终于知道网络要怎么设置了,还有其他不同的solver值得一试。例如autoencoder网络,运行命令:
- 1
或者:
- 1
或者:
- 【caffe学习笔记——mnist】mnist手写数据集训练和测试
- Caffe mnist数据集训练
- caffe学习(二):利用mnist数据集训练并进行手写数字识别(windows)
- caffe中MNIST数据集训练与测试LeNet
- caffe学习笔记5:详细、完整的Mnist数据集训练
- MNIST数据集训练
- caffe学习笔记:mnist数据集的训练和测试
- Windows Caffe 学习笔记 caffe-windows(CPU)配置与利用mnist数据集训练第一个caffemodel
- Windows Caffe 学习笔记(四)搭建自己的网络,训练和测试MNIST手写字体库
- Ubuntu14.04配置caffe,及mnist数据集训练与测试(仅在CPU下)
- Caffe的安装及MNIST数据集训练
- tensorflow-mnist数据集训练
- Windows7+VS2013 MNIST数据集训练与测试
- caffe学习笔记:mnist
- 用Caffe 训练和测试MNIST数据
- 机器学习笔记6:TensorFlow入门之MNIST数据集训练
- caffe之利用mnist数据集训练好的lenet_iter_10000.caffemodel模型测试一张自己的手写体数字
- caffe之利用mnist数据集训练好的lenet_iter_10000.caffemodel模型测试一张自己的手写体数字
- LightOJ1197 Help Hanzo
- 1046. Shortest Distance (20)
- 第一章 代码开发规范及其指南
- SQL SERVER2008笔记
- Unity--WWW类与协程
- 【caffe学习笔记——mnist】mnist手写数据集训练和测试
- JAVA中常见异常
- rpm包和源码包安装的区别
- 关于堆排序的一些思考
- 三次握手四次挥手的原理
- 日志同步与时间同步
- android开发:The method getSupportFragmentManager() is undefined for the type
- mysql status记录
- OJ提交题目中的语言选项里G++与C++的区别