原文网址:http://caffe.berkeleyvision.org/tutorial/layers.html
此为Caffe官网的层讲解部分。
层讲解
要创建一个Caffe模型我们必须要在协议缓冲区(prototxt)先定义一个模型架构。Caffe的层及其参数都被定义在协议缓冲区caffe.proto。
视觉层
- 头文件:./include/caffe/vision_layers.hpp
通常视觉层将输入图像后会输出其他的图像,在现实世界中。一幅灰度图像有一个色彩通道(c = 1),一个RGB图像拥有3个通道(c = 3),但是在本文中,用于区别图像的特征是它的空间结构:通常一幅图像有不同的高h和宽w(其值均大于1)。这种2D几何特征会使得在如何处理输入的选择上不同,大多数的视觉层都会对输入的局部用一些特殊的处理来得到局部的输出,相反地,其他的层(只有个别反例)会忽略掉输入的空间结构,只将其看做chw维的大向量。
卷积(convolution)
- 层类型:Convolution(卷积层)
- CPU实现:./src/caffe/layers/convolution_layer.cpp
- CUDA GPU实现:./src/caffe/layers/convolution_layer.cu
- 卷积参数
- 必需参数
- num_output(c_o):滤波器的数目,也可以说卷积核的数目
- kernel_size(kernel_h kernel_w):每个卷积核的大小
- 强烈建议
- 权重滤波器[默认类型:'constant'取值:0]
- 可选参数
- bias_term[默认值 true]:是否学习并对滤波器的输出加上一组偏置
- pad(pad_h pad_w)[默认值 0]:在输入的每边进行像素值扩展
- stride(stride_h 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同理
- 举例(详见./models/bvlc_reference_caffenet/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
}
}
}
卷积层包括含有一组可学习滤波器的输入图像,每个滤波器都能在输出中产生一个特征图。
池化(pool)
- 层类型:Pooling(池化层)
- CPU实现:./src/caffe/layers/pooling_layer.cpp
- CUDA GPU实现:./src/caffe/layers/pooling_layer.cu
- 池化参数
- 必需参数
- Kernel_size(kernel_h kernel_w):每个滤波器的高和宽
- 可选参数
- pool[默认值 MAX]:池化方法,现在有MAX, AVE, STOCHASTIC
- pad(pad_h pad_w):[默认值 0] 在输入的每边进行像素值扩展
- stride(stride_h stride_w):[默认值 1] 每次移动卷积核的步长
- 必需参数
- 输入
- n * c * h_i * w_i
- 输出
- n * c * h_o * w_o, h_o和w_o的计算与卷积层相同
- 示例 (详见 ./models/bvlc_reference_caffenet/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
}
}
局部响应归一化(LRN)
- 层类型:LRN(局部响应归一化层)
- CPU实现:./src/caffe/layers/lrn_layer.cpp
- CUDA GPU实现:./src/caffe/layers/lrn_layer.cu
- LRN参数
- 可选参数
- local_size[默认值 5] : 通道数相加的个数(对交叉通道LRN)相加方形区域的边长
- alpha[默认值 1]:伸缩参数(见下)
- beta[默认值 5]:指数(见下)
- norm_region[默认值 ACROSS_CHANNELS]:是将邻近通道值进行相加( ACROSS_CHANNELS)还是将空间上相邻的进行相加( WITHIN_CHANNEL)
- 可选参数
局部响应归一化层是一种通过归一化局部输入的“侧边抑制”,在ACROSS_CHANNELS模式中,局部区域是由临近通道组成的(大小为local_size * 1 * 1),不具有空间相关性,在WITHIN_CHANNEL模式中,局部区域是由临近空间区域扩展得到的(大小为1 * lacal_size * lacal_size),但是在不相邻的通道。每个输入图像被分为
,n是每个局部区域的大小,局部区域相加后的结果放置在区域的中间(如需填充默认为零元素填充)。
im2col
im2col是用来帮助进行图像矩阵和图像向量转换的,不需要知道它是怎么实现的,它在Caffe的原始卷积中通过列出分块矩阵而用于矩阵相乘。
损失层
Caffe通过损失函数使输出结果与目标结果相比较来促进学习过程,并逐渐使损失减小,损失函数通过前向传递计算,梯度通过后向传播计算。
Softmax
- 层类型:SoftmaxWithLoss(广义线性回归分析损失层)
Softmax损失层计算Softmax的输入的多项逻辑损失,它在理论上等同于Softmax层后跟着多项逻辑损失层,但是可得到更多数值的稳定梯度。
平方和/欧几里得距离(Sum-of-Squares / Euclidean)
- 层类型:EuclideanLoss(欧式损失层)
欧几里得损失层计算两个输入的欧几里得距离,
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预测值
- n * 1 * 1 * 1标签值
- 输出
- 1 * 1 * 1 * 1计算出的损失
- 样例
# 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
}
}
链接损失层计算出一个与所有链接相关的损失数或者是它的平方值。
Sigmoid互熵(Sigmoid Cross-Entropy)
Sigmoid互熵损失(SigmoidCrossEntropyLoss)
(没有详解)
Infogain
层类型:InfogainLoss
(没有详解)
准确度与前k排名(Accuracy and Top-k)
类型(type):Accuracy
计算输出的准确率(相对于target),事实上这不是一个损失数值,也没有后向传播。
激励/神经元层
一般来说激励/神经元层是以元素为单位的操作算子,对每个输入(上一级的blob)产生一个相同大小的输出(下一级的blob),在本层之后将不再考虑输入与输出的大小,因为它们大小均相同。
- 输入
- n * c * h * w
- 输出
- n * c * h * w
改进的线性单元(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 ] :当输入为x负数时,指定输出为negative_slope * x;默认值为0.
- 可选参数
- 样例(详见./models/bvlc_reference_caffenet/train_val.prototxt)
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
给定一个输入值x,ReLU层的输出为:x > 0 ? x : negative_slope * x,如未给定参数negative_slope的值,则为标准ReLU方法:max(x, 0)。ReLU层支持原位计算,输出会覆盖输入,以节省内存空间。
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"
}
对于每一个输入值x,Sigmoid层的输出为sigmoid(x)
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"
}
对于每一个输入值x,TanH层的输出为tanh(x).
绝对值(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"
}
对于每一个输入值x,AbsVal层的输出为abs(x).
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
}
}
对于每一个输入值x,Power层的输出为(shift + scale * x) ^ power
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
}
对于每一个输入值x,BNLL层(binomial normal log likelihood,二项正态对数似然)的输出为log(1 + exp(x))
数据层
数据通过数据层进入Caffe:数据层位于网络的底部。数据可以来自:1、高效的数据库(LevelDB或 LMDB);2、内存;3、HDF5或image文件(效率低)。
基本的输入预处理(例如:减去均值,缩放,随机裁剪,镜像处理)可以通过指定TransformationParameter达到。
数据库(Database)
- 层类型:Data
- 参数
- 必需参数
- source :包含数据库的路径
- batch_size :每次处理的输入的数据量
- 可选参数
- rand_skip :在开始的时候跳过这个数值量的输入;这对于异步随机梯度下降是非常有用的
- backend[默认值 LEVELDB]:选择使用LEVELDB数据库还是LMDB数据库,默认为LEVELDB
- 必需参数
内存读取(In-Memory)
- 层类型:MemoryData
- 参数
- 必需参数
- batch_size, channels, height, width : 4个值,确定每次读取输入数据量的大小
- 必需参数
Memory Data层从内存直接读取数据(而不是复制数据)。使用Memory Data层之前,必须先调用MemoryDataLayer::Reset(C++方法)或Net.set_input_arrays(Python方法)以指定一个连续的数据来源(4D,按行排列),每次读取大小由batch_size决定。
HDF5格式输入(HDF5 Input)
- 层类型:HDF5Data
- 参数
- 必需参数
- source :读取文件的名称
- batch_size :每次处理的输入的数据量
- 必需参数
HDF5格式输出(HDF5 Output)
- 层类型:HDF5Output
- 参数
- 必需参数
- file_name :写入文件的名称
- 必需参数
HDF5 output层与这部分的其他层的功能正好相反,不是读取而是将其输入blobs写入磁盘。
图像格式(Images)
- 层类型:ImageData
- 参数
- 必需参数
- source :一个text文件的名称,text文件中每一行指定一个图像(image)文件名和标签(label)
- batch_size :每次处理的image的个数
- 可选参数
- rand_skip :在开始的时候跳过这个数值量的输入
- shuffle[默认值 false] : 是否随机乱序,默认为否
- new_height, new_width :缩放所有的images到新的大小
- 必需参数
Windows
层类型:WindowData
(没有详解)
Dummy
层类型:DummyData
DummyData用于开发和测试,详见DummyDataParameter
共用层
内积/全连接(Inner Product)
- 层类型:InnerProduct
- CPU实现:./src/caffe/layers/inner_product_layer.cpp
- GPU实现:./src/caffe/layers/inner_product_layer.cpp
- 参数(InnerProductParameter inner_product_param)
- 必需参数
- num_output(c_o):滤波器数目
- 强烈推荐
- weight_filler[默认类型:'constant'默认值:0]:滤波器权重;默认类型为constant,默认值为0
- 可选参数
- bias_filler[默认类型: 'constant' 默认值:0]:滤波器偏置项的值,默认类型为constant,默认值为0
- bias_term[默认值 true]:是否添加偏置项,默认为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层(常被称为全连接层)将输入视为一个向量(vector),输出也是一个向量(vector)(输出的高度(height)和宽度(width)被设为1)
Splitting
层类型:Split
Split层用于将一个输入的blob分离成多个输出的blob,这用于当需要将一个blob输入至多个输出层时。
Flattening
层类型:Flatten
Flatten层用于把一个维度为n * c * h * w的输入转化为一个维度为 n * (c*h*w)的向量输出。
Reshape
- 层类型:Reshape
- 实现:./src/caffe/layers/reshape_layer.cpp
- 参数(ReshapeParameter reshape_param)
- 可选参数(也请参阅下面的详细描述)
- Shape:改变后的维度
- 可选参数(也请参阅下面的详细描述)
- 输入
- 一个任意维度的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
}
}
}
Reshape层只改变输入数据的维度,但内容不变,也没有数据复制的过程,与Flatten层类似。
输出维度由reshape_param指定,正整数直接指定维度大小,两个特殊值的含义如下:
- 0 =>表示copy the respective dimension of the bottom layer,复制输入相应维度的值。
- -1 =>表示infer this from the other dimensions,这类似于numpy中的-1及MATLAB中的[]来调整大小:根据其他维度自动推测维度大小。reshape_param中至多只能有一个-1。
再举一个例子:如果指定reshape_param参数为:{ shape { dim: 0 dim: -1 } } ,那么输出和Flattening layer的输出是完全一样的。
连结层(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的维度是n_i * c_i * h * w,共K个
- 输出
- axis = 0时,输出 blob的维度为(n_1 + n_2 +… + n_K) * c_1 * h * w,要求所有的input的channel相同
- axis = 1时,输出 blob的维度为n_1 * (c_1 + c_2 +… + c_K) * h * w,要求所有的input的num相同
- 样例
layer {
name: "concat"
bottom: "in1"
bottom: "in2"
top: "out"
type: "Concat"
concat_param {
axis: 1
}
}
Concat层用于把多个输入blob连结成一个输出blob
Slicing
- 层类型:Slice
Slice层用于将一个input层分割成多个output层,根据给定的维度(目前只能指定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表明是哪一个维度(axis = 0 -> num或者axis = 1 -> channel),slice_point是该维度的索引,slice_point的数量必须是top blobs的数量减1.
Elementwise Operations
层类型:Eltwise
(没有详解)
Argmax
层类型:ArgMax
(没有详解)
Softmax
层类型:Softmax
(没有详解)
Mean-Variance Normalization
层类型:MVN
(没有详解)
【caffe】官网层结构译文
最新推荐文章于 2020-08-02 17:04:36 发布