Caffe(学习2)--隐藏层详解

     在学习了上一节数据层中的参数详解后,本文内容讲主要讲述Caffe网络模型中隐藏层的独有的参数信息(name, type, bottom, top和transform_param是所有层共有参数)。

1、Convolution

卷积层是卷积神经网络(CNN)的核心层,但在这之前希望你了解卷积操作

拓展:在Pytorch中主要是通过nn.Conv2d(input_ch,output_ch,kernelsize,stride,padding)来实现的与Caffe中实现的原理一致。

层类型: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个输入分组进行连接。

输出层size计算公式 

  1. 输入:n*c0*w0*h0  [N,C,W,H]
  2. 输出:n*c1*w1*h1
  3. 其中,c1就是参数中的num_output,生成的feature_map个数
  4.  w1=(w0+2*pad-kernel_size)/stride+1;
  5.  h1=(h0+2*pad-kernel_size)/stride+1;
  6. 如果设置stride为1,前后两次卷积部分存在重叠。如果设置pad=(kernel_size-1)/2,则运算后,宽度和高度不变。

示例: 

layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1  #lr_mult: 学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。如果有两个lr_mult, 则第一个表示权值的学习率,第二个表示偏置项的学习率。一般偏置项的学习率是权值学习率的两倍。
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 20 #卷积核(filter)的个数
    kernel_size: 5 #卷积核的大小 
    stride: 1 #卷积核的步长,默认为1 
    pad: 0 #扩充边缘,默认为0,不扩充
    weight_filler {
      type: "xavier" #权值初始化。 默认为“constant",值全为0,很多时候我们用"xavier"算法来进行初始化,也可以设置为”gaussian"
    }
    bias_filler {
      type: "constant" #偏置项的初始化。一般设置为"constant",值全为0
    }
  }
}

  2、Pooling层

也叫池化层,为了减少运算量和数据维度而设置的一种层。在Pytorch中使用MaxPool2d或者AvgPool2d等方法来实现。

层类型:Pooling

必须设置的参数:

    kernel_size: 池化的核大小。也可以用kernel_h和kernel_w分别设定。

其它参数:

      pool: 池化方法,默认为MAX。目前可用的方法有MAX, AVE, 或STOCHASTIC 

   pad: 和卷积层的pad的一样,进行边缘扩充。默认为0

   *stride: 池化的步长,默认为1。一般我们设置为2,即不重叠。也可以用stride_h和stride_w来设置。这个参数很重要,决定最终输出size的大小

 示例:

layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX #池化方法,默认为MAX。目前可用的方法有MAX, AVE
    kernel_size: 3 #池化的核大小
    stride: 2 #池化的步长,默认为1。一般我们设置为2,即不重叠。
  }
}
#pooling层的运算方法基本是和卷积层是一样的。
 H1/C1=(h0/w0+2*pad-kernel_size)/stride+1;

3、激活函数

  对于激活函数,目前绝大多数论文中都是用的是ReLU,对于sigmoid,tanh等函数使用较少,详细对于可以参考我的这篇文章
f(x)=max(x,0)

layer {
  name: "relu1"
  type: "ReLU"
  bottom: "pool1"
  top: "pool1"
}

4、reshape 

   作用是在不改变数据的情况下,改变输入的维度和pytorch中x.view(x.view(0)[1],-1)用法相似,主要是对数据的维度进行调整。

有一个可选的参数组shape, 用于指定blob数据的各维的值(blob是一个四维的数据:[N,C,W,H])

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

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

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

假设原数据为:32*3*28*28, 表示32张3通道的28*28的彩色图片
    shape {
    dim: 0 
    dim: 0
    dim: 14
    dim: -1 
    }
输出数据为:32*3*14*56

示例: 

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

5、Dropout

    Dropout是一个防止过拟合的层,只需要设置一个dropout_ratio就可以了。

    Dropout说的简单一点就是:我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征,如图1所示。


                                          图1:使用Dropout的神经网络模型
2. Dropout工作流程及使用

2.1 Dropout具体工作流程

假设我们要训练这样一个神经网络,如图2所示。

                                                                       

                                                                             图2:标准的神经网络

输入是x输出是y,正常的流程是:我们首先把x通过网络前向传播,然后把误差反向传播以决定如何更新参数让网络进行学习。使用Dropout之后,过程变成如下:

(1)首先随机(临时)删掉网络中一半的隐藏神经元,输入输出神经元保持不变(图3中虚线为部分临时被删除的神经元)

                                                                                   

                                                                                   图3:部分临时被删除的神经元

(2) 然后把输入x通过修改后的网络前向传播,然后把得到的损失结果通过修改的网络反向传播。一小批训练样本执行完这个过程后,在没有被删除的神经元上按照随机梯度下降法更新对应的参数(w,b)。

(3)然后继续重复这一过程:

     恢复被删掉的神经元(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新)
     从隐藏层神经元中随机选择一个一半大小的子集临时删除掉(备份被删除神经元的参数)。
     对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)。 
     不断重复这一过程。
示例:

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

6、全连接和softmax

     经过上一层的reshape操作一般会得到一个C*W*H 的一维向量,之后进行全连接,在Pytorch中使用nn.Linker进行实现,Caffe中实现方法如下。

#全连接层,输出的是一个简单向量  参数跟卷积层一样
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"
    }
  }
}
#测试的时候输入准确率
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "ip2"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}

    之后用softmax输出各个label的confidence,softmax和softmax-loss的区别

softmax计算公式:

而softmax-loss计算公式:

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

      网络输出的结果,通过prob获取模型的最后输出,并进行后续的分类以及检测操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值