深度学习-基础知识batchNormal原理及caffe中是如何使用的

Posted 超级无敌陈大佬的跟班

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习-基础知识batchNormal原理及caffe中是如何使用的相关的知识,希望对你有一定的参考价值。

目录

Batchnorm解决的问题:

Batchnorm 原理解读

0、caffe中为什么bn层要和scale层一起使用

1、caffe中BatchNorm层参数:

2、caffe中scale层参数

三、❤❤融合BatchNorm+Scale层到卷积层进行推理加速

四、BatchNorm层训练和测试的注意事项

五、BatchNorm的好处


Batchnorm解决的问题:

简单一句话:在训练过程中,每轮迭代网络层的输入数据分布变化很大的话,使得数据抖动很大,导致权重变化也会很大,网络很难收敛。而batch norm会将数据归一化,减少不同batch间数据的抖动情况,从而提高训练速度加快收敛。

PS:不想关注的太细,该小节后面不用细看了。

机器学习领域有个很重要的假设:IID独立同分布假设,就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。那BatchNorm的作用是什么呢?BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同的分布。

如果ML系统实例集合<X,Y>中的输入值X的分布老是变,这不符合IID假设,网络模型很难稳定的学规律,这不得引入迁移学习才能搞定吗,我们的ML系统还得去学习怎么迎合这种分布变化啊。对于深度学习这种包含很多隐层的网络结构,在训练过程中,因为各层参数不停在变化,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。

BN的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致反向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。

dropout和bN抑制过拟合的方法有着统一的思想, 即:

在训练阶段引入随机性, 防止过度匹配; 在测试阶段通过求期望等方式在全局去除掉这种随机性, 从而获得确定而准确的结果。

 

Batchnorm 原理解读

加入可训练的参数alpha 和 beta的作用:

  • 防止每层特征被归一化成一样的,加入可学习的alpha 和 beta能够时网络参数有一定的分布移动和差异。

之前就说过,为了减小  ,对神经网络的每一层做归一化不就可以了,假设将每一层输出后的数据都归一化到0均值,1方差,满足正太分布,但是,此时有一个问题,每一层的数据分布都是标准正太分布,导致其完全学习不到输入数据的特征,因为,费劲心思学习到的特征分布被归一化了,因此,直接对每一层做归一化显然是不合理的。 
但是如果稍作修改,加入可训练的参数alpha 和 beta做归一化,那能防止每层特征归一化成一样,接下来结合下图的伪代码做详细的分析:

流程图:

0、caffe中为什么bn层要和scale层一起使用

这个问题首先要清楚BN的是做什么的。它其实做了两件事:

  • (1)输入归一化:x_norm = (x - mean) / var,其中mean和var是个累计计算的均值和方差。
  • (2)对归一化后的x进行比例缩放和位移:y = alpha * x_norm + beta,其中的alpha和beta是通过迭代学习得到的

那么caffe中的BN层其实只做了第一件事,scale层做了第二件事

1、caffe中BatchNorm层参数:

BatchNorm是进行归一化,计算

                  

eps是在分母的var项上加一个小值,防止方差为0时出错,默认为1e-5;

1.1 caffe的BN层共有三个参数:均值mean方差variance滑动系数moving_average_fraction

  • 参数mean,variance是由输入数据计算直接计算得到的,参数moving_average_fraction是指定的,一般为0.99,并且不通过反向传播更新;
  • 因此上面三个参数都与学习率和衰减率无关,所以网络中lr_mult和decay_mult都为0;
  • 参数moving_average_fraction应该是控制均值和方差滑动更新的系数,训练网络更新均值和方差会用到它。

1.2 BN层中还有一个参数use_global_stats

  • use_global_stats:如果为true,则使用事先保存的均值和方差,否则采用滑动平均的方式计算更新全局的均值和方差。
  • 该参数缺省时,网络测试时设置为true,训练阶段设置为false

