caffe网络模型各层详解中文版资料.docx
《caffe网络模型各层详解中文版资料.docx》由会员分享,可在线阅读,更多相关《caffe网络模型各层详解中文版资料.docx(40页珍藏版)》请在冰豆网上搜索。
caffe网络模型各层详解中文版资料
一.数据层及参数
要运行caffe,需要先创建一个模型(model),如比较常用的Lenet,Alex等,而一个模型由多个屋(layer)构成,每一屋又由许多参数组成。
所有的参数都定义在caffe.proto这个文件中。
要熟练使用caffe,最重要的就是学会配置文件(prototxt)的编写。
层有很多种类型,比如Data,Convolution,Pooling等,层之间的数据流动是以Blobs的方式进行。
今天我们就先介绍一下数据层.
数据层是每个模型的最底层,是模型的入口,不仅提供数据的输入,也提供数据从Blobs转换成别的格式进行保存输出。
通常数据的预处理(如减去均值,放大缩小,裁剪和镜像等),也在这一层设置参数实现。
数据来源可以来自高效的数据库(如LevelDB和LMDB),也可以直接来自于内存。
如果不是很注重效率的话,数据也可来自磁盘的hdf5文件和图片格式文件。
所有的数据层的都具有的公用参数:
先看示例
layer{
name:
"cifar"
type:
"Data"
top:
"data"
top:
"label"
include{
phase:
TRAIN
}
transform_param{
mean_file:
"examples/cifar10/mean.binaryproto"
}
data_param{
source:
"examples/cifar10/cifar10_train_lmdb"
batch_size:
100
backend:
LMDB
}
}
name:
表示该层的名称,可随意取
type:
层类型,如果是Data,表示数据来源于LevelDB或LMDB。
根据数据的来源不同,数据层的类型也不同(后面会详细阐述)。
一般在练习的时候,我们都是采用的LevelDB或LMDB数据,因此层类型设置为Data。
top或bottom:
每一层用bottom来输入数据,用top来输出数据。
如果只有top没有bottom,则此层只有输出,没有输入。
反之亦然。
如果有多个top或多个bottom,表示有多个blobs数据的输入和输出。
data与label:
在数据层中,至少有一个命名为data的top。
如果有第二个top,一般命名为label。
这种(data,label)配对是分类模型所必需的。
include:
一般训练的时候和测试的时候,模型的层是不一样的。
该层(layer)是属于训练阶段的层,还是属于测试阶段的层,需要用include来指定。
如果没有include参数,则表示该层既在训练模型中,又在测试模型中。
Transformations:
数据的预处理,可以将数据变换到定义的范围内。
如设置scale为0.00390625,实际上就是1/255,即将输入数据由0-255归一化到0-1之间
其它的数据预处理也在这个地方设置:
transform_param{
scale:
0.00390625
mean_file_size:
"examples/cifar10/mean.binaryproto"
#用一个配置文件来进行均值操作
mirror:
1#1表示开启镜像,0表示关闭,也可用ture和false来表示
#剪裁一个227*227的图块,在训练阶段随机剪裁,在测试阶段从中间裁剪
crop_size:
227
}
1、数据来自于数据库(如LevelDB和LMDB)
层类型(layertype):
Data
必须设置的参数:
source:
包含数据库的目录名称,如examples/mnist/mnist_train_lmdb
batch_size:
每次处理的数据个数,如64
可选的参数:
rand_skip:
在开始的时候,路过某个数据的输入。
通常对异步的SGD很有用。
backend:
选择是采用LevelDB还是LMDB,默认是LevelDB.
示例:
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
}
}
2、数据来自于内存
层类型:
MemoryData
必须设置的参数:
batch_size:
每一次处理的数据个数,比如2
channels:
通道数
height:
高度
width:
宽度
示例:
layer{
top:
"data"
top:
"label"
name:
"memory_data"
type:
"MemoryData"
memory_data_param{
batch_size:
2
height:
100
width:
100
channels:
1
}
transform_param{
scale:
0.0078125
mean_file:
"mean.proto"
mirror:
false
}
}
3、数据来自于HDF5
层类型:
HDF5Data
必须设置的参数:
source:
读取的文件名称
batch_size:
每一次处理的数据个数
示例:
layer{
name:
"data"
type:
"HDF5Data"
top:
"data"
top:
"label"
hdf5_data_param{
source:
"examples/hdf5_classification/data/train.txt"
batch_size:
10
}
}
4、数据来自于图片
层类型:
ImageData
必须设置的参数:
source:
一个文本文件的名字,每一行给定一个图片文件的名称和标签(label)
batch_size:
每一次处理的数据个数,即图片数
可选参数:
rand_skip:
在开始的时候,路过某个数据的输入。
通常对异步的SGD很有用。
shuffle:
随机打乱顺序,默认值为false
new_height,new_width:
如果设置,则将图片进行resize
示例:
layer{
name:
"data"
type:
"ImageData"
top:
"data"
top:
"label"
transform_param{
mirror:
false
crop_size:
227
mean_file:
"data/ilsvrc12/imagenet_mean.binaryproto"
}
image_data_param{
source:
"examples/_temp/file_list.txt"
batch_size:
50
new_height:
256
new_width:
256
}
}
5、数据来源于Windows
层类型:
WindowData
必须设置的参数:
source:
一个文本文件的名字
batch_size:
每一次处理的数据个数,即图片数
示例:
layer{
name:
"data"
type:
"WindowData"
top:
"data"
top:
"label"
include{
phase:
TRAIN
}
transform_param{
mirror:
true
crop_size:
227
mean_file:
"data/ilsvrc12/imagenet_mean.binaryproto"
}
window_data_param{
source:
"examples/finetune_pascal_detection/window_file_2007_trainval.txt"
batch_size:
128
fg_threshold:
0.5
bg_threshold:
0.5
fg_fraction:
0.25
context_pad:
16
crop_mode:
"warp"
}
}
2.视觉层(VisionLayers)及参数
本文只讲解视觉层(VisionLayers)的参数,视觉层包括Convolution,Pooling,LocalResponseNormalization(LRN),im2col等层。
1、Convolution层:
就是卷积层,是卷积神经网络(CNN)的核心层。
层类型:
Convolution
lr_mult:
学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。
如果有两个lr_mult,则第一个表示权值的学习率,第二个表示偏置项的学习率。
一般偏置项的学习率是权值学习率的两倍。
在后面的convolution_param中,我们可以设定卷积层的特有参数。
必须设置的参数:
num_output:
卷积核(filter)的个数
kernel_size:
卷积核的大小。
如果卷积核的长和宽不等,需要用kernel_h和kernel_w分别设定
其它参数:
stride:
卷积核的步长,默认为1。
也可以用stride_h和stride_w来设置。
pad:
扩充边缘,默认为0,不扩充。
扩充的时候是左右、上下对称的,比如卷积核的大小为5*5,那么pad设置为2,则四个边缘都扩充2个像素,即宽度和高度都扩充了4个像素,这样卷积运算之后的特征图就不会变小。
也可以通过pad_h和pad_w来分别设定。
weight_filler:
权值初始化。
默认为“constant",值全为0,很多时候我们用"xavier"算法来进行初始化,也可以设置为”gaussian"
bias_filler:
偏置项的初始化。
一般设置为"constant",值全为0。
bias_term:
是否开启偏置项,默认为true,开启
group:
分组,默认为1组。
如果大于1,我们限制卷积的连接操作在一个子集内。
如果我们根据图像的通道来分组,那么第i个输出分组只能与第i个输入分组进行连接。
输入:
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,则运算后,宽度和高度不变。
示例:
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"
}
}
}
2、Pooling层
也叫池化层,为了减少运算量和数据维度而设置的一种层。
层类型:
Pooling
必须设置的参数:
kernel_size:
池化的核大小。
也可以用kernel_h和kernel_w分别设定。
其它参数:
pool:
池化方法,默认为MAX。
目前可用的方法有MAX,AVE,或STOCHASTIC
pad:
和卷积层的pad的一样,进行边缘扩充。
默认为0
stride:
池化的步长,默认为1。
一般我们设置为2,即不重叠(步长=窗口大小)。
也可以用stride_h和stride_w来设置。
示例:
layer{
name:
"pool1"
type:
"Pooling"
bottom:
"conv1"
top:
"pool1"
pooling_param{
pool:
MAX
kernel_size:
3
stride:
2
}
}
pooling层的运算方法基本是和卷积层是一样的。
输入:
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,前后两次卷积部分重叠。
3、LocalResponseNormalization(LRN)层
此层是对一个输入的局部区域进行归一化,达到“侧抑制”的效果。
可去搜索AlexNet或GoogLenet,里面就用到了这个功能
层类型:
LRN
参数:
全部为可选,没有必须
local_size:
默认为5。
如果是跨通道LRN,则表示求和的通道数;如果是在通道内LRN,则表示求和的正方形区域长度。
alpha:
默认为1,归一化公式中的参数。
beta:
默认为5,归一化公式中的参数。
norm_region:
默认为ACROSS_CHANNELS。
有两个选择,ACROSS_CHANNELS表示在相邻的通道间求和归一化。
WITHIN_CHANNEL表示在一个通道内部特定的区域内进行求和归一化。
与前面的local_size参数对应。
归一化公式:
对于每一个输入,去除以
,得到归一化后的输出
示例:
layers{
name:
"norm1"
type:
LRN
bottom:
"pool1"
top:
"norm1"
lrn_param{
local_size:
5
alpha:
0.0001
beta:
0.75
}
}
4、im2col层
如果对matlab比较熟悉的话,就应该知道im2col是什么意思。
它先将一个大矩阵,重叠地划分为多个子矩阵,对每个子矩阵序列化成向量,最后得到另外一个矩阵。
看一看图就知道了:
在caffe中,卷积运算就是先对数据进行im2col操作,再进行内积运算(innerproduct)。
这样做,比原始的卷积操作速度更快。
看看两种卷积操作的异同:
三.激活层(ActiviationLayers)及参数
在激活层中,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的。
从bottom得到一个blob数据输入,运算后,从top输入一个blob数据。
在运算过程中,没有改变数据的大小,即输入和输出的数据大小是相等的。
输入:
n*c*h*w
输出:
n*c*h*w
常用的激活函数有sigmoid,tanh,relu等,下面分别介绍。
1、Sigmoid
对每个输入数据,利用sigmoid函数执行操作。
这种层设置比较简单,没有额外的参数。
层类型:
Sigmoid
示例:
layer{
name:
"encode1neuron"
bottom:
"encode1"
top:
"encode1neuron"
type:
"Sigmoid"
}
2、ReLU/Rectified-LinearandLeaky-ReLU
ReLU是目前使用最多的激活函数,主要因为其收敛更快,并且能保持同样效果。
标准的ReLU函数为max(x,0),当x>0时,输出x;当x<=0时,输出0
f(x)=max(x,0)
层类型:
ReLU
可选参数:
negative_slope:
默认为0.对标准的ReLU函数进行变化,如果设置了这个值,那么数据为负数时,就不再设置为0,而是用原始数据乘以negative_slope
layer{
name:
"relu1"
type:
"ReLU"
bottom:
"pool1"
top:
"pool1"
}
RELU层支持in-place计算,这意味着bottom的输出和输入相同以避免内存的消耗。
3、TanH/HyperbolicTangent
利用双曲正切函数对数据进行变换。
层类型:
TanH
layer{
name:
"layer"
bottom:
"in"
top:
"out"
type:
"TanH"
}
4、AbsoluteValue
求每个输入数据的绝对值。
f(x)=Abs(x)
层类型:
AbsVal
layer{
name:
"layer"
bottom:
"in"
top:
"out"
type:
"AbsVal"
}
5、Power
对每个输入数据进行幂运算
f(x)=(shift+scale*x)^power
层类型:
Power
可选参数:
power:
默认为1
scale:
默认为1
shift:
默认为0
layer{
name:
"layer"
bottom:
"in"
top:
"out"
type:
"Power"
power_param{
power:
2
scale:
1
shift:
0
}
}
6、BNLL
binomialnormalloglikelihood的简称
f(x)=log(1+exp(x))
层类型:
BNLL
layer{
name:
"layer"
bottom:
"in"
top:
"out"
type:
“BNLL”
}
4.其它常用层及参数
本文讲解一些其它的常用层,包括:
softmax_loss层,InnerProduct层,accuracy层,reshape层和dropout层及其它们的参数配置。
1、softmax-loss
softmax-loss层和softmax层计算大致是相同的。
softmax是一个分类器,计算的是类别的概率(Likelihood),是LogisticRegression的一种推广。
LogisticRegression只能用于二分类,而softmax可以用于多分类。
softmax与softmax-loss的区别:
softmax计算公式:
而softmax-loss计算公式:
关于两者的区别更加具体的介绍,可参考:
softmaxvs.softmax-loss
用户可能最终目的就是得到各个类别的概率似然值,这个时候就只需要一个Softmax层,而不一定要进行softmax-Loss操作;或者是用户有通过其他什么方式已经得到了某种概率似然值,然后要做最大似然估计,此时则只需要后面的softmax-Loss而不需要前面的Softmax操作。
因此提供两个不同的Layer结构比只提供一个合在一起的Softmax-LossLayer要灵活许多。
不管是softmaxlayer还是softmax-losslayer,都是没有参数的,只是层类型不同而也
softmax-losslayer:
输出loss值
layer{
name:
"loss"
type:
"SoftmaxWithLoss"
bottom:
"ip1"
bottom:
"label"
top:
"loss"
}
softmaxlayer:
输出似然值
layers{
bottom:
"cls3_fc"
top:
"prob"
name:
"prob"
type:
“Softmax"
}
2、InnerProduct
全连接层,把输入当作成一个向量,输出也是一个简单向量(把输入数据blobs的width和height全变为1)。
输入:
n*c0*h*w
输出:
n*c1*1*1
全连接层实际上也是一种卷积层,只是它的卷积核大小和原数据大小一致。
因此它的参数基本和卷积层的参数一样。
层类型:
InnerProduct
lr_mult:
学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。
如果有两个lr_mult,则第一个表示权值的学习率,第二个表示偏置项的学习率。
一般偏置项的学习率是权值学习率的两倍。
必须设置的参数:
num_output:
过滤器(filfter)的个数
其它参数:
weight_filler:
权值初始化。
默认为“constant",值全为0,很多时候我们用"xavier"算法来进行初始化,也可以设置为”gaussian"
bias_filler:
偏置项的初始化。
一般设置为"constant",值全为0。
bias_term:
是否开启偏置项,默认为true,开启
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"
}
}
}
3、accuracy
输出分类(预测)精确度,只有test阶段才有,因此需要加入include参数。
层类型:
Accuracy
layer{
name:
"accuracy"
type:
"Accuracy"
bottom:
"ip2"
bottom:
"label"
top:
"accuracy"
include{
phase:
TEST
}
}
4、reshape
在不改变数据的情况下,改变输入的维度。
层类型:
Reshape
先来看例子
layer{
name:
"reshape"
type:
"Reshape"
bottom:
"input"
top:
"output"
reshape_param{
shape{
dim:
0#copythedimensionfrombelow
dim:
2
dim:
3
dim:
-1#inferitfromtheotherdimensions
}
}
}
有一个可选的参数组shape,用于指定blob数据的各维的值(blob是一个四维的数据:
n*c*w*h)。
dim:
0表示维度不变,即输入和输出是相同的维度。
dim:
2或dim:
3将