【深度学习】在Caffe中配置神经网络的每一层结构

前言

层结构,是神经网络(Neural Networks)建模和计算的最基本单元。由于神经网络有不同的层结构,不同类型的层又有不同的参数。所以,对Caffe的每一层配置都不一样,而层结构和参数都预先定义在prototxt文件中,在此,我们对最新版Caffe模型的层结构做一个简要的总结。
如需要转载,请注明出处:http://blog.csdn.net/ws_20100
由于水平有限,如果有错误,敬请指正。


1. 视觉层(Vision Layers)

  • 头文件:./include/caffe/vision_layers.hpp

视觉层通常将图像作为输入,并将处理后的图像作为输出。一个典型的图像,一般具有一个通道(c=1,灰度图像)或三个通道(c=3,RGB图像)。而在本文中,一幅图像的区分特征是它的空间结构:通常一幅图像具有一个较大的高度h>1和宽度w>1。这种二维的几何特性很自然地引领我们去恰当地处理图像输入。通常,视觉层对输入图像的局部区域进行操作,并产生与之对应的局部输出。相比而言,其他层(除了极个别例外)会忽略输入图像的空间结构,而将其作为一个维度为chw的”大向量”进行处理。

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层会计算两个输入差值的平方和。公式如下:
    12NNi=1||x1ix2i||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+scalex)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

转载于:https://www.cnblogs.com/lixuebin/p/10814861.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值