深度学习之Batch Normalization

1、Batch Normalization的引入

  在机器学习领域有个很重要的假设:IID独立同分布假设,也就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集上获得好的效果的一个基本保障。在深度学习网络中,后一层的输入是受前一层的影响的,而为了方便训练网络,我们一般都是采用Mini-Batch SGD来训练网络的(Mini-Batch SGD的两个优点是:梯度更新方向更准确和并行计算速度快)。

  我们知道在神经网络训练开始前,都要对输入数据做一个归一化处理,那么具体为什么需要归一化呢?归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。

  对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。

  除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。

  我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal  Covariate Shift”。nternal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。Batch Normalization就是来解决该问题的。Batch Normalization的基本思想就是能不能让每个隐层节点的激活输入分布固定下来,从而避免Internal Covariate Shift的问题。

2、Batch Normalization的本质思想

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

  首先我们来看下期望为0,方差为1的标准正态分布:

    

  这意味着在一个标准差范围内,也就是说64%的概率x其值落在[-1,1]的范围内,在两个标准差范围内,也就是说95%的概率x其值落在了[-2,2]的范围内。我们知道,激活值x=WU+B,U是真正的输入,x是某个神经元的激活值,假设非线性函数是sigmoid,那么看下sigmoid函数及其导数如下:

    

  我们可以从中观察到,sigmoid函数的导数范围是(0, 0.25]。假设没有经过BN调整前x的原先正态分布均值是-6,方差是1,那么意味着95%的值落在了[-8, -4]之间,那么对应的Sigmoid函数值及其导数的值都明显接近于0,这是典型的梯度饱和区,在这个区域里梯度变化很慢,导数接近于0意味着梯度变化很小甚至消失。而假设经过BN后,均值是0,方差是1,那么意味着95%的x值落在了[-2, 2]区间内,很明显这一段是sigmoid(x)函数接近于线性变换的区域,意味着x的小变化会导致非线性函数值较大的变化,也即是梯度变化较大,对应导数函数图中明显大于0的区域,就是梯度非饱和区。

  这种性质不只是适用于sigmoid函数,也适用于其他的激活函数。而且从图中经过BN后,使得大部分的激活值落入非线性函数的线性区内(也就是在0附近的那一段,很多激活函数都有这样的性质),在这里对应的导数远离导数饱和区,这样来加速训练收敛过程。

  但是从上面来看,把大部分激活值拉入到线性区,也就相当于在网络的传输过程中对输入值做了一系列的线性变换,那么此时网络的表达能力急剧下降,而且深层也没有意义(多层的线性转换和一层的线性转换是一样的)。为了解决这个问题,BN对标准化后的值X又进行了scale加上shift操作(y=scale*x+shift)。对每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者由移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区动了动。这样看似之前的标准化变换毫无意义,又回到了起点。其实不然,大神博主张俊林认为:这种做法的核心思想应该是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。这种想法看似是有一定的道理的,尽量保证激活值在非线性区域,而又不会进入到梯度饱和区。

3、Batch Normalization算法

  Batch Normalization操作就像激活函数层、卷积层、全连接层、池化层一样,也属于网络中的一层。我们要对每个隐层神经元的激活值做BN,那么就可以想象成每个隐层又加上了一层BN操作层,它位于X=WU+B激活值获得之后,非线性函数变换之前,其图示如下:

    

  具体BN网络层的前向传播过程如下

      

  在这里的期望μB是每一次Mini-Batch SGD时的Mini-Batch的均值,σB2也是Mini-Batch的方差。

  在做验证或者测试时只有一个样本的输入,此时没有Mini-Batch,那么怎么计算标准化的期望和方差呢?在训练的过程中我们会将每一次梯度下降时的Mini-Batch的期望和方差保存起来,在验证和测试时我们就用这些保存的期望和方差的期望值来作为此时的期望和方差(这句话有点拗口,其实就是在训练过程中会计算很多批Mini-Batch的期望和方差,在之后的验证和测试的时候,我们将这批Mini-Batch的期望和方差分别求平均值来作为此时的期望和方差)。具体算法流程如下:

    

    

  在得到了均值和方差之后的计算和训练时计算公式有点不一样(也只是表现形式不一样,本质和训练时是一样的):

    

  至于为什么要写成上述形式,可能是为了减少计算量,因为在实际的验证和测试时我们的γ、β、μ和σ值都是已经确实的,这样在一开始就求出

    

  然后保存起来,这样就避免了重复计算的过程。