1.3 更重要的一点:由于BN层中会做归一化处理,因此BN层前的那个卷积层应当将bias关闭,因为BN的操作会做一个减去均值的操作,因此卷积层有没有bias都会被这个减法操作去除掉,所以这时候bias不起作用,因此将其关闭可以减少参数量且不影响模型准确率。

在测试时,所使用的均值和方差是整个训练集的均值和方差。整个训练集的均值和方差的值通常是在训练的同时用移动平均法来计算的。

layer {
  name: "conv1_bn"
  type: "BatchNorm"
  bottom: "conv1"
  top: "conv1"
  batch_norm_param {  
        use_global_stats: true #训练时为false,测试时为true 
  }  
  #参数mean,variance是由输入数据计算直接计算得到的,moving_average_fraction是指定的,
  #因此都与学习率和衰减率无关,所以lr_mult和decay_mult都为0
  param {	#参数mean均值
    lr_mult: 0.0  #网络当前层的局部学习率.当前层学习率=base_lr*lr_mult;base_lr为网络基础学习率
    decay_mult: 0 #网络当前层的局部衰减率	
  }
  param {	#参数variance方差
    lr_mult: 0.0
  }
  param {	#参数moving_average_fraction滑动系数,默认0.999
    lr_mult: 0.0
  }
}

2、caffe中scale层参数

Scale是将BatchNorm得到的数据做线性变换:

 

bias_term在这里打开!学习率系数设定为1即可,无需decay_mult。

layer {
  name: "conv1_scale"
  type: "Scale"
  bottom: "conv1"
  top: "conv1"
  param {
    lr_mult: 1.0
    decay_mult: 0
  }
  param {
    lr_mult: 1.0
    decay_mult: 0
  }
  scale_param {
    bias_term: true
  }
}

三、❤❤融合BatchNorm+Scale层到卷积层进行推理加速

在推理时BatchNorm非常耗时,可以将训练时学习到的BatchNorm+Scale的线性变换参数融合到卷积层。具体方法为:

  • 1、识别prototxt文件中的Batch和Scale层,直接删除(这要求BatchNorm和Scale层中top和bottom名保持一致,才能保证删除BatchNorm和Scale层后数据仍然能够正确传输,如上文中示例所用的方式)
  • 2、修改caffemodel的weight,将convolution的bias_term修改为true,并用Convolution+BatchNorm+Scale的等效weight和bias去替换原来的weight和新打开的bias_term。convolution输出值为wx+b,作为BatchNorm层的输入.
  • 3、另外,有些网络使用了dropout层防止过拟合,在预测时可直接删除dropout层,并不影响预测时数据的传输。

合并具体公式:

四、BatchNorm层训练和测试的注意事项

1:BatchNormal层:

BN层的设定一般是按照conv->bn->scale->relu的顺序来形成一个block。

use_global_stats:为True时,使用保存的均值,方差;为False时,滑动计算均值方差。在caffe中,该参数缺省的话,TEST阶段自动置为True, 其他阶段为False. 当Finetune需要freeze BN的参数时,要把该参数置为False,否则均值,方差仍在更新;

moving_average_fraction:滑动系数,默认0.999;

eps:加在var上面的,防止标准化时分母为0。

 

五、BatchNorm的好处

BatchNorm为什么NB呢,关键还是效果好。

  • 不仅仅极大提升了训练速度,收敛过程大大加快;
  • ②还能增加分类效果,一种解释是这是类似于Dropout的一种防止过拟合的正则化表达方式,所以不用Dropout也能达到相当的效果;
  • ③另外调参过程也简单多了,对于初始化要求没那么高,而且可以使用大的学习率等;

 

参考:https://blog.csdn.net/zhuiqiuk/article

 

 

以上是关于深度学习-基础知识batchNormal原理及caffe中是如何使用的的主要内容,如果未能解决你的问题,请参考以下文章

PyTorch基础(12)-- torch.nn.BatchNorm2d()方法

PyTorch基础(12)-- torch.nn.BatchNorm2d()方法

深度学习深度学习基础学习笔记

深度学习基础面试知识

PyTorch:train模式与eval模式的那些坑

深度学习中batch normalization