一:BN的解释:
 定义:
顾名思义,batch normalization嘛,就是“批规范化”咯。Google在ICML文中描述的非常清晰,即在每次SGD时,通过mini-batch来对相应的activation做规范化操作,使得结果(输出信号各个维度)的均值为0,方差为1. 最后通过加入beta和gamma来还原数据的最初分布(通过这两个参数还原输出到输入的分布),则是为了让因训练所需而“刻意”加入的BN能够有可能还原最初的输入,使得在反向传播的时候,梯度能传播的更加明显,扩大网络的容量(对数据分布的容量)
解释一:在训练深层神经网络的过程中, 由于输入层的参数在不停的变化, 因此, 导致了当前层的分布在不停的变化, 这就导致了在训练的过程中, 要求 learning rate 要设置的非常小, 另外, 对参数的初始化的要求也很高. 论文作者把这种现象称为internal convariate shift. Batch Normalization 的提出就是为了解决这个问题的. BN 在每一个 training mini-batch 中对每一个 feature 进行 normalize. 通过这种方法, 使得网络可以使用较大的 learning rate, 使得训练加速;而且, BN 具有一定的 regularization 作用.
 
 
解释二:顾名思义,batch normalization嘛,就是“批规范化”咯。Google在ICML文中描述的非常清晰,即在每次SGD时,通过mini-batch来对相应的activation做规范化操作,使得结果(输出信号各个维度)的均值为0,方差为1. 而最后的“scale and shift”操作则是为了让因训练所需而“刻意”加入的BN能够有可能还原最初的输入,增加了较大的learning rate,但是会使数据的分布发生变化,这里就是要把数据的分布还原到最初的输入分布,并且提高了learning rate。
 
大家细想便会发现,的确,对于神经网络的各层输出,由于它们经过了层内操作作用,其分布显然与各层对应的输入信号分布不同,而且差异会随着网络深度增大而增大,可是它们所能“指示”的样本标记(label)仍然是不变的,这便符合了covariate shift的定义。由于是对层间信号的分析,也即是“internal”的来由。
 
原理:
 那BN到底是什么原理呢?说到底还是为了防止“梯度弥散”。关于梯度弥散,大家都知道一个简单的栗子:。在BN中,是通过将activation规范为均值和方差一致的手段使得原本会减小的激活的值变大。
 
 为什么要使用BN:
  1.在训练时,每批次输入的数据的分布都是不一样的。
    2.经过批规范化后,使得它们数据分布基本相同。
    3.经过这样,不管输入到网络中的数据是什么分布,都可以利用BN把它进行规范化,达到差不多的分布。
    4.最后输出的时候,利用Beta和Gramma来还原数据同分布(跟每次归一化一样的数据分布,因为涉及到每个层要加归一化,所以这里是还原归一化的数据同分布),Beta和Gramma是通过学习学习到的。
 
BN就是在神经网络的训练过程中对每层的输入数据加一个标准化处理。
 
 
传统的神经网络,只是在将样本x输入输入层之前对x进行标准化处理(减均值,除标准差),以降低样本间的差异性。BN是在此基础上,不仅仅只对输入层的输入数据x进行标准化,还对每个隐藏层的输入进行标准化。
 
 
 

 
 
 
在tensorflow中的应用 

  tensorflow中具有一个这样的方法,可以让我们归一化数据

# value表示输入的value,mean表示value的均值,variance表示方差,这两个参数用来计算value的normalization,eps:分母附加值,防止除以方差时出现除0操作,默认为1e-5


# beta,gamma会在训练时进行学习


tf.nn.batch_normalization(value, mean, variance, beta, gamma, 1e-5)

  我们在训练的时候,方差和均值,需要记录一个影子变量,这个影子变量用来当输入测试集的时候,只有单一的数据,没有均值和方差(在训练的时候,是一个batch的输入,具有均值和方差),利用影子变量来记算均值和方差。影子变量可以参考这篇博客

  具体代码数据归一层的代码如下:

