• 【深度学习】在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

  • 相关阅读:
    Pandas数据存取
    Pandas统计分析
    (4)awk读取行的细节
    (3)awk命令行结构和语法结构
    安装新版gawk
    (2)BEGIN和END语句块
    (1)AWK快速入门
    shell读取文件的几种方式
    Docker 部署 elk + filebeat
    Linux之关于用户的几个重要配置文件
  • 原文地址:https://www.cnblogs.com/lixuebin/p/10814861.html
Copyright © 2020-2023  润新知