博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Layers Of Caffe
阅读量:5251 次
发布时间:2019-06-14

本文共 10010 字,大约阅读时间需要 33 分钟。

  本文试图描述构建一个网络结构的layers,可以用prototxt脚本直接写,也可以用python接口实现。

  最简单的神经网络包含但不限于以下四部分:

        数据层(Data): Data、ImageData

        激活层(Activation): sigmoid、tanh、relu

        视觉层(vision) :Convolution、Pooling、 Local Response Normalization (LRN)、 im2col

        输出层(output): softmax_loss、Inner Product、accuracy、reshape、dropout

A、数据层(Data)

  数据层是每个模型的最底层,是模型的入口,不仅提供数据的输入,也提供数据从Blobs转换成别的格式进行保存输出。通常数据的预处理(如减去均值, 放大缩小, 裁剪和镜像等),也在这一层设置参数实现。

  数据来源来自:

  高效率:高效的数据库(如LevelDB和LMDB)、内存;

  低效率:磁盘的hdf5文件、图片格式文件。

所有的数据层的都具有的公用参数:

layer {  name: "cifar"  type: "Data"  top: "data"  top: "label"  include {    phase: TRAIN  }  transform_param {    mean_file: "examples/cifar10/mean.binaryproto"    scale: 0.00390625    # 用一个配置文件来进行均值操作    mirror: 1  # 1表示开启镜像,0表示关闭,也可用ture和false来表示    # 剪裁一个 227*227的图块,在训练阶段随机剪裁,在测试阶段从中间裁剪 如果超过这个数据就会裁剪    crop_size: 227    shuffle: true  #随机打乱数据  }  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之间

1、数据来自于数据库(如LevelDB和LMDB)

  LMDB数据制作:

  计算均值文件(非必须)

  层类型(layer type):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、数据来自于图片image

层类型:ImageData

必须设置的参数:

  source: 一个文本文件的名字,每一行给定一个图片文件的名称和标签(label)

 /iamges/aaa.jpg 0

   /images/bbb.jpg 1

  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  }}

B、激活层(Activation)

在激活层中,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的。从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"}

python代码:

 

2、ReLU / Rectified-Linear and Leaky-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的输出和输入相同以避免内存的消耗。

python代码实现

relu = Layers.ReLU(inputs, in_place=True)

3、TanH / Hyperbolic Tangent

利用双曲正切函数对数据进行变换。

层类型:TanH

layer {  name: "layer"  bottom: "in"  top: "out"  type: "TanH"}

4、Absolute Value

求每个输入数据的绝对值。

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

binomial normal log likelihood的简称

f(x)=log(1 + exp(x))

层类型:BNLL

layer {  name: "layer"  bottom: "in"  top: "out"  type: “BNLL”}

 

C、视觉层(vision)

视觉层(Vision Layers)的参数,视觉层包括Convolution, Pooling, Local Response Normalization (LRN), im2col等层。

前一节中Data层用python代码实现:

data, label = L.Data(source=lmbd_file, backend=P.Data.LMDB, batch_size=batch_size_num,ntop=2,transform_parm=dict(crop_size=40,mean_file=mean_file,mirror=True))

这块预留ImageData的python实现代码:

 

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*c
0*w
0*h
0
输出:n*c
1*w
1*h
1
其中,c
1就是参数中的num_output,生成的特征图个数
 w
1=(w
0+2*pad-kernel_size)/stride+1;
 h
1=(h
0+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"  #0    }  }}

用python代码实现:

conv1 = Layer.Convolution(data,kernel_size=5, stride=1, num_output=16,pad=2,weight_filler=dict(type='xavier'))

参数:

  data为数据层传递的数据

 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*w
0*h
0
输出:n*c*w
1*h
1
和卷积层的区别就是其中的c保持不变
 w
1=(w
0+2*pad-kernel_size)/stride+1;
 h
1=(h
0+2*pad-kernel_size)/stride+1;
如果设置stride为2,前后两次卷积部分不重叠。100*100的特征图池化后,变成50*50.
python实现代码:
pool1 = Layer.Pooling(inputs,pool=Pooling.Max,kernel_size=3,stride=2)
3、Local Response Normalization (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  }}

python代码实现:

待续。。

4、im2col层

如果对matlab比较熟悉的话,就应该知道im2col是什么意思。它先将一个大矩阵,重叠地划分为多个子矩阵,对每个子矩阵序列化成向量,最后得到另外一个矩阵。

 

看一看图就知道了:

在caffe中,卷积运算就是先对数据进行im2col操作,再进行内积运算(inner product)。这样做,比原始的卷积操作速度更快。

看看两种卷积操作的异同:

