caffe学习系列:阅读solver和train_test的prototxt文件

来源:互联网 发布:网络数据抓包工具 编辑:程序博客网 时间:2024/06/01 10:41

参考博文:徐其华caffe学习系列

lenet_solver.prototxt参数学习

# The train/test net protocol buffer definitionnet:"D:\\GitSpace\\caffe-windows\\examples\\mnist\\lenet_train_test.prototxt"#设置深度网络模型test_iter: 100#这个要与test layer中的batch_size结合起来理解。mnist数据中测试样本总数为10000,一次性执行全部数据效率很低,因此我们将测试数据分成几个批次来执行,每个批次的数量就是batch_size。假设我们设置batch_size为100,则需要迭代100次才能将10000个数据全部执行完。因此test_iter设置为100。执行完一次全部数据,称之为一个epoch# Carry out testing every 500 training iterations.#测试间隔。也就是每训练500次,才进行一次测试test_interval: 500# The base learning rate, momentum and the weight decay of the network.#可以放在一起理解,用于学习率的设置。只要是梯度下降法来求解优化,都会有一个学习率,也叫步长。base_lr: 0.001#base_lr用于设置基础学习率momentum: 0.9weight_decay: 0.0005#权重衰减项,防止过拟合的一个参数lr_policy: "inv"#调整的策略,由lr_policy来设置gamma: 0.0001power: 0.75# Display every 100 iterations#每训练100次,在屏幕上显示一次。如果设置为0,则不显示display: 100# The maximum number of iterations#最大迭代次数。这个数设置太小,会导致没有收敛,精确度很低。设置太大,会导致震荡,浪费时间max_iter: 10000# snapshot intermediate results#快照。将训练出来的model和solver状态进行保存,snapshot用于设置训练多少次后进行保存,默认为0,不保存#还可以设置snapshot_diff,是否保存梯度值,默认为false,不保存。#也可以设置snapshot_format,保存的类型。有两种选择:HDF5 和BINARYPROTO ,默认为BINARYPROTOsnapshot: 5000snapshot_prefix: "D:\\GitSpace\\caffe-windows\\examples\\mnist\\lenet\\lenet"# solver mode: CPU or GPU#设置运行模式。默认为GPU,如果你没有GPU,则需要改成CPU,否则会出错solver_mode: CPU

在实际中,通过将整个数据集分成几批(batches), 每一批就是一个mini-batch,其数量(batch_size)为N<<|D|,此时的loss 函数为:
这里写图片描述

Solver的流程:

  1. 设计好需要优化的对象,以及用于学习的训练网络和用于评估的测试网络。(通过调用另外一个配置文件prototxt来进行)

  2. 通过forward和backward迭代的进行优化来跟新参数。

  3. 定期的评价测试网络。 (可设定多少次训练后,进行一次测试)

  4. 在优化过程中显示模型和solver的状态

在每一次的迭代过程中,solver做了这几步工作:

1、调用forward算法来计算最终的输出值,以及对应的loss

2、调用backward算法来计算每层的梯度

3、根据选用的slover方法,利用梯度进行参数更新

4、记录并保存每次迭代的学习率、快照,以及对应的状态。

lr_policy可以设置为下面这些值,相应的学习率的计算为:
•- fixed:   保持base_lr不变.
•- step:    如果设置为step,则还需要设置一个stepsize, 返回 base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示当前的迭代次数
•- exp:   返回base_lr * gamma ^ iter, iter为当前迭代次数
•- inv:   如果设置为inv,还需要设置一个power, 返回base_lr * (1 + gamma * iter) ^ (- power)
•- multistep: 如果设置为multistep,则还需要设置一个stepvalue。这个参数和step很相似,step是均匀等间隔变化,而multistep则是根据 stepvalue值变化
•- poly:    学习率进行多项式误差, 返回 base_lr (1 - iter/max_iter) ^ (power)
•- sigmoid: 学习率进行sigmod衰减,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))

lenet_train_test.prototxt参数学习