4、Batch Normalization的优点

  1)你可以选择比较大的初始学习率,让你的训练速度飙涨。以前还需要慢慢调整学习率,甚至在网络训练到一半的时候,还需要想着学习率进一步调小的比例选择多少比较合适,现在我们可以采用初始很大的学习率,然后学习率的衰减速度也很大,因为这个算法收敛很快。当然这个算法即使你选择了较小的学习率,也比以前的收敛速度快,因为它具有快速训练收敛的特性。

  2)你再也不用去理会过拟合中drop out、L2正则项参数的选择问题,采用BN算法后,你可以移除这两项了参数,或者可以选择更小的L2正则约束参数了,因为BN具有提高网络泛化能力的特性。

  3)再也不需要使用使用局部响应归一化层了(局部响应归一化是Alexnet网络用到的方法),因为BN本身就是一个归一化网络层。

  4)可以把训练数据彻底打乱(防止每批训练的时候,某一个样本都经常被挑选到,文献说这个可以提高1%的精度,这句话我也是百思不得其解啊)。

5、Batch Normalization在CNN中的应用

   BN在CNN中的应用也同样采用共享权值的操作,把一个FilterMap看成一个整体,可以想象成是一个Filter Map对应DNN隐层中的一个神经元,所以一个Filter Map的所有神经元共享一个Scale和Shift参数,Mini-Batch里m个实例的统计量均值和方差是在p*q个神经元里共享,就是说从m*p*q个激活里面算Filter Map全局的均值和方差,这体现了Filter Map的共享参数特性,当然在实际计算的时候每个神经元还是各算各的BN转换值,只不过采用的统计量和Scale,shift参数用的都是共享的同一套值而已。

6、Batch Normalization在RNN中的应用

  对于RNN来说,希望引入BN的一个很自然的想法是在时间序列方向展开的方向,即水平方向(图1)在隐层神经元节点引入BN,因为很明显RNN在时间序列上展开是个很深的深层网络,既然BN在深层DNN和CNN都有效,很容易猜想这个方向很可能也有效。

  另外一个角度看RNN,因为在垂直方向上可以叠加RNN形成很深的Stacked  RNN,这也是一种深层结构,所以理论上在垂直方向也可以引入BN,也可能会有效。但是一般的直觉是垂直方向深度和水平方向比一般深度不会太深,所以容易觉得水平方向增加BN会比垂直方向效果好。

  然而关于上面两种用法还是有很多争议,不一定都能有好的结果,具体的结论可能如下:

  1)RNN垂直方向引入BN的话:如果层数不够深(感觉5层是各分界线),那么BN的效果不稳定或者是有损害效果,如果深度足够的话,是能够加快训练收敛速度和泛化性能的。

  2)在隐层节点做BN的话:

    

  就是对水平序和垂直序单独做BN,然后再相加。

  3)在水平方向做BN时,因为RNN在不同时间点水平展开后参数共享的,所以就产生了BN在不同时间序列的参数也是共享的,事实证明这是不行的。因此BN在RNN中在每个时间点神经元上必须维护各自的统计量和参数。

  4)在水平方向做BN时,Scala参数要足够小,一般设置为0.1是可以的。

 

参考文献:

  Batch Normalization导读

  CNN和RNN中如何引入BatchNorm

  深度学习(二十九)Batch Normalization 学习笔记

  [深度学习] Batch Normalization算法介绍

原文地址:https://www.cnblogs.com/jiangxinyang/p/9372678.html

时间: 2024-09-30 00:07:07

深度学习之Batch Normalization的相关文章

深度学习中batch normalization

目录 1  Batch Normalization笔记 1.1  引包 1.2  构建模型: 1.3  构建训练函数 1.4  结论 Batch Normalization笔记 我们将会用MNIST数据集来演示这个batch normalization的使用, 以及他所带来的效果: 引包 import tensorflow as tf import os from tensorflow.examples.tutorials.mnist import input_data from tensorf

深度学习之Batch归一化

前言            以下内容是个人学习之后的感悟,转载请注明出处~ Batch归一化 在神经网络中,我们常常会遇到梯度消失的情况,比如下图中的sigmod激活函数,当离零点很远时,梯度基本为0.为了 解决这个问题,我们可以采用Batch归一化. 通过BN法,我们将每层的激活值都进行归一化,将它们拉到均值为0.方差为1的区域,这样大部分数据都从梯度趋于0变 换到中间梯度较大的区域,如上图中红线所示,从而解决梯度消失的问题.但是做完归一化后,函数近似于一个线性函数,多 层网络相当于一层,这不