D、输出层(output)

包括:softmax_loss层,Inner Product层,accuracy层,reshape层和dropout层及其它们的参数配置。

1、softmax-loss

softmax-loss层和softmax层计算大致是相同的。softmax是一个分类器,计算的是类别的概率(Likelihood),是Logistic Regression 的一种推广。Logistic Regression 只能用于二分类,而softmax可以用于多分类。

softmax与softmax-loss的区别:

softmax计算公式:

而softmax-loss计算公式:

关于两者的区别更加具体的介绍,可参考:

用户可能最终目的就是得到各个类别的概率似然值,这个时候就只需要一个 Softmax层,而不一定要进行softmax-Loss 操作;或者是用户有通过其他什么方式已经得到了某种概率似然值,然后要做最大似然估计,此时则只需要后面的 softmax-Loss 而不需要前面的 Softmax 操作。因此提供两个不同的 Layer 结构比只提供一个合在一起的 Softmax-Loss Layer 要灵活许多。

不管是softmax layer还是softmax-loss layer,都是没有参数的,只是层类型不同而已

softmax-loss layer:输出loss值

layer {  name: "loss"  type: "SoftmaxWithLoss"  bottom: "ip1"  bottom: "label"  top: "loss"}

softmax layer: 输出似然值

layers {  bottom: "cls3_fc"  top: "prob"  name: "prob"  type: “Softmax"}

python代码:

loss = Layers.SoftmaxWithLoss(fc,label)  #label是数据层的label

2、Inner Product

全连接层,把输入当作成一个向量,输出也是一个简单向量(把输入数据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"    }  }}

 python实现代码:

fc = Layers.InnerProduct(pool2, num_output=1024,weight_filler=dict(type='xavier'))

3、accuracy

输出分类(预测)精确度,只有test阶段才有,因此需要加入include参数。

层类型:Accuracy

layer {  name: "accuracy"  type: "Accuracy"  bottom: "ip2"  bottom: "label"  top: "accuracy"  include {    phase: TEST  }}

python代码实现:

accurary = Layers.Accurary(inputs,label)

4、reshape

在不改变数据的情况下,改变输入的维度。

层类型:Reshape

先来看例子

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      }    }  }

有一个可选的参数组shape, 用于指定blob数据的各维的值(blob是一个四维的数据:n*c*w*h)。

dim:0  表示维度不变,即输入和输出是相同的维度。

dim:2 或 dim:3 将原来的维度变成2或3

dim:-1 表示由系统自动计算维度。数据的总量不变,系统会根据blob数据的其它三维来自动计算当前维的维度值 。

假设原数据为:64*3*28*28, 表示64张3通道的28*28的彩色图片

经过reshape变换:

reshape_param {      shape {        dim: 0         dim: 0        dim: 14        dim: -1       }    }

输出数据为:64*3*14*56

5、Dropout

Dropout是一个防止过拟合的trick。可以随机让网络某些隐含层节点的权重不工作。

先看例子:

layer {  name: "drop7"  type: "Dropout"  bottom: "fc7-conv"  top: "fc7-conv"  dropout_param {    dropout_ratio: 0.5  }}

只需要设置一个dropout_ratio就可以了。

还有其它更多的层,但用的地方不多,就不一一介绍了。

随着深度学习的深入,各种各样的新模型会不断的出现,因此对应的各种新类型的层也在不断的出现。

 

原文链接:https://www.cnblogs.com/denny402/tag/caffe/

转载于:https://www.cnblogs.com/missidiot/p/10237745.html

你可能感兴趣的文章
帆软 控件内容 清除
查看>>
第一页 - 工具的使用(webstorm)
查看>>
.net static 变量
查看>>
The Number of set-hdu-3006
查看>>
[设计模式]适配器模式与外观模式
查看>>
自定义分页控件,修改自AspNetForums.Controls.Pager
查看>>
ssh 免签登录 亲测可以
查看>>
Linux 进程资源用量监控和按用户设置进程限制
查看>>
IE浏览器整页截屏程序(二)
查看>>
IOS小技巧积累
查看>>
web页面设计稿的完美还原
查看>>
D3.js 之 d3-shap 简介(转)
查看>>
制作满天星空
查看>>
MyBatis日记(三):戏说MyBatis配置文件
查看>>
$_POST和$GLOBALS['HTTP_RAW_POST_DATA'] 的区别
查看>>
类和结构
查看>>
遍历文件夹下所有dll的类
查看>>
Centos 7.6 部署 Jumpserver 1.5.0
查看>>
CSS3选择器(二)之属性选择器
查看>>
[转]Doing more with Outlook filter and SQL DASL syntax
查看>>