Caffe从入门到精通03

来源:互联网 发布:网络攻击的发展趋势是 编辑:程序博客网 时间:2024/06/05 06:47

【Caffe层次结构及参数介绍——以MNIST为例】

要熟练使用caffe,最重要的就是学会配置文件prototxt的编写。

以MNIST为例,其模型的层次结构通过examples/mnist文件目录下的lenet_train_test.prototxt文件来定义。如下图所示:


层(layer)的类型有很多种,比如data(数据层),convolution(卷积层),pooling(池化层)、inner product(全连接层)、softmax-loss(softmax损失层),层之间的数据流动是以Blobs的方式进行(Blobs是一个4维张量,用于存储和交换数据)。接下来,我将以caffe自带的MNIST为例,由浅入深介绍一下caffe的层次结构及参数。

一、数据层

数据层是每一个模型的最底层,由数据定义和数据参数两部分组成。数据层是模型的入口,不仅提供数据的输入,也提供数据的格式转换。通常的数据预处理(减去均值、缩放、剪裁、镜像)也在这一层设置参数实现。

layer {  name: "mnist"  type: "Data"  top: "data"  top: "label"  include {    phase: TRAIN  }  transform_param {    scale: 0.00390625  }  data_param {    source: "examples/mnist/mnist-train-leveldb"    batch_size: 64    backend: LEVELDB  }}

1.层定义

name:表示该层的名称,可以随意取,这里取为“mnist”

type:表示层类型,如果值设置为“Data”,那么表示数据来源于LEVEDB或者LMDB。根据数据来源的不同,层类型也会不一样。由于我们下载的mnist的数据大都为LEVELDB,所以这里取值为“Data”

top或bottom:每一层用bottom来表示输入数据,用top来输出数据。即“自底而上”。本层只有top没有bottom,表示此层只有输出,没有输入。在数据层,至少有一个top取值为data“”,如果像本例一样有第二个top,那么一般取值为“label”。这种(data,label)组合对是分类模型必须的。

include:“训练\测试”调度器,一般模型的训练和测试所用的模型层是不一样的,因而需要配置include的参数phase,来指定该层是用于测试还是训练。如果没有设置include参数,则表示该层同时兼容训练和预测模型。本例中,include的参数设置为“TRAIN”,即表示该层用于训练。

2.层参数

transform_param:数据的预处理,可以将数据变换到定义的范围内。本例设置为0.00390625,即1/255,表示将输入数据由0-255归一化到0-1之间

data_param:根据数据来源(层类型)不同,来进行不同的设置。本例中层类型为“Data”,故必须要设置的参数source:包含数据库的文件路径,如“examples/mnist/mnist-train-lmdb”;bath_size:每一个批次处理的数据个数,如“64”;backend:支持数据库类型,可以选择是LevelDB还是LMDB,本例为“LevelDB”

二、卷积层

卷积层是CNN的核心层

layer {  name: "conv1"  type: "Convolution"  bottom: "data"  top: "conv1"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  convolution_param {    num_output: 20    kernel_size: 5    stride: 1    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}
1.层定义

该层的名称为“con1”,层类型为“Convolution”,输入源来自“data”层,在本层“con1”输出。

2.层参数

lr_mult :学习率的系数。而最终的学习率 lr=lr_mult*base_lr,其中base_lr在lenet_solver.prototxt配置文件中(base_lr:0.01);如果有两个lr_mult,则第一个表示为权值的学习率,第二个表示为偏置的学习率。一般后者是前者的两倍。故本例中第二个lr_mult的值为“2”,第一个lr_mult的值为“1”

convolution_param:卷积层的系数,必须包含:num_output:卷积核个数,这里设置为“20”;kernel_size:卷积核的大小;stride:卷积核步长,默认为1;weight_filler:权值初始化,这里设置为“xavier”,即采用“xavier”算法进行初始化。(即“对称区间均匀采样”,为了使网络中的参数更好的流动 ,推荐这篇文档,讲的不错 点击打开链接 );bias_filler,默认为“constant”,即值全部初始化为“0”


三、池化层

池化层,为了减少运算量和数据维度而设置的一种层。

layer {  name: "pool1"  type: "Pooling"  bottom: "conv1"  top: "pool1"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}
1.层参数

pool:池化方法,默认为“Max”,目前可用的方法有MAX(最大池化),AVE(平均池化)

kernel_size:池化核大小,这里设置为“2”

stride:池化步长。默认为1,这里这设置为“2”,目的是不重叠。

四、全连接层

全连接层,把输入当作一个向量,输出也是一个简单向量

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"    }  }}
1.层参数

num_output:过滤器个数。这里设置为500.表示在“pool2”之后每个样本有n(n>500)个特征,那么在经过ip1全连接层后,每个样本的特征数均被“压缩”到500个。同理,在经过ip2全连接层后,特征数被“压缩到”10个(此时就满足了0-9的数字分类需要)

五、激活层

ReLU是目前使用最多的激活函数,主要是因为其收敛更快,并且能保持同样的效果。

layer {  name: "relu1"  type: "ReLU"  bottom: "ip1"  top: "ip1"}
可以看出,在caffe的mnist的网络中,ReLU激活函数应用在了全连接层。

六、分类精度层

输出预测精确度,只有test阶段才有,因此需要加入include参数

layer {  name: "accuracy"  type: "Accuracy"  bottom: "ip2"  bottom: "label"  top: "accuracy"  include {    phase: TEST  }}

七、损失层

softmax-loss层,输出loss值

layer {  name: "loss"  type: "SoftmaxWithLoss"  bottom: "ip2"  bottom: "label"  top: "loss"}
softmax-loss的计算包含2步,首先计算softmax归一化概率,然后计算损失。此外,softmax_loss可支持更高维度的label。这里推荐一篇文档,这方面内容讲的很好softmax_loss