前言
层结构,是神经网络(Neural Networks)建模和计算的最基本单元。由于神经网络有不同的层结构,不同类型的层又有不同的参数。所以,对Caffe的每一层配置都不一样,而层结构和参数都预先定义在prototxt文件中,在此,我们对最新版Caffe模型的层结构做一个简要的总结。
如需要转载,请注明出处:http://blog.csdn.net/ws_20100
由于水平有限,如果有错误,敬请指正。
1. 视觉层(Vision Layers)
- 头文件:./include/caffe/vision_layers.hpp
视觉层通常将图像作为输入,并将处理后的图像作为输出。一个典型的图像,一般具有一个通道(
1. 卷积层(Convolution)
- 类型:Convolution
- CPU实现代码:./src/caffe/layers/convolution_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/convolution_layer.cu
- 参数(ConvolutionParameter convolution_param)
- 必要参数:
num_output (c_o):滤波器数量。
kernel_size (or kernel_h and kernel_w):指定每个滤波器的高度和宽度。 - 强烈建议参数:
weight_filler:滤波器的初始分布和分布参数。
bias_filler:[默认: type: ‘constant’ value: 0] - 可选参数:
bias_term:[默认:true]指定是否在滤波器输出之后学习并应用附加的偏置。
pad (or pad_h and pad_w):[默认:0]指定输入的每一边(暗中)加上多少像素个数。
stride (or stride_h and stride_w):[默认:1]指定输入滤波器的间隔。
group (g):[默认:1]如果g>1,我们将每个滤波器的连接限制到输入图像的一个子集中;具体来说,输入和输出通道被分为了g个组,并且第i 组的输出通道仅仅与第i 组的输入通道相连接。
- 必要参数:
- 输入:
- n * c_i * h_i * w_i
- 输出
- n * c_o * h_o * w_o,其中h_o = (h_i + 2 * pad_h - kernel_h) /stride_h + 1,w_o通过同样的方法计算。
- 例子(在./examples/imagenet/imagenet_train_val.prototxt可以见到):
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
# learning rate and decay multipliers for the filters
param { lr_mult: 1 decay_mult: 1 }
# learning rate and decay multipliers for the biases
param { lr_mult: 2 decay_mult: 0 }
convolution_param {
num_output: 96 # learn 96 filters
kernel_size: 11 # each filter is 11x11
stride: 4 # step 4 pixels between each filter application
weight_filler {
type: "gaussian" # initialize the filters from a Gaussian
std: 0.01 # distribution with stdev 0.01 (default mean: 0)
}
bias_filler {
type: "constant" # initialize the biases to zero (0)
value: 0
}
}
}
2. 池化层(Pooling)
- 类型:Pooling
- CPU实现代码:./src/caffe/layers/pooling_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/pooling_layer.cu
- 参数(PoolingParameter pooling_param)
- 必要参数:
kernel_size (or kernel_h and kernel_w):指定每个滤波器的高度和宽度。 - 可选参数:
pool :[默认:MAX]池化方法,目前有MAX,AVE,STOCHASTIC。
pad (or pad_h and pad_w):[默认:0]指定输入的每一边(暗中)加上多少像素个数。
stride (or stride_h and stride_w):[默认:1]指定输入滤波器的间隔。
- 必要参数:
- 输入:
- n * c * h_i * w_i
- 输出
- n * c * h_o * w_o,其中h_o 和 w_o 通过和卷积层同样的方法计算。
- 例子(在./examples/imagenet/imagenet_train_val.prototxt可以见到):
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3 # pool over a 3x3 region
stride: 2 # step two pixels (in the bottom blob) between pooling regions
}
}
3.LRN层(Local Response Normalization)
- 类型:LRN
- CPU实现代码:./src/caffe/layers/lrn_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/lrn_layer.cu
- 参数(LRNParameter lrn_param)
- 可选参数:
local_size :[默认:5]用于求和的通道数(跨通道LRN),或者用于求和的正方形区域的边长(通道内LEN)。
alpha :[默认:1]缩放参数(见下面介绍)。
beta:[默认:5]指数(见下面介绍)。
norm_region:[默认:ACROSS_CHANNELS]指定对邻近通道求和(ACROSS_CHANNELS)还是对相邻空间位置求和(WITHIN_CHANNELS)。
- 可选参数:
局部响应正则化层,通过对局部输入区域进行正则化,以达到一种”侧抑制”的作用。在ACROSS_CHANNELS模式中,局部区域扩展到了相邻通道,但是没有空间扩展(例如,它们的大小为local_size x 1 x 1)。在WITHIN_CHANNEL模式中,局部区域存在空间扩展,但是是在单独的通道中(例如,它们的大小为1 x local_size x local_size)。每个输入值要除以
(1+(α/n)∑ix2i)β ,其中,n 是局部区域的尺寸,并对以该值为中心的区域进行求和(如果需要会增加0填充)。
4.im2col
对于将图像转化为列向量的变换,im2col是一个很有用的工具,而你多数情况下并不需要知道它。im2col将所有的块布局到一个矩阵,将Caffe原始的卷积操作转换为矩阵乘法。
2.损耗层(Loss Layers)
损耗层通过比较输出和目标的差值并最小化代价来驱动学习。损耗自身通过前向传播计算,而损耗的梯度 w.r.t 通过反向传播计算。
1.Softmax
- 类型: SoftmaxWithLoss
softmax loss层会计算它输入数据softmax的多项式逻辑损耗。在概念上等效于,在多项式逻辑loss层之后级联一个softmax层。但在数值上可以提供更为稳定的梯度。
2 Sum-of-Squares / Euclidean
- 类型: EuclideanLoss
Euclidean loss层会计算两个输入差值的平方和。公式如下:
12N∑Ni=1||x1i−x2i||22
3 Hinge / Margin
- 类型: HingeLoss
- CPU实现代码:./src/caffe/layers/hinge_loss_layer.cpp
- CUDA GPU实现代码:目前还没有
- 参数(HingeLossParameter hinge_loss_param)
- 可选参数:
norm :[默认:L1]使用的范数,目前有L1和L2范数。
- 可选参数:
- 输入:
- n * c * h * w Predictions
- n * 1 * 1 * 1 Labels
- 输出
- 1 * 1 * 1 * 1 Computed Loss
- 例子:
# L1 Norm
layer {
name: "loss"
type: "HingeLoss"
bottom: "pred"
bottom: "label"
}
# L2 Norm
layer {
name: "loss"
type: "HingeLoss"
bottom: "pred"
bottom: "label"
top: "loss"
hinge_loss_param {
norm: L2
}
}
hinge loss层计算一个一对多的hinge损耗或hinge损耗的平方。
4.Sigmoid Cross-Entropy
- 类型:SigmoidCrossEntropyLoss
5.Infogain
- 类型:InfogainLoss
6.Accuracy and Top-k
Accuracy层用来计算输出和目标输出的正确率,事实上这不是一个loss层,而且没有后向传播这一步。
3.激励层(Activation / Neuron Layers)
通常,激励层或称为神经元层,是元素级的操作,输入底层blob,并在顶层产生相同大小的blob。在以下介绍的激励层中,我们忽略输入和输出的大小,统一定义为:
- 输入
- n * c * h * w
- 输出
- n * c * h * w
1.ReLU / Rectified-Linear and Leaky-ReLU
- 类型:ReLU
- CPU实现代码:./src/caffe/layers/relu_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/relu_layer.cu
- 参数(ReLUParameter relu_param)
- 可选参数:
negative_slope :[默认:0]指定如何去除负值。通过乘以一个斜率值(1)还是设置负数值为0(0)。
- 可选参数:
- 例子:
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
对于给定的一个输入值x,如果x > 0,ReLU层的输出为x,如果x < 0,ReLU层的输出为negative_slope * x。如果negative_slope参数没有设置,它就等价于标准ReLU函数:
max(x,0) 。它也支持原地计算,这意味着底层blob和顶层blob可以相同,以减少资源消耗。
2.Sigmoid
- 类型:Sigmoid
- CPU实现代码:./src/caffe/layers/sigmoid_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/sigmoid_layer.cu
- 例子(在./examples/mnist/mnist_autoencoder.prototxt可以见到):
layer {
name: "encode1neuron"
bottom: "encode1"
top: "encode1neuron"
type: "Sigmoid"
}
Sigmoid层对每个输入元素x计算其
sigmoid(x) 值作为输出。
3.TanH / Hyperbolic Tangent
- 类型:TanH
- CPU实现代码:./src/caffe/layers/tanh_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/tanh_layer.cu
- 例子:
layer {
name: "layer"
bottom: "in"
top: "out"
type: "TanH"
}
TanH层对每个输入元素x计算其
tanh(x) 值作为输出。
4.Absolute Value
- 类型:AbsVal
- CPU实现代码:./src/caffe/layers/absval_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/absval_layer.cu
- 例子:
layer {
name: "layer"
bottom: "in"
top: "out"
type: "AbsVal"
}
AbsVal层对每个输入元素x计算其
abs(x) 值作为输出。
5.Power
- 类型:Power
- CPU实现代码:./src/caffe/layers/power_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/power_layer.cu
- 参数(PowerParameter power_param)
- 可选参数:
power :[默认:1]。
scale :[默认:1]。
shift :[默认:0]。
- 可选参数:
- 例子:
layer {
name: "layer"
bottom: "in"
top: "out"
type: "Power"
power_param {
power: 1
scale: 1
shift: 0
}
}
Power层对每个输入元素x计算其
(shift+scale∗x)power 值作为输出。
6.BNLL
- 类型:BNLL
- CPU实现代码:./src/caffe/layers/bnll_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/bnll_layer.cu
- 例子:
layer {
name: "layer"
bottom: "in"
top: "out"
type: BNLL
}
BNLL(binomial normal log likelihood)层对每个输入元素x计算其
log(1+ex) 值作为输出。
4.数据层(Data Layers)
数据通过数据层进入Caffe:它们处于网络的底部。数据可以来自于有效的数据库(LevelDB或者LMDB),直接来自于内存,或者,当效率不是关键因素时,数据可以来自于磁盘的HDF5文件或通用的图像格式文件。
通过指定TransformationParameters可以进行常用的输入预处理(减去均值、缩放、随机裁剪、镜像处理)。
1.Database
- 类型:Data
- 参数
- 必要参数:
source:包含数据库的目录名。
batch_size:一次性输入的数据量。 - 可选参数:
rand_skip:开始时,跳到指定的输入数据上;对异步随机梯度下降有用。
backend:[默认:LEVELDB]选择使用LEVELDB还是LMDB。
- 必要参数:
2.In-Memory
- 类型:MemoryData
- 参数
- 必要参数:
batch_size,channels,height,width:指定从内存中读取的输入块的大小。
- 必要参数:
memory data层直接从内存中读取数据,而不进行拷贝操作。为了使用它,必须调用MemoryDataLayer::Reset(C++中)或者Net.set_input_arrays(Python中),使用一个四维行向量来指定连续数据的来源,并且每次只读batch_size大小的数据块。
3.HDF5 Input
- 类型:HDF5Data
- 参数
- 必要参数:
source:需要读取的文件名。
batch_size:一次性输入的数据量。
- 必要参数:
- 例子(来自自己的程序):
layer {
name: "data"
type: "HDF5Data"
top: "data"
top: "label"
hdf5_data_param {
source: "examples/CNN/train.txt"
batch_size: 128
}
include: { phase: TRAIN }
}
layer {
name: "data"
type: "HDF5Data"
top: "data"
top: "label"
hdf5_data_param {
source: "examples/CNN/test.txt"
batch_size: 2
}
include: { phase: TEST }
}
4.HDF5 Output
- 类型:HDF5Data
- 参数
- 必要参数:
file_name:需要写入的文件名。
- 必要参数:
HDF5 output层与这节中的其他层相反,它将输入blob写入到磁盘中。
5.Images
- 类型:ImageData
- 参数
- 必要参数:
source:一个文本文件的名称,文件中每一行给定一幅图像的文件名和标号。
batch_size:一起批处理的图像数目。 - 可选参数:
rand_skip
shuffle:[默认:false]。
new_height,new_width:如果提供此参数,将图像调整到新的尺寸。
- 必要参数:
6.Windows
- 类型:WindowData
7.Dummy
DummyData用于开发和调试。请见DummyDataParameter
5. 通用层(Common Layers)
1.全连接层(Inner Product)
- 类型:InnerProduct
- CPU实现代码:./src/caffe/layers/inner_product_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/inner_product_layer.cu
- 参数(InnerProductParameter inner_product_param)
- 必要参数:
num_output (c_o):滤波器数量。 - 强烈建议参数:
weight_filler:滤波器的初始分布和分布参数。 - 可选参数:
bias_filler:[默认: type: ‘constant’ value: 0]
bias_term:[默认:true]指定是否在滤波器输出之后学习并应用附加的偏置。
- 必要参数:
- 输入:
- n * c_i * h_i * w_i
- 输出
- n * c_o * 1 * 1
- 例子
layer {
name: "fc8"
type: "InnerProduct"
# learning rate and decay multipliers for the weights
param { lr_mult: 1 decay_mult: 1 }
# learning rate and decay multipliers for the biases
param { lr_mult: 2 decay_mult: 0 }
inner_product_param {
num_output: 1000
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
bottom: "fc7"
top: "fc8"
}
InnerProduct层(通常也称为全连接层),将输入数据以简单的向量形式进行处理,并且输出一个简单的向量(blob的高度,宽带为1)。
2.Splitting
Splitting层可以把一个输入blob分离成多个输出blobs。这个用在需要把一个blob输入到多个输出层的情形。
3.Flattening
Flattening层是把一个输入的大小为n * c * h * w的数据变成一个简单的向量,其大小为 n * (c * h * w)。
4.Reshape
- 类型:Reshape
- 实现代码:./src/caffe/layers/reshape_layer.cpp
- 参数(ReshapeParameter reshape_param)
- 可选参数:(在以下的详述中也可以查看)
sharp
- 可选参数:(在以下的详述中也可以查看)
- 输入:
- 一个任意维度的blob
- 输出
- 同一个blob,只不过维度依据reshape_param进行过修改
- 例子
layer {
name: "reshape"
type: "Reshape"
bottom: "input"
top: "output"
reshape_param {
shape {
dim: 0 # copy the dimension from below
dim: 2
dim: 3
dim: -1 # infer it from the other dimensions
}
}
}
Resharp层可以用于改变输入的维度,而不改变其自身的数据。和Flatten层一样,仅仅改变维度,在过程中不涉及数据拷贝操作。输出维度通过ReshapeParam的proto文件指定。直接使用正数设置对应的输出blob维度。另外,两个特殊的值也可以用于设置任何目标维度值。
- 0 代表“拷贝底层相应的维度“。就是说,如果给定dim: 0作为第一个维度,则底层第一个维度如果是2,顶层第一个维度也会是2。
- -1 代表“从其他维度推断“。它的性质有点类似于numpy中的-1,或者MATLAB的resharp中的
[] :计算出的维度与底层保持相同的整体元素数。多数情况下,-1可以用于resharp操作。另一个例子:指定resharp_param { sharp { dim: 0 dim: -1 } },这样,这层的性质与Flatten层完全一样。
5.Concatenation
- 类型:Concat
- CPU实现代码:./src/caffe/layers/concat_layer.cpp
- CUDA GPU实现代码:./src/caffe/layers/concat_layer.cu
- 参数(ConcatParameter concat_param)
- 可选参数:
axis:[默认: 1]0代表根据num串连,1代表根据channel串连。
- 可选参数:
- 输入:
- n_i * c_i * h * w 其中,i为输入blob标号,从1到K。
- 输出
- 如果axis = 0; (n_1 + n_2 + … + n_K) * c_1 * h * w,且所有的输入c_i必须一样。
- 如果axis = 1; n_1 * (c_1 + c_2 + … + c_K) * h * w,且所有的输入n_i必须一样。
- 例子
layer {
name: "concat"
bottom: "in1"
bottom: "in2"
top: "out"
type: "Concat"
concat_param {
axis: 1
}
}
Concat层将串连多个输入blob,成为一个单一的输出blob。
6.Slicing
Slice层将一个输入层根据切割指标给定的维度(现在只有num和channel)切割成多个输出层。
- 例子
layer {
name: "slicer_label"
type: "Slice"
bottom: "label"
## Example of label with a shape N x 3 x 1 x 1
top: "label1"
top: "label2"
top: "label3"
slice_param {
axis: 1
slice_point: 1
slice_point: 2
}
}
axis指定目标轴;slice_point指定选定维数的索引(索引的数量必须等于blob数量减去一)。
7.Elementwise Operations
- 类型:Eltwise
8.Argmax
- 类型:ArgMax
9.Softmax
- 类型:Softmax
10.Mean-Variance Normalization
- 类型:MVN
参考资料
Caffe下载地址:https://github.com/BVLC/caffe