name: "LeNet"layer {  name: "mnist"#表示该层的名称,可随意取  type: "Data"#层类型,如果是Data,表示数据来源于LevelDB或LMDB  top: "data"#在数据层中,至少有一个命名为data的top。如果有第二个top,一般命名为label。 这种(data,label)配对是分类模型所必需的  top: "label" #每一层用bottom来输入数据,用top来输出数据  include {    phase: TRAIN  }#该层(layer)是属于训练阶段的层,还是属于测试阶段的层,需要用include来指定。如果没有include参数,则表示该层既在训练模型中,又在测试模型中。  transform_param {    scale: 0.00390625  }#数据的预处理,可以将数据变换到定义的范围内。如设置scale为0.00390625,实际上就是1/255, 即将输入数据由0-255归一化到0-1之间 data_param {    source: "D:/GitSpace/caffe-windows/examples/mnist/mnist-train-leveldb"    batch_size: 100#每次处理的数据个数    #backend: LMDB    backend: LEVELDB#选择是采用LevelDB还是LMDB  }}layer {  name: "mnist"  type: "Data"  top: "data"  top: "label"  include {    phase: TEST  }  transform_param {    scale: 0.00390625  }  data_param {    source:"D:/GitSpace/caffe-windows/examples/mnist/mnist-test-leveldb"    batch_size: 100    #backend: LMDB    backend: LEVELDB  }}layer {  name: "conv1"  type: "Convolution"#卷积层  bottom: "data"  top: "conv1"  param {    lr_mult: 1#表示权值的学习率  }  param {    lr_mult: #表示偏置项的学习率  }# 学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。如果有两个lr_mult, 则第一个表示权值的学习率,第二个表示偏置项的学习率。一般偏置项的学习率是权值学习率的两倍。 convolution_param {#我们可以设定卷积层的特有参数    num_output: 20#卷积核(filter)的个数    kernel_size: 5#卷积核的大小。如果卷积核的长和宽不等,需要用kernel_h和kernel_w分别设定    stride: 1#卷积核的步长,默认为1。也可以用stride_h和stride_w来设置    weight_filler {# 权值初始化。 默认为“constant",值全为0,很多时候我们用"xavier"算法来进行初始化,也可以设置为”gaussian"      type: "xavier"    }    bias_filler {#偏置项的初始化。一般设置为"constant",值全为0      type: "constant"    }  }}layer {  name: "pool1"  type: "Pooling"#也叫池化层,为了减少运算量和数据维度而设置的一种层  bottom: "conv1"  top: "pool1"  pooling_param {    pool: MAX#池化方法,默认为MAX。目前可用的方法有MAX, AVE, 或STOCHASTIC    kernel_size: 2# kernel_size: 池化的核大小。也可以用kernel_h和kernel_w分别设定    stride: 2#池化的步长,默认为1。一般我们设置为2,即不重叠。也可以用stride_h和stride_w来设置  }}layer {  name: "conv2"  type: "Convolution"  bottom: "pool1"  top: "conv2"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  convolution_param {    num_output: 50    kernel_size: 5    stride: 1    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "pool2"  type: "Pooling"  bottom: "conv2"  top: "pool2"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "ip1"  type: "InnerProduct"#全连接层,把输入当作成一个向量,输出也是一个简单向量(把输入数据blobs的width和height全变为1)。  bottom: "pool2"  top: "ip1"  param {    lr_mult: 1#表示权值的学习率  }  param {    lr_mult: 2#偏置项的学习率  }# 学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。如果有两个lr_mult, 则第一个表示权值的学习率,第二个表示偏置项的学习率。一般偏置项的学习率是权值学习率的两倍。  inner_product_param {    num_output: 500#过滤器(filfter)的个数    weight_filler {      type: "xavier"# 权值初始化。 默认为“constant",值全为0,很多时候我们用"xavier"算法来进行初始化,也可以设置为”gaussian"    }    bias_filler {      type: "constant"#偏置项的初始化。一般设置为"constant",值全为0    }  }}layer {  name: "relu1"  type: "ReLU"  bottom: "ip1"  top: "ip1"}layer {  name: "ip2"  type: "InnerProduct"  bottom: "ip1"  top: "ip2"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  inner_product_param {    num_output: 10    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "accuracy"  type: "Accuracy"#输出分类(预测)精确度,只有test阶段才有,因此需要加入include参数  bottom: "ip2"  bottom: "label"  top: "accuracy"  include {    phase: TEST  }}layer {  name: "loss"  type: "SoftmaxWithLoss"#输出loss值  bottom: "ip2"  bottom: "label"  top: "loss"}

卷积层计算: 输入:n*c0*w0*h0 输出:n*c1*w1*h1 其中,c1就是参数中的num_output,生成的特征图个数
w1=(w0+2*pad-kernel_size)/stride+1;
h1=(h0+2*pad-kernel_size)/stride+1;
如果设置stride为1,前后两次卷积部分存在重叠。如果设置pad=(kernel_size-1)/2,则运算后,宽度和高度不变。

池化层计算: 输入:n*c*w0*h0 输出:n*c*w1*h1 和卷积层的区别就是其中的c保持不变
w1=(w0+2*pad-kernel_size)/stride+1;
h1=(h0+2*pad-kernel_size)/stride+1;
如果设置stride为2,前后两次卷积部分不重叠。100*100的特征图池化后,变成50*50.

softmax-loss层和softmax层不同: 用户可能最终目的就是得到各个类别的概率似然值,这个时候就只需要一个
Softmax层,而不一定要进行softmax-Loss
操作;或者是用户有通过其他什么方式已经得到了某种概率似然值,然后要做最大似然估计,此时则只需要后面的 softmax-Loss
而不需要前面的 Softmax 操作。因此提供两个不同的 Layer 结构比只提供一个合在一起的 Softmax-Loss Layer
要灵活许多。

阅读全文
0 0