批量归一化(BN, Batch Normalization)
现在的神经网络通常都特别深,在输出层向输入层传播导数的过程中,梯度很容易被激活函数或是权重以指数级的规模缩小或放大,从而产生“梯度消失”或“梯度爆炸”的现象,造成训练速度下降和效果不理想。
如何避免或者减轻这一现象的发生呢?归一化就是方法的一种。归一化将网络中层与层之间传递的数据限制在一定范围内,从而避免了梯度消失和爆炸的发生。下面介绍一种最基本的归一化:批量归一化(BN, Batch Normalization)。另外还有层归一化(LN, Layer Normalization)和权重归一化(WN, Weight Normalization),和BN大同小异。
批量归一化
批量归一化层的是这样定义的,当使用批量梯度下降(或小批量)时,对前一层的输出在批量的维度上进行归一化,即
\begin{align} &\hat{X}_i^t=\frac{X_i^{t-1}-E(X^{t-1})}{\sqrt{D(X^{t-1})+\varepsilon}} \\ \text{where}\;\; &E(X^{t-1}) = \frac{1}{n}\sum\limits_{i=1}^nX_i^{t-1}\notag\\ &D(X^{t-1}) = \frac{1}{n-1}\sum\limits_{i=1}^n\left[X_i^{t-1}-E(X^{t-1})\right]^2\notag \end{align}
其中$n$是输入批量,$X_i^{t-1}$是前一层输出批量中的第$i$个,$\varepsilon$是为避免0除而设置的较小数。以上都是按元素进行的操作。这样做的显式优点在于,大部分的输出都被映射到了-1和1之间,而诸如sigmoid激活函数,在这个区间内的梯度是最大的,从而避免因激活函数值的饱和而产生的梯度消失。并且由于层输出的归一化约束,反向传播的累积不会特别显著,梯度爆炸也得以避免。
但是,如果仅仅进行以上操作,网络的拟合能力就会下降。这是因为,神经网络强大的拟合能力在于激活函数的非线性。经过以上操作,激活函数的输入通常都集中在-1和1之间,而sigmoid函数在这区间内的导数变化率是比较低的,或者说是比较线性的。为了防止这一点,BN在这基础上再加一个“反向”操作,将权重输出再乘上自学习的标准差和均值,映射到激活函数曲率(或者说二阶导数绝对值、导数变化率)相对更大的位置,在获得较大导数的同时,保留激活非线性。公式如下:
$ \begin{aligned} &X_i^t= \gamma^t\hat{X}_i^t+\beta^t\\ \end{aligned} $
与$(1)$式联合得到:
$ \begin{aligned} &X_i^t= \frac{\gamma^t}{\sqrt{D(X^{t-1})+\varepsilon}}X_i^{t-1} + \left(\beta^t-\frac{E(X^{t-1})\gamma^t}{\sqrt{D(X^{t-1})+\varepsilon}}\right) \\ \end{aligned} $
其中$\gamma,\beta$都是模型中用反向传播学习的参数。这样一来,BN层可以自己“决定”将输出映射到合适位置。
另外,在训练结束进行推理时,我们输入模型的通常都是单个样本,毕竟一个样本是不能求样本方差的。所以BN使用滑动平均(moving average)来保存所有输入的均值和方差,以用于对单一输入的归一化。
Keras中BN的使用
Keras中已经实现了BN层可以直接使用,而不用我们自己重新写这个轮子。使用方式如下:
x = keras.layers.BatchNormalization(axis=-1,#对输入的哪个轴执行BN
momentum=0.99,#滑动平均和方差的动量
epsilon=0.001,#防止0除的较小值
center=True,#是否使用beta调整归一化后的输出均值
scale=True,#是否使用gamma调整归一化后的输出方差
trainable=True)(x)
其中要注意axis,归一化操作是针对axis维度指定的向量进行的。比如当BN层的前一层是二维卷积层,输出的第一维是批量,然后是图像宽高,最后一维是通道。假如BN层axis=-1,均值就是整个批量的所有像素对应的通道向量的平均,方差的计算也是以这个维度进行。也可以传入列表,假如axis=[1,2,3],那么进行的规范化就是原理中所介绍的那样,均值的规模就是CxHxW。对于下面的代码:
from keras import layers,Model,Input Input_img = Input(shape = [320,320,3])
x = layers.BatchNormalization(axis=-1,
momentum=0.99,
epsilon=0.001,
center=True,
scale=True)(Input_img)
model = Model(Input_img,x)
model.summary()
summary()输出可训练参数和不可训练参数各6个。可训练参数就是$\gamma,\beta$,不可训练参数是滑动平均所保存的均值和方差。另外,如果将BN层的traninable标记设置为False,那么$\gamma,\beta$就会被固定,不会被训练;而如果设置为True,则只有$\gamma,\beta$会被训练,另外6个不可训练参数依然是不可训练状态,因为它们是通过滑动平均而不是反向传播来更新的。
Pytorch中的BN
在Pytorch中使用BN的代码如下(和上面一样,也是2维BN):
from torch import nn bn = nn.BatchNorm2d(num_features = 6,# 特征数
eps = 0.00001, # 防止0除
momentum = 0.1, # 滑动平均与方差的动量(与Keras中相反),如果设为None,momentum = 1/i,i是输入的次数
affine = True, # 是否使用gamma与beta再次映射,也就是会多出几个训练参数
track_running_stats = True)# 是否累计每次计算的均值与方差
for i in bn.state_dict():
print(i,bn.state_dict()[i])
与Keras中类似,但这里直接默认对特征维度进行规范化,特征维度在pytorch中是倒数第3维。需要注意的是,track_running_stats,也就是累计每次输入计算的均值与方差,只要你传入一个输入,累计的均值与方差就会被修改。因此,如果你在推理时不想修改这两个累计值,就要将track_running_stats设置为False。而在训练时,只需再修改回True即可。
批量归一化(BN, Batch Normalization)的更多相关文章
- 转载-通俗理解BN(Batch Normalization)
转自:参数优化方法 1. 深度学习流程简介 1)一次性设置(One time setup) -激活函数(Activation functions) - 数据预处理(Data Prep ...
- BN(Batch Normalization)
Batch Nornalization Question? 1.是什么? 2.有什么用? 3.怎么用? paper:<Batch Normalization: Accelerating Deep ...
- 【转载】 BN(batch normalization)
原文地址: https://blog.csdn.net/qq_35608277/article/details/79212700 ----------------------------------- ...
- 第十八节,TensorFlow中使用批量归一化(BN)
在深度学习章节里,已经介绍了批量归一化的概念,详情请点击这里:第九节,改善深层神经网络:超参数调试.正则化以优化(下) 神经网络在进行训练时,主要是用来学习数据的分布规律,如果数据的训练部分和测试部分 ...
- 【深度学习】批归一化(Batch Normalization)
BN是由Google于2015年提出,这是一个深度神经网络训练的技巧,它不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中"梯度弥散"的问题,从而使得训练深层网 ...
- 批归一化(Batch Normalization)
之前在几篇博客中说到了权重共享,但都觉得不够全面,这里做个专题,以后有新的理解都在此更新. 1. 减少运算只是锦上添花之前说到权重共享可以减少运算,是的,但这样说好像是可有可无,只是运算量大小的问题, ...
- 机器学习(ML)十三之批量归一化、RESNET、Densenet
批量归一化 批量归一化(batch normalization)层,它能让较深的神经网络的训练变得更加容易.对图像处理的输入数据做了标准化处理:处理后的任意一个特征在数据集中所有样本上的均值为0.标准 ...
- 深度学习面试题21:批量归一化(Batch Normalization,BN)
目录 BN的由来 BN的作用 BN的操作阶段 BN的操作流程 BN可以防止梯度消失吗 为什么归一化后还要放缩和平移 BN在GoogLeNet中的应用 参考资料 BN的由来 BN是由Google于201 ...
- 【转载】 详解BN(Batch Normalization)算法
原文地址: http://blog.csdn.net/hjimce/article/details/50866313 作者:hjimce ------------------------------- ...
- caffe︱深度学习参数调优杂记+caffe训练时的问题+dropout/batch Normalization
一.深度学习中常用的调节参数 本节为笔者上课笔记(CDA深度学习实战课程第一期) 1.学习率 步长的选择:你走的距离长短,越短当然不会错过,但是耗时间.步长的选择比较麻烦.步长越小,越容易得到局部最优 ...
随机推荐
- 在 Docker 中启动 Jupyter
参考:Jupyter Docker Stacks documentation 容器地址在 quay.io/jupyter/scipy-notebook 如果你直接运行命令: docker run -p ...
- Kubernetes-3.2:kubespray安装高可用k8sv1.20.2集群及常见报错解决
kubespray安装高可用k8s集群 环境介绍 系统环境 主机名 / IP地址 角色 内核版本 CentOS 7.6.1810 master1 / 192.168.181.252 master &a ...
- .net 环境使用 RabbitMQ ,由浅入深 【一】
最近因为先开发的项目需要用到消息队列,因此捣鼓了一下市面上开源的消息队列. 原本听闻Rocketmq ,一开始用的是 RocketMQ,各种集群搭建完毕,消息发送什么的测试后,,但是结果因为 Rock ...
- Angular 学习笔记 (Typescript 高级篇)
由于 typescript 越来越复杂. 所以特意开多一个篇幅来记入一些比较难的, 和一些到了一定程度需要知道的基础. 主要参考 https://basarat.gitbook.io/typescri ...
- APP专项测试之兼容性测试
1.APP 兼容性测试认识 随着 APP 应用范围越来越广,用户群体越来越大,终端设备的型号也越来越多,移动终端碎片化加剧,使得 APP 兼容性测试成为测试质量保障必须要考虑的环节. APP 兼容性测 ...
- iOS动画之CABasicAnimation的使用方法(移动,旋转,缩放)
设定动画CABasicAnimation的属性和说明 属性 说明 duration 动画的时间 repeatCount 重复的次数.不停重复设置为 HUGE_VALF repeatDuration ...
- dotnet 虚方法的使用
// 虚方法 // 作用:允许子类,进行重写,可以实现不一样的功能 // 特点:好维护 -- 不该变原方法(虚方法)情况下,可以直接使用虚方法或者重写虚方法 VirtualMethod method ...
- 25. http 常见状态码
状态码的分类: 2xx:表明请求被成功接收并处理 : 3xx:表示要完成请求,需要进一步操作. 通常,这些状态代码用来重定向 :重定向就是 从 a 地址跳转到 b 地址 : 4xx:客户端错误,请求错 ...
- 云原生周刊:CNCF 宣布 Falco 毕业|2024.3.4
开源项目推荐 ldap-operator 用于部署和管理 LDAP 目录的 Kubernetes Operator. Updatecli Updatecli 是一个用于应用文件更新策略的工具.每个应用 ...
- OpenFunction 应用系列之一: 以 Serverless 的方式实现 Kubernetes 日志告警
概述 当我们将容器的日志收集到消息服务器之后,我们该如何处理这些日志?部署一个专用的日志处理工作负载可能会耗费多余的成本,而当日志体量骤增.骤降时亦难以评估日志处理工作负载的待机数量.本文提供了一种基 ...