用Caffe在MNIST上训练LeNet
来源:互联网 发布:科技公司网站源码 编辑:程序博客网 时间:2024/05/19 12:11
数据准备
首先从MNIST网站下载数据集并转换获取的数据格式,运行以下简单的命令脚本
cd $CAFFE_ROOT #$CAFFE_ROOT指的是caffe所在根目录./data/mnist/get_mnist.sh #从脚本中提供的网址下载数据(.gz格式)并解压、删除已下载的原件,仅保留解压后的数据(如train-images-idx3-ubyte、train-labels-idx1-ubyte)./examples/mnist/create_mnist.sh #将上述数据转化成lmdb格式lmdb格式讲解
简述:Caffe中的lmdb数据大约有两类:1. 输入DataLayer的训练/测试数据集;2.extract_feature输出的特征数据。
lmdb,文件结构简单,一个文件夹里面包含一个数据文件,一个锁文件。数据随意复制,随意传输。访问简单,不需要运行单独的数据库管理进程,只要在访问数据的代码里引用LMDB库,访问时给文件路径即可。
运行完上述的脚本文件后,会在/examples/mnist目录下面得到mnist_train_lmdb和mnist_test_lmdb两个文件夹,每个文件夹下包含有一个数据文件data.lmdb和一个锁文件lock.lmdb。
LeNet:MNIST分类模型
在初始版本的LeNet上稍稍改变:用ReLU替换sigmoid激活函数。已经在$CAFFE_ROOT/examples/mnist/lenet_train_test.prototxt
中定义了网络结构。
caffe中的protobuf定义,见$CAFFE_ROOT/src/caffe/proto/caffe.proto,官方的protobuf documents参考Google Protobuf,另参考博客protobuf文件的简单使用
定义MNIST网络
在LeNet的示例中,lenet_train_test.prototxt文件描述了LeNet网络的结构:
首先,给网络一个名字
name:"LeNet"
数据层Data Layer
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 }}从所指定的lmdb中读取数据;batch size为64,scal输入的像素值到[0,1)256分之1=0.00390625;最后产生(输出)两个blob(data blob和label blob)用于下层。
卷积层Convolution Layer
第一个卷积层:
layer { name: "conv1" # 本层的名字自取 type: "Convolution" # 层类型 bottom: "data" # 接受来自data layer的data top: "conv1" # 输出/产生conv1 blob param { lr_mult: 1#学习率 } param { lr_mult: 2 } convolution_param { num_output: 20 #输出的channels数为20 kernel_size: 5 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } }}fillers可以随机的初始化weights和bias值。在本层中,对于weights fillers,使用xavier算法根据输入输出的神经节点数目自动决定初始化的尺度;对于bisa fillers,采用constant常数填充,这里用0填充。
lr_mults是层中可学习参数的学习率。在该例子中,weight的学习率与运行期间由solver给定的学习率相同,bias学习率是weight学习率的两倍大,这样做通常有更好的收敛率。
池化层Pooling Layer
layer { name: "pool1" type: "Pooling" bottom: "conv1" top: "pool1" pooling_param { pool: MAX kernel_size: 2 stride: 2 }}pooling层相对简单,这里的解释是对来自conv1的blob以max-pooling的方式处理,然后产生名为pool1的blob。如此,可以近似地编写conv2和pool2层。
全连接层Fully Connected Layer
layer { name: "ip1" type: "InnerProduct" #全连接方式 bottom: "pool2" top: "ip1" param { lr_mult: 1 } param { lr_mult: 2 } inner_product_param { num_output: 500 weight_filler { type: "xavier" } bias_filler { type: "constant" } }}这样就定义了对来自pool2的blob进行InnerProduct以得到一个有500单元输出的blob ip1。
ReLU处理层
layer { name: "relu1" type: "ReLU" bottom: "ip1" top: "ip1"}以相同的名字来命名bottom和top,即对输入进行一次ReLU变换。同理,可以构建InnerProduct layer ip2层。
Loss Layer
layer { name: "loss" type: "SoftmaxWithLoss" bottom: "ip2" bottom: "label" top: "loss"}softmax_loss层实现softmax和多项logistic损失(省时并提高数值稳定性)。它需要两个blob,第一个是预测,第二个是数据层提供的标签。计算损失函数值,在反向传播开始时报告它,并针对ip2启动梯度。
额外注意点:编写层规则
layer { // ...layer definition... include: { phase: TRAIN }}
图层的定义可以包含是否以及何时包含在网络定义中的规则中。示例描述的是一个基于当前网络状态来控制网络中的层包含的规则。规则TRAIN说明该层只包含在训练阶段,默认情况下(无规则时)层包含在整个网络中。因此,lenet_train_test.prototxt有两个具有不同batch_size的Data Layers:一个用于训练,另一个用于测试。
layer { name: "accuracy" type: "Accuracy" bottom: "ip2" bottom: "label" top: "accuracy" include { phase: TEST }}此外,还有一个Accurry Layer,仅包含在测试阶段,用于每100次迭代报告模型精度。当然,这里所说的100次是在$CAFFE_ROOT/examples/mnist/lenet_solver.prototxt中描述的。
定义MNIST的Solver
具体描述见$CAFFE_ROOT/examples/mnist/lenet_solver.prototxt
# The train/test net protocol buffer definitionnet: "examples/mnist/lenet_train_test.prototxt"# test_iter specifies how many forward passes the test should carry out.# In the case of MNIST, we have test batch size 100 and 100 test iterations,# covering the full 10,000 testing images.test_iter: 100# Carry out testing every 500 training iterations.test_interval: 500# The base learning rate, momentum and the weight decay of the network.base_lr: 0.01momentum: 0.9weight_decay: 0.0005# The learning rate policylr_policy: "inv"gamma: 0.0001power: 0.75# Display every 100 iterationsdisplay: 100# The maximum number of iterationsmax_iter: 10000# snapshot intermediate resultssnapshot: 5000snapshot_prefix: "examples/mnist/lenet"# solver mode: CPU or GPUsolver_mode: GPU选择GPU训练,solver_model:GPU
训练和测试模型
运行$CAFFE_ROOT/examples/mnist/train_lenet.sh脚本,训练的主要工具就是caffe中的train操作,并以solver prototxt文件作为它的参数。
#!/usr/bin/env shset -e./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt $@
由图可知,每层的连接和输出规模,并且可在对应的源文件中追踪,如[... net.cpp:84]。此外,我们还能知道哪些层需要反向传播计算,有无输出loss。在初始化完成后,开始训练过程。
根据solver的设置,每100 iterations打印输出训练损失,以及每500 iterations测试一次网络,那么可以看到:
I1208 10:02:38.242851 4482 solver.cpp:218] Iteration 100 (653.884 iter/s, 0.152932s/100 iters), loss = 0.21386I1208 10:02:38.242880 4482 solver.cpp:237] Train net output #0: loss = 0.21386 (* 1 = 0.21386 loss)I1208 10:02:38.242887 4482 sgd_solver.cpp:105] Iteration 100, lr = 0.00992565......I1208 10:02:38.758451 4482 solver.cpp:330] Iteration 500, Testing net (#0)I1208 10:02:38.809602 4491 data_layer.cpp:73] Restarting data prefetching from start.I1208 10:02:38.810797 4482 solver.cpp:397] Test net output #0: accuracy = 0.9726I1208 10:02:38.810818 4482 solver.cpp:397] Test net output #1: loss = 0.0893905 (* 1 = 0.0893905 loss)......I1208 10:02:51.497777 4482 solver.cpp:447] Snapshotting to binary proto file examples/mnist/lenet_iter_10000.caffemodelI1208 10:02:51.501615 4482 sgd_solver.cpp:273] Snapshotting solver state to binary proto file examples/mnist/lenet_iter_10000.solverstateI1208 10:02:51.503881 4482 solver.cpp:310] Iteration 10000, loss = 0.00287347I1208 10:02:51.503899 4482 solver.cpp:330] Iteration 10000, Testing net (#0)I1208 10:02:51.553721 4491 data_layer.cpp:73] Restarting data prefetching from start.I1208 10:02:51.555130 4482 solver.cpp:397] Test net output #0: accuracy = 0.9907I1208 10:02:51.555150 4482 solver.cpp:397] Test net output #1: loss = 0.0314041 (* 1 = 0.0314041 loss)I1208 10:02:51.555155 4482 solver.cpp:315] Optimization Done.I1208 10:02:51.555158 4482 caffe.cpp:259] Optimization Done.最终的模型,以2进制protobuf文件的形式存储在lenet_iter_10000.caffemodel中,运行测试文件test_lenet.sh.
#!/usr/bin/env sh./build/tools/caffe test --model=examples/mnist/lenet_train_test.prototxt \--weights=examples/mnist/lenet_iter_10000.caffemodel -gpu=0如果遇到权限问题,加上权限:
$ chmod +x ./examples/mnist/test_lenet.sh
- 用Caffe在MNIST上训练LeNet
- 奔跑吧Caffe(在MNIST手写体数字集上用Caffe框架训练LeNet模型)
- 用caffe用LeNet来训练MNIST
- Caffe MNIST训练lenet网络
- caffe示例实现之4在MNIST手写数字数据集上训练与测试LeNet
- caffe示例实现之4在MNIST手写数字数据集上训练与测试LeNet
- caffe示例实现之4在MNIST手写数字数据集上训练与测试LeNet
- Caffe 实践 在数据集MNIST上使用LeNet
- 在大规模分布式集群上用caffe训练mnist模型
- Caffe实战:LeNet模型训练测试MNIST数据集
- caffe训练mnist数据集使用lenet网络
- ubuntu16.04 caffe 数据集MNIST 训练LeNet
- 【caffe】mnist数据集lenet训练与测试
- MNIST在caffe上的训练与学习
- Training MNIST LeNet on MNIST with Caffe
- caffe 练习1:training LeNet on MNIST with Caffe/ 用LeNet识别手写字符集 Mnist------by 香蕉麦乐迪
- caffe 练习1:training LeNet on MNIST with Caffe/ 用LeNet识别手写字符集 Mnist------by 香蕉麦乐迪
- Ubuntu 14.04 64位机上用Caffe+MNIST训练Lenet网络操作步骤
- webpack+vue+vueRouter模块化构建完整项目实例超详细步骤(附截图、代码、入门篇)
- 10、新手入手树莓派教程--Qt中使用wiringPi来开发工程
- IT运维管理系统的十大无奈之处
- 147. Insertion Sort List
- 【第八周】项目三 顺序串算法
- 用Caffe在MNIST上训练LeNet
- ConEmu设置当前目录打开右键菜单
- 养成良好的习惯
- 第四周 【项目5- 循环双链表应用】
- 第四周-项目四-猴子选大王
- 通过 SSH 实现 TCP / IP 隧道(端口转发)
- 第十五周 【项目2
- 有趣的二进制手表问题。
- 第十五周项目一