"""
参考 https://www.cnblogs.com/cloud-ken/p/7521609.html
加入这个衰减率的原因是为了预测下一次的方差和均值,因为当输入测试集的时候,我们要给他均值和方差,只有一个数据,没有均值和方差,在输入训练集的时候是一个batch的输入,具有均值和方差
所以使用影子变量来记录均值和方差,
所以这里分训练和不训练,为了让归一化更好,与其说是让归一化更好,实际上时,为了让输入的数据的均值和方差,更加趋向我们的测试数据分布,使其测试率更加准确。
shadow_variable = decay * shadow_variable + (1 - decay) * updated_model_variable
"""
# 数据归一化 为了提高学习率,使得数据的均值为0,方差为1,最后加入beta和gamma来还原数据分布
def batch_norm(value, is_train=True, name='batch_norm',
epsilon=1e-5, momentum=0.9):
with tf.variable_scope(name): # tf.train.ExponentialMovingAverage用于更新参数,参数越大,模型越稳定
ema = tf.train.ExponentialMovingAverage(decay=momentum) # value.get_shape().as_list()[-1] 获取value最后一维的大小
shape = value.get_shape().as_list()[-1]
#print(value,shape) # 这里加入beta和gamma的意思就是让经过归一化的数据趋近于输入时候的分布,公式中的那两个参数,这两个参数为利用梯度下降进行学习
beta = bias('beta', [shape], bias_start=0.0)
gamma = bias('gamma', [shape], bias_start=1.0) if is_train:
# 求均值和方差
batch_mean, batch_variance = tf.nn.moments(value, [0, 1, 2], name='moments')
# 定义影子变量的名字,方便以后进行调用
moving_mean = bias('moving_mean', [shape], 0.0, False)
moving_variance = bias('moving_variance', [shape], 1.0, False) # 进行衰减,不使用原来的变量,衰减均值和方差
with tf.variable_scope(tf.get_variable_scope(), reuse=False):
# 进行计算影子变量
ema_apply_op = ema.apply([batch_mean, batch_variance]) # ema.average获取影子变量(也叫滑动平均值),把移动的平均分配给moving_mean bias值,相当于平均移动多少 assign为重新赋值的操作
assign_mean = moving_mean.assign(ema.average(batch_mean))
assign_variance = moving_variance.assign(ema.average(batch_variance)) """
tf.control_dependencies指定某些操作执行的依赖关系,control_dependencies(control_input)返回一个控制依赖的上下文管理器,
使用with关键字可以让在这个上下文环境中的操作都在ema_apply_op执行,control_input必须是一个list,使用[]是将ema_apply_op
转换为一个list
"""
# 这里也可以不在计算影子变量后执行
with tf.control_dependencies([ema_apply_op]):
# 这里加tf.identity的作用的是加入一个op,如果不加一个op的话,这里这个控制依赖就无法执行,因为tf.control_dependencies定义的是op的执行顺序
mean, variance = tf.identity(batch_mean), tf.identity(batch_variance) """
这里为什么要在这后面执行,因为这里要记录影子变量,为什么能记录,因为在一个variable_scope下面,到时候调用这个variable_scope的名字,可以直接调用这个变量
然后才返回数据归一化后的结果
"""
with tf.control_dependencies([assign_mean, assign_variance]):
# value表示输入的value,mean表示value的均值,variance表示方差,这两个参数用来计算value的normalization,eps:分母附加值,防止除以方差时出现除0操作,默认为1e-5
# beta,gamma会在训练时进行学习
return tf.nn.batch_normalization(value, mean, variance, beta, gamma, 1e-5) else:
mean = bias('moving_mean', [shape], 0.0, False)
variance = bias('moving_variance', [shape], 1.0, False) return tf.nn.batch_normalization(
value, mean, variance, beta, gamma, epsilon)

深度学习(八) Batch Normalization的更多相关文章

  1. 深度学习中 Batch Normalization

    深度学习中 Batch Normalization为什么效果好?(知乎) https://www.zhihu.com/question/38102762

  2. 深度学习之Batch Normalization

    在机器学习领域中,有一个重要的假设:独立同分布假设,也就是假设训练数据和测试数据是满足相同分布的,否则在训练集上学习到的模型在测试集上的表现会比较差.而在深层神经网络的训练中,当中间神经层的前一层参数 ...

  3. 深度学习中 Batch Normalization为什么效果好

    看mnist数据集上其他人的CNN模型时了解到了Batch Normalization 这种操作.效果还不错,至少对于训练速度提升了很多. batch normalization的做法是把数据转换为0 ...

  4. 深度学习中batch normalization

    目录 1  Batch Normalization笔记 1.1  引包 1.2  构建模型: 1.3  构建训练函数 1.4  结论 Batch Normalization笔记 我们将会用MNIST数 ...

  5. zz详解深度学习中的Normalization,BN/LN/WN

    详解深度学习中的Normalization,BN/LN/WN 讲得是相当之透彻清晰了 深度神经网络模型训练之难众所周知,其中一个重要的现象就是 Internal Covariate Shift. Ba ...

  6. 深度学习中的Normalization模型

    Batch Normalization(简称 BN)自从提出之后,因为效果特别好,很快被作为深度学习的标准工具应用在了各种场合.BN 大法虽然好,但是也存在一些局限和问题,诸如当 BatchSize ...

  7. [优化]深度学习中的 Normalization 模型

    来源:https://www.chainnews.com/articles/504060702149.htm 机器之心专栏 作者:张俊林 Batch Normalization (简称 BN)自从提出 ...

  8. 深度学习之Batch归一化

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ Batch归一化 在神经网络中,我们常常会遇到梯度消失的情况,比如下图中的sigmod激活函数,当离零点很远时,梯度基本为0 ...

  9. 关于深度学习之中Batch Size的一点理解(待更新)

    batch 概念:训练时候一批一批的进行正向推导和反向传播.一批计算一次loss mini batch:不去计算这个batch下所有的iter,仅计算一部分iter的loss平均值代替所有的. 以下来 ...

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

    <深度学习基础> 卷积神经网络,循环神经网络,LSTM与GRU,梯度消失与梯度爆炸,激活函数,防止过拟合的方法,dropout,batch normalization,各类经典的网络结构, ...

随机推荐

  1. Last-Modified Header in Asp.net Core MVC

    public class YourController : Controller { public ActionResult MyPage(string id) { var entity = _db. ...

  2. 代码修改之后MSbuild编译不出最新的dll解决方法

    问题: 使用jenkins发布的时候,开发不断反馈自己修改的文件使用jenkins没有发布到测试环境.经过查证发现使用MSBUILD编译的时出现修改的文件编译出的日期不是最新日期,但是使用VS编译就不 ...

  3. shell中调用jenkins API批量运行历史任务

    shell中调用jenkins API批量运行jenkins带参数的任务: #!/bin/sh #startdate=20150127 startdate=20150201 while [ " ...

  4. vscode怎样新建项目

    首先,vscode本身没有新建项目的选项,所以要先创建一个空的文件夹喔.   然后打开vscode,再在vscode里面打开文件夹,这样才可以创建项目.   选择之前创建的空文件将作为vscode的文 ...

  5. 一起学习《C#高级编程》2--比较对象的相等性

    今后争取每两天能更新一次.平日的诱惑太多,双休只顾玩了,进度有点慢. 接上一讲的,类型的安全性,留下了点小尾巴——比较对象的相等性. C#有四种比较相等的方式:除了“==”运算符外,System.Ob ...

  6. WP8.1StoreApp(WP8.1RT)---MessageBox与MessageDialog

    在WP7和WP8中,MessageBox是跟WinForm中一样常用的对话框,但是有一个显著的缺点,就是WP7/8中默认的MessageBox是阻塞线程的.也许是由于这个原因,WP8.1/Win8中采 ...

  7. UWP开发入门(二)——RelativePanel

    RelativePanel也是Win10 UWP新增的控件,和上篇提到的SplitView一样在UWP的UI布局起到非常重要的作用.说句实在话,这货其实就是为了UWP的Adaptive UI而特意增加 ...

  8. C# 键盘中的按键对应KeyValue

    首先先看一下什麼情況下需要對按鍵進行識別: KeyPress事件響應函數中,有KeyPressEventArgs, 對應於e.KeyChar; KeyDown事件響應中有KeyEventArgs 求取 ...

  9. 浅谈Android选项卡(三)

    上一节介绍了TabActivity的简单用法,但是现在的Api中已经不建议使用了,建议使用Fragment来替代以上的功能,下面介绍下使用Fragment和ViewPager的结合使用. http:/ ...

  10. 给对象和函数添加method方法

    蝴蝶书中有一个method方法,用来给函数定义方法.看了之后,想着能不能给对象也定义方法呢?. 下面的代码可以实现给函数定义方法: //Function method Function.prototy ...