算法工程师<深度学习基础>

<深度学习基础> 卷积神经网络,循环神经网络,LSTM与GRU,梯度消失与梯度爆炸,激活函数,防止过拟合的方法,dropout,batch normalization,各类经典的网络结构,各类优化方法 1.卷积神经网络工作原理的直观解释 https://www.zhihu.com/question/39022858 简单来说,在一定意义上,训练CNN就是在训练每一个卷积层的滤波器.让这些滤波器组对特定的模式有高的激活能力,以达到CNN网络的分类/检测等目的. 2.卷积神经网络的复杂度分析 ht

深度学习面试题21:批量归一化(Batch Normalization,BN)

目录 BN的由来 BN的作用 BN的操作阶段 BN的操作流程 BN可以防止梯度消失吗 为什么归一化后还要放缩和平移 BN在GoogLeNet中的应用 BN在GoogLeNet中的应用 BN的由来 BN是由Google于2015年提出,论文是<Batch Normalization_ Accelerating Deep Network Training by Reducing Internal Covariate Shift>,这是一个深度神经网络训练的技巧,主要是让数据的分布变得一致,从而使得

深度学习系列(1)| Dropout VS Batch Normalization? 是时候放弃Dropout了

Dropout是过去几年非常流行的正则化技术,可有效防止过拟合的发生.但从深度学习的发展趋势看,Batch Normalizaton(简称BN)正在逐步取代Dropout技术,特别是在卷积层.本文将首先引入Dropout的原理和实现,然后观察现代深度模型Dropout的使用情况,并与BN进行实验比对,从原理和实测上来说明Dropout已是过去式,大家应尽可能使用BN技术. 一.Dropout原理 根据wikipedia定义,dropout是指在神经网络中丢弃掉一些隐藏或可见单元.通常来说,是在神

吴恩达-深度学习-课程笔记-8: 超参数调试、Batch正则化和softmax( Week 3 )

1 调试处理( tuning process ) 如下图所示,ng认为学习速率α是需要调试的最重要的超参数. 其次重要的是momentum算法的β参数(一般设为0.9),隐藏单元数和mini-batch的大小. 第三重要的是神经网络的层数和学习率衰减 adam算法的三个参数一般不调整,设定为0.9, 0.999, 10^-8. 注意这些直觉是ng的经验,ng自己说了,可能其它的深度学习研究者是不这么认为的. 那么如何选择参数呢?下面介绍两个策略,随机搜索和精细搜索. 早一代的机器学习算法中,如下

Batch Normalization 学习笔记

原文:http://blog.csdn.net/happynear/article/details/44238541 今年过年之前,MSRA和Google相继在ImagenNet图像识别数据集上报告他们的效果超越了人类水平,下面将分两期介绍两者的算法细节. 这次先讲Google的这篇<Batch Normalization Accelerating Deep Network Training by Reducing Internal Covariate Shift>,主要是因为这里面的思想比较

吴恩达《深度学习》第二门课(3)超参数调试、Batch正则化和程序框架

3.1调试处理 (1)不同超参数调试的优先级是不一样的,如下图中的一些超参数,首先最重要的应该是学习率α(红色圈出),然后是Momentum算法的β.隐藏层单元数.mini-batch size(黄色圈出).再之后是Layer.learning rate decay(紫色圈出).最后是Adam算法中的β1.β2.ε. (2)用随机取值代替网格点取值.下图左边是网格点取值,如果二维参数中,一个参数调试的影响特别小,那么虽然取了25个点,其实只相当于取了5个不同的点:而右图中随机取值取了多少个点就代

深度学习之卷积神经网络CNN及tensorflow代码实现示例

一.CNN的引入 在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连的.当输入层的特征维度变得很高时,这时全连接网络需要训练的参数就会增大很多,计算速度就会变得很慢,例如一张黑白的 28×28 的手写数字图片,输入层的神经元就有784个,如下图所示: 若在中间只使用一层隐藏层,参数 w 就有 784×15=11760 多个:若输入的是28×28 带有颜色的RGB格式的手写数字图片,输入神经元就有28×28×3=2352 个-- .这很容易看出使用全连接神经网络处理图像中的需要训