1、引入BN的原因

1、加快模型的收敛速度

2、在一定程度上缓解了深度网络中的“梯度弥散”问题,从而使得训练深层网络模型更加容易和稳定。

3、对每一批数据进行归一化。这个数据是可以输入也可以是网络中间的某一层输出

4、网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。BN的提出,就是要解决在训练过程中,中间层数据分布发生改变的情况。

2、BN在训练和预测时的具体计算过程

2.1、 BN在训练过程

BN在训练过程中主要分为4步:

  1. 求每一个训练批次数据的均值
  2. 求每一个训练批次数据的方差
  3. 使用求得的均值和方差对该批次的训练数据做归一化,获得0-1分布。其中ε是为了避免除数为0时所使用的微小正数。
  4. 尺度变换和偏移:将xi乘以γ调整数值大小,再加上β增加偏移后得到yi,这里的γ是尺度因子,β是平移因子。这一步是BN的精髓,由于归一化后的xi基本会被限制在正态分布下,使得网络的表达能力下降。为解决该问题,我们引入两个新的参数:γ,β。 γ和β是在训练时网络自己学习得到的。

2.2、BN在预测时生效

在训练时,我们会对同一批的数据的均值和方差进行求解,进而进行归一化操作。但是对于预测时我们的均值和方差怎么求呢?比如我们预测单个样本时,那还怎么求均值和方法呀!其实是这种样子的,对于预测阶段时所使用的均值和方差,其实也是来源于训练集。比如我们在模型训练时我们就记录下每个batch下的均值和方差,待训练完毕后,我们求整个训练样本的均值和方差期望值,作为我们进行预测时进行BN的的均值和方差。

3、BN的位置及效果

3.1、BN的位置

关于BN的使用位置,在CNN中一般应作用与非线性激活函数之前,s型函数s(x)的自变量x是经过BN处理后的结果。其实因为偏置参数b经过BN层后其实是没有用的,最后也会被均值归一化,当然BN层后面还有个β参数作为偏置项,所以b这个参数就可以不用了。因此最后把BN层+激活函数层就变成了:

z=g(BN(Wu))

3.2、BN作用

a中左图是没有经过任何处理的输入数据,曲线是sigmoid函数,如果数据在梯度很小的区域,那么学习率就会很慢甚至陷入长时间的停滞。减均值除方差后,数据就被移到中心区域如右图所示,对于大多数激活函数而言,这个区域的梯度都是最大的或者是有梯度的(比如ReLU),这可以看做是一种对抗梯度消失的有效手段。对于一层如此,如果对于每一层数据都那么做的话,数据的分布总是在随着变化敏感的区域,相当于不用考虑数据分布变化了,这样训练起来更有效率。

那么为什么要有第4步,不是仅使用减均值除方差操作就能获得目的效果吗?我们思考一个问题,减均值除方差得到的分布是正态分布,我们能否认为正态分布就是最好或最能体现我们训练样本的特征分布呢?不能,比如数据本身就很不对称,或者激活函数未必是对方差为1的数据最好的效果,比如Sigmoid激活函数,在-1~1之间的梯度变化不大,那么非线性变换的作用就不能很好的体现,换言之就是,减均值除方差操作后可能会削弱网络的性能!针对该情况,在前面三步之后加入第4步完成真正的batch normalization。

BN的本质就是利用优化变一下方差大小和均值位置,使得新的分布更切合数据的真实分布,保证模型的非线性表达能力。BN的极端的情况就是这两个参数等于mini-batch的均值和方差,那么经过batch normalization之后的数据和输入完全一样,当然一般的情况是不同的。

4、BN的tf实现

#coding=utf-8
# util.py 用于实现一些功能函数import tensorflow as tf# 实现Batch Normalization
def bn_layer(x,is_training,name='BatchNorm',moving_decay=0.9,eps=1e-5):# 获取输入维度并判断是否匹配卷积层(4)或者全连接层(2)shape = x.shapeassert len(shape) in [2,4]param_shape = shape[-1]with tf.variable_scope(name):# 声明BN中唯一需要学习的两个参数,y=gamma*x+betagamma = tf.get_variable('gamma',param_shape,initializer=tf.constant_initializer(1))beta  = tf.get_variable('beat', param_shape,initializer=tf.constant_initializer(0))# 计算当前整个batch的均值与方差axes = list(range(len(shape)-1))batch_mean, batch_var = tf.nn.moments(x,axes,name='moments')# 采用滑动平均更新均值与方差ema = tf.train.ExponentialMovingAverage(moving_decay)def mean_var_with_update():ema_apply_op = ema.apply([batch_mean,batch_var])with tf.control_dependencies([ema_apply_op]):return tf.identity(batch_mean), tf.identity(batch_var)# 训练时,更新均值与方差,测试时使用之前最后一次保存的均值与方差mean, var = tf.cond(tf.equal(is_training,True),mean_var_with_update,lambda:(ema.average(batch_mean),ema.average(batch_var)))# 最后执行batch normalizationreturn tf.nn.batch_normalization(x,mean,var,beta,gamma,eps)def batch_norm(x,epsilon=1e-5, momentum=0.9,train=True, name="batch_norm"):with tf.variable_scope(name):epsilon = epsilonmomentum = momentumname = namereturn tf.contrib.layers.batch_norm(x, decay=momentum, updates_collections=None, epsilon=epsilon,scale=True, is_training=train,scope=name)# 注意bn_layer中滑动平均的操作导致该层只支持半精度、float32和float64类型变量
x = tf.constant([[1,2,3],[2,4,8],[3,9,27]],dtype=tf.float32)
y = bn_layer(x,True)
z=batch_norm(x)# 注意bn_layer中的一些操作必须被提前初始化
init = tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init)print('x = ',x.eval())print('y = ',y.eval())print('z = ',z.eval())

参考文档

【1】 [深度学习概念]·数据批归一化解析 - 云+社区 - 腾讯云    (详细介绍了batch normalization在训练、预测过程中的具体计算过程,以及batch normalization处理的原因)

【2】深度学习中的归一化(normalization)和正则化(regularization)_sinoai-CSDN博客_深度学习归一化   (在图像领域的几种normalization方法)

【3】 BN 详解和使用Tensorflow实现(参数理解) - WSX_1994 - 博客园   (batch normalization tf 的具体实现)

【4】tensorflow中Batch Normalization的实现_shuzfan的专栏-CSDN博客_batch normalization实现

(BN具体实现)

batch normalization详解相关推荐

  1. Batch Normalization详解(原理+实验分析)

    Batch Normalization详解(原理+实验分析) 1. 计算过程 2. 前向传播过程 3. 反向传播过程 4. 实验分析 4.1 实验一:验证有没有BatchNorm下准确率的区别 4.2 ...

  2. 批归一化(Batch Normalization)详解

    批归一化(Batch Normalization)详解 文章目录 批归一化(Batch Normalization)详解 前言 一.数据归一化 二.BN解决的问题:Internal Covariate ...

  3. 【深度学习】Batch Normalization详解

    Batch Normalization 学习笔记 原文地址:http://blog.csdn.net/hjimce/article/details/50866313 作者:hjimce 一.背景意义 ...

  4. Conditional Batch Normalization 详解(SFT思路来源)

    Conditional Batch Normalization 的概念来源于这篇文章:Modulating early visual processing by language .后来又先后被用在  ...

  5. Batch Normalization详解以及pytorch实验

    Batch Normalization是google团队在2015年论文<Batch Normalization: Accelerating Deep Network Training by R ...

  6. python batch normalization_Batch Normalization 详解

    一.背景意义 本篇博文主要讲解2015年深度学习领域,非常值得学习的一篇文献:<Batch Normalization: Accelerating Deep Network Training b ...

  7. 代码分析 | 单细胞转录组Normalization详解

    标准化加高变基因选择 NGS系列文章包括NGS基础.转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这).ChIP-seq分析 (ChIP-seq基本分析流程).单细胞测序分析 ( ...

  8. Batch Normalization应该放在ReLU非线性激活层的前面还是后面?

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 编辑:CVDaily  转载自:计算机视觉Daily https: ...

  9. 论文阅读笔记:看完也许能进一步了解Batch Normalization

    提示:阅读论文时进行相关思想.结构.优缺点,内容进行提炼和记录,论文和相关引用会标明出处. 文章目录 前言 介绍 BN之前的一些减少Covariate Shift的方法 BN算法描述 Batch No ...

最新文章

  1. 创建一个水平盒子java_你了解如何比较两个对象吗
  2. drawable如何只让两个叫圆角_cad怎么使用圆角?cad的圆角怎么使用?
  3. 面试官问:跨域请求如何携带cookie?
  4. Spring Boot-springbootHelloword(一)
  5. (13) css浮动补充
  6. linux命令封装sh,shell脚本学习之调用脚本将文件打包zip的方法示例
  7. 云络科技服务器管理基础架构
  8. servlet请求转发
  9. python输出被五整除的数_python中给定一系列正整数能被5整除的数字中所有偶数的和?...
  10. 几种简单的负载均衡算法及其 Java 代码实现
  11. java获取京东token_京东开放服务平台(JOS)关于token问题汇总(一)
  12. 后代选择器和子代选择器
  13. 为文字添加下划线和中划线
  14. 如何使用UUP来下载Windows 10 的安装镜像(Windows篇)
  15. python爬取分析超级大乐透历史开奖数据
  16. Prometheus节点失联后CPU使用率不准确
  17. 09-多窗口切换-window_handles
  18. .Net Core通过NPOI在CentOS 7(Docker)环境中导出Excel报错The type initializer for ‘Gdip‘ 的问题
  19. 三层内网渗透笔记-靶场(teamssix.com)
  20. scala中打印数组和集合_如何在Scala中打印数组?

热门文章

  1. VBa运行c语言程序,VBA从零学习之12——如何调试程序
  2. vue消息推送【个推】
  3. Linux命令详解:iptables 命令
  4. Escaping closure captures non-escaping parameter ‘findPeripheral‘
  5. 几个的常见基础协议类型数据格式以及协议内容简介
  6. 【最全Mybatis学习笔记(导入mybatis相关jar包)】
  7. 取整函数(向上取整 向下取整 四舍五入)
  8. android 接入阿里百川,阿里百川android 引入SDK
  9. A.M. Best确认中国再保险(集团)股份有限公司及其子公司信用评级
  10. 可调式直流电源需要注意哪些以防止损坏?