Batch Normalize的几点说明
前言
前面也讲过部分Batch Normalize的内容,单独拿出来成文,是因为感觉这方法非常赞,加快训练速度十几倍不等,模型越复杂越受益。
一句话总结BN:对每层输入加同分布约束,再加参数线性变换学习其表达能力。
BN解决的问题
Problem :: Internal Covariate Shift
神经网络训练的难题之一,在前层参数变化时,每层的输入分布也随之变化。这就造成了当层的训练困难,老是变来变去,还能不能好好地玩耍啊~通常地解决思路是使用很小的学习率,并且小心地初始化。
Batch Normalize的基本思想是,将每层的输入做std-normalize, y=x−x¯var(x)√ y = x − x ¯ v a r ( x ) y=\frac{x- \bar{x}}{\sqrt{var(x)}},使得变换后,是 N(0 1) N ( 0 1 ) N(0~1)高斯分布。
疑问解答
1)Batch Normalize是怎么做的?
假设输入m-size的batch样本 x x x,对其中的所有特征都做如下处理:
\left\{\begin{matrix}\hat{x} = \frac{x- \overline{x}}{\sqrt{var(x)}} & std·normalize \\ BN(x) = \gamma \hat{x} + \beta & scale·shift \end{matrix}\right. 其中 x¯¯¯=1m∑mi=1xi x ¯ = 1 m ∑ i = 1 m x i \overline{x} = \frac{1}{m}\sum_{i=1}^m x_i; var(x)=1m∑mi=1(xi−x¯¯¯)2 v a r ( x ) = 1 m ∑ i = 1 m ( x i − x ¯ ) 2 var(x) = \frac{1}{m} \sum_{i=1}^m (x_i - \overline{x})^2
2)单纯地std-normalize能行么?
只是将输入约束到同分布下,岂不是所有层的输入都一样了,那还学个毛线啊。在normalize上,Sergey更向前走了一步,一不做二不休,干脆再搞它俩参数 γ γ \gamma和 β β \beta,将输入恢复出来,通过不断学习调整这两个参数,使得重构输入的能力也能被搞定。
3)梯度消失的现象在带有BN的网络结构里还存在么?
误差后传,传递的是误差项 ∗ ∗ *导数项∗" role="presentation">∗∗*其他项;传递的动作是链式法则的体现。随着传递路径越长,越容易出现为0的现象。
原因1: sigmoid激活函数,自身带有的饱和域(导数近似为0)。
原因2: 串联网络本身的参数累乘所带来的梯度消失问题没有解决掉。
ReLU激活函数,只是解决了由于激活函数的饱和域(导数近似0)所带来的的梯度消失问题。
BN方法,会将训练早期的数据约束到[-1,+1]范围内,避开了饱和区域,也能解决饱和域带来的梯度消失问题。
4)BN在网络中,放到哪里适合?
在非卷积网络中,通常是放到激活函数前面,处理之后做激活函数输入: σ(BN(wx)) σ ( B N ( w x ) ) \sigma(BN(wx))。
notice:由于 BN(wx+b)=BN(wx) B N ( w x + b ) = B N ( w x ) BN(wx+b)=BN(wx),会将bias去掉,后面的 β β \beta起到类似bias的作用。
在卷积网络中,则要服从卷积的特性。利用固定filter-blank抽取某一特征feature-map,相当于每个f-map是一个抽取之后的特征(是个整体),那么对只需要对feature-map加统一的 γ γ \gamma和 β β \beta即可,同样放到激活函数前。详细如下图。
5)如何解释 BN使得网络更稳定的特性
假设权重参数 w w w变为aw" role="presentation">awawaw,对新旧参数下的 x x x求导如下:
\frac{\partial BN(awx)}{\partial x} = \frac{\gamma aw}{\sqrt{var(awx)}}=\frac{a}{|a|} \frac{rw}{\sqrt{var(wx)}}=sign(a) \frac{\partial BN(wx)}{\partial x} 发现,虽然参数虽然放缩 a a a倍,但是参数的变化率并没有变化(除了方向),所以参数的放缩对参数变化率无影响。这是很好的特性,表明不会因为参数值的变化,就导致参数变化率飞速增长/缩小,从而使得依赖参数的前向和后向计算值都失控。
6)如何理解 BN对大学习率更友好
对于大学习率learning rate, BN是更为友好的。
{BN(wx)=γ(wx)−wx¯var(wx)+βBN(awx)=γawx−awx¯var(awx)+β" role="presentation">⎧⎩⎨⎪⎪BN(wx)=γ(wx)−wx¯¯¯¯¯¯¯var(wx)√+βBN(awx)=γawx−awx¯¯¯¯¯¯¯¯¯¯var(awx)√+β{BN(wx)=γ(wx)−wx¯var(wx)+βBN(awx)=γawx−awx¯var(awx)+β\left\{\begin{matrix} BN(wx)=\gamma \frac{(wx) - \overline{wx}}{\sqrt{var(wx)}} + \beta \\ BN(awx)=\gamma \frac{awx - \overline{awx}}{\sqrt{var(awx)}} + \beta \end{matrix}\right.==> ⎧⎩⎨⎪⎪∂BN(wx)∂w=rxvar(wx)√∂BN(awx)∂(aw)=rxvar(awx)√ { ∂ B N ( w x ) ∂ w = r x v a r ( w x ) ∂ B N ( a w x ) ∂ ( a w ) = r x v a r ( a w x ) \left\{ \begin{matrix} \frac{\partial BN(wx)}{\partial w} = \frac{rx} {\sqrt{var(wx)}} \\ \frac{\partial BN(awx)}{\partial (aw)}=\frac{rx}{\sqrt{var(awx)}} \end{matrix}\right.
得到:
\frac{\partial BN(awx)}{\partial (aw)}= \frac{1}{|a|} \frac{\partial BN(wx)}{\partial w} 对BN而言,权重变化 wnew=wold−α∂BN∂w=a∗wold w n e w = w o l d − α ∂ B N ∂ w = a ∗ w o l d w_{new}=w_{old} - \alpha \frac{\partial BN}{\partial w}=a*w_{old}时,其中权重的导数,也会按照对应比例 1|a| 1 | a | \frac{1}{|a|}变化。
若是学习率 α α \alpha较大,训练初始则容易使得 |a|>1 | a | > 1 |a|>1,新参数下的梯度反而会压缩到旧参数时的梯度 1|a| 1 | a | \frac{1}{|a|}倍,对梯度更新是更安全的,不会无端地放大跑偏。
当参数前后两次变化幅度较小,比如a=0.9时,则新梯度是之前梯度的10/9倍,再乘以 α α \alpha,更容易跳出梯度过小而陷入的局部解,或者马鞍部位。
更新前后两个梯度和学习率之间互相牵制,是其他方法所不具备的特点。
6)BN怎么计算导数?
假设其中 ZLj=BN(wLj∗hL−1)=rLj∗∑iwLj,ihL−1i−wLjhL−1¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯var(wLjhL−1)√+βLj Z j L = B N ( w j L ∗ h L − 1 ) = r j L ∗ ∑ i w j , i L h i L − 1 − w j L h L − 1 ¯ v a r ( w j L h L − 1 ) + β j L Z_j ^{L}=BN(w_j^L * h^{L-1})=r_j^{L} * \frac{\sum_{i} w_{j,i} ^{L} h_i^{L-1} - \overline{w_j^{L} h^{L-1}}}{\sqrt{var(w_j^{L} h^{L-1})}} + \beta_j^{L}
对 wLj,i w j , i L w_{j,i}^{L}求导得: ∂Zj∂wLj,i=rLjhL−1ivar(wLjhL−1)√ ∂ Z j ∂ w j , i L = r j L h i L − 1 v a r ( w j L h L − 1 ) \frac{\partial Z_j}{\partial w_{j,i}^{L}}=\frac{r_j^{L} h_i^{L-1}} {\sqrt{var(w_j^{L} h^{L-1})}};若无BN,则 ∂Zj∂wLj,i=hL−1i ∂ Z j ∂ w j , i L = h i L − 1 \frac{\partial Z_j}{\partial w_{j,i}^{L}}=h_i^{L-1}
对 βLj β j L \beta_j^L求导得: ∂BN∂βLj=1 ∂ B N ∂ β j L = 1 \frac{\partial BN}{\partial \beta_j^L}=1。
对 γLj γ j L \gamma_j^L求导得: ∂BN∂γLj=wLjhL−1var(wLjhL−1)√ ∂ B N ∂ γ j L = w j L h L − 1 v a r ( w j L h L − 1 ) \frac{\partial BN}{\partial \gamma_{j}^{L}}=\frac{w_j^{L} h^{L-1}}{\sqrt{var(w_j^{L}h^{L-1})}}
在网络中误差后传如下: h=h(z) h = h ( z ) h=h(z)
W(L) W ( L ) W^{(L)}记做第 L L L层的权重,连接L−1" role="presentation">L−1L−1L-1和 L L L之间的权重,γ(L)和βL" role="presentation">γ(L)和βLγ(L)和βL\gamma^{(L)}和\beta^{L}作为本层学习的标准差向量和偏倚向量,其各自的维度等于本层节点数。
a)计算 L L L层的输出误差:
a.1)δ′(L)={∑δ(L+1)W(L+1),后层传递过来的δh−y,本层直接差h−y(最后一层时)" role="presentation">δ′(L)={∑δ(L+1)W(L+1)h−y,后层传递过来的δ,本层直接差h−y(最后一层时)δ′(L)={∑δ(L+1)W(L+1),后层传递过来的δh−y,本层直接差h−y(最后一层时)\delta^{'(L)} = \left\{\begin{matrix} \sum \delta^{(L+1)} W^{(L+1)} &,后层传递过来的\delta \\ h-y &, 本层直接差h-y(最后一层时)\end{matrix}\right.
a.2) δ(L)=δ′(L)∗h′(L)∗r(L)var(W(L)h(L−1))√ δ ( L ) = δ ′ ( L ) ∗ h ′ ( L ) ∗ r ( L ) v a r ( W ( L ) h ( L − 1 ) ) \delta^{(L)} = \delta^{'(L)} * h^{'(L)}*\frac{r^{(L)}}{\sqrt{var(W^{(L)} h^{(L-1)} )}} ,乘本层激活导数,再乘BN对w的导数。
b)更新 w w w:ΔW(L)=h(L−1)∗δ(L)" role="presentation">ΔW(L)=h(L−1)∗δ(L)ΔW(L)=h(L−1)∗δ(L)\Delta W^{(L)} =h^{(L-1)} * \delta^{(L)} 前层输出*本层的 δ δ \delta。
c)更新 β β \beta: Δβ(L)=δ′(L)∗h′(L) Δ β ( L ) = δ ′ ( L ) ∗ h ′ ( L ) \Delta \beta^{(L)} = \delta'^{(L)}*h'^{(L)}
d)更新 γ γ \gamma: Δγ(L)=δ′(L)∗h′(L)∗w(L)h(L−1)var(w(L)h(L−1))√ Δ γ ( L ) = δ ′ ( L ) ∗ h ′ ( L ) ∗ w ( L ) h ( L − 1 ) v a r ( w ( L ) h ( L − 1 ) ) \Delta \gamma^{(L)} =\delta'^{(L)} * h'^{(L)}*\frac{ w^{(L)} h^{(L-1)}}{\sqrt{ var( w^{(L)} h^{(L-1)})}}
实际计算时,会在分母的 var v a r var上叠加个随机很小的正数,防止分母为0。最开始初始化时,每对 γ和β γ 和 β \gamma和\beta分别都初始化到1和0附近。注意,批量计算均值和方差。
补充梯度求导,与paper里面的对比。不是特别明白为什么论文里有对估计参数 u和σ u 和 σ u和\sigma的求导。
训练过程:用batch-GD训练;记录每个 batchB b a t c h B batch_B的 uB和σB u B 和 σ B u_B和\sigma_B,用以最后估计全局的 u和σ u 和 σ u和\sigma。
9)BN在预测时怎么玩?
这个问题的由来:因为预测是单样本依次预测。不存在batch训练的情况,所以预测是与训练不同的,如何利用训练过程及结果参数是个问题。
预测时,计算总体的均值和方差是不实际的,也是无法实现的,因为无法采样到所有样本。用总采样来估计总体的均值和方差呢?也是需要大量计算的,在训练过程中的batch下的均值 uB u B u_B和方差 σB σ B \sigma_B,可以加以利用来估计总体,如下:
\left\{\begin{matrix}E[x] = E[u_B] = \frac{1}{K}\sum_{B=1}^K u_B \\ Var[x] = \frac{m}{m-1} E[\sigma_B] \end{matrix}\right. 如上,估计总体的均值和方差,预测时BN不再生效,但是 仍然利用 x^=γx−E[x]Var[x]√+β x ^ = γ x − E [ x ] V a r [ x ] + β \hat{x}= \gamma \frac{x-E[x]}{\sqrt{Var[x]}} + \beta 来重构,否则岂不是白学习了重构参数,哈哈。(论文里的那个式子是这个式子稍微变换之后的样子)
作者说”Using moving averages instead, we can track the accuracy of a model as it trains”?说的不甚明了,难道是追踪均值和方差的情况。
moving_mean = gamma * moving_mean + (1-gamma)* mean
moving_var = gamma * moving_var + (1-gamma)* var
10)几种提高BN效力的方法
Sergey友情提示了几个方法,提高BN的效力。
增大学习率,学得快还安全;去掉dropout,节省时间;去掉L2正则,但是个人觉得不要去最好,没有理由证明BN能够代替L2;样本集多次shuf,避免同batch总是一样的样本;减少图片变形处理,说的理由不充分;去掉local Response Normalize。
11)怎么理解BN是whiten的简化之后的版本?
已有研究说明[2],针对Internal Covariate Shift问题,将输入做whiten处理,可以收敛地更快。疑问,真有必要whiten么?ICS只是权重变换,影响输出的分布而已,将分布搞得一致不就好了,还用着考虑各个输出变量间的相关关系么,后续层反正也不care变量间的相关性。
whiten的处理非常严格:要求去掉各个变量间的相关性;且每个变量的variance=1。
whiten定义:将一组随机变量 (X1,X2,....,Xn) ( X 1 , X 2 , . . . . , X n ) (X_1, X_2, ...., X_n) 通过 Y=WX Y = W X Y=WX变换为 → → \rightarrow (Y1,Y2,...,Ym) ( Y 1 , Y 2 , . . . , Y m ) (Y_1, Y_2, ..., Y_m),称后者为白噪声,其协方差矩阵为单位对角矩阵,各变量间无相关性( ∃非零系数向量 ∃ 非 零 系 数 向 量 \exists 非零系数向量,使得 aY=0 a Y = 0 aY=0成立), Var[Ym]=1 V a r [ Y m ] = 1 Var[Y_m]=1。
whiten的求解:假设X有non-singular 协方差矩阵M,and mean=0。
方法一: W=M−1/2 W = M − 1 / 2 W=M^{-1/2} ZCA白化。
方法二:cholesky分解 of M−1 M − 1 M^{-1}。
方法三:特征分解 of M M <script type="math/tex" id="MathJax-Element-73">M</script> (PCA类方法)。
其他相关变换:
decorrelation transform:去相关,但是对variance不处理。
standard transform: mean=0,variance=1;相关性不处理。
corloring transform:白化的逆向处理,将白噪声处理成具有指定协方差矩阵的变换。
具体例子见参考3.
而BN使用标准化变换,不再考虑相关性,又把全局均值和方差用batch均值和方差来代替,省了大量的计算需要,并且效果还很不错。
BN本质,使得同分布;约束范围(量纲归一)。
code example
## model ##
training=True
with tf.variable_scope('layer-1', reuse = tf.AUTO_REUSE):y1 = tf.layers.dense(inputs = x, units = 128, use_bias=False, \activation = tf.nn.relu, \kernel_regularizer = regularizer, \bias_regularizer = None)y1 = tf.layers.batch_normalization(y1, training= training)
with tf.variable_scope('layer-2', reuse = tf.AUTO_REUSE):y2 = tf.layers.dense(inputs = y1, units = 64, use_bias=False, \activation = tf.nn.relu, \kernel_regularizer = regularizer, \bias_regularizer = None)y2 = tf.layers.batch_normalization(y2, training= training)
with tf.variable_scope('layer-3', reuse = tf.AUTO_REUSE):y3 = tf.layers.dense(inputs = y2, units = 2, use_bias=True, \activation = None, \kernel_regularizer = regularizer, \bias_regularizer = regularizer)logits = y3
prob_all = tf.nn.softmax(logits, 1)## when training ##
tf.losses.softmax_cross_entropy(onehot_labels=y, logits=logits)
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
## tf.control_dependencies(a): b # a执行后,b才会执行 ##
with tf.control_dependencies(update_ops):losses = tf.get_collection('losses')total_loss = tf.add_n(losses, name='total_loss')grads = optimizer.compute_gradients(total_losses)
optimizer.apply_gradients(grads, global_step)## save ## moving_var 不会被存到tf.trainable_variables里面 ##
saver = tf.train.Saver(tf.global_variables())## when predict ##
training=False
Reference
- 《Batch Nomalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》
- 《A Convergence analysis of log-linear training》
- https://www.projectrhea.org/rhea/index.php/ECE662_Whitening_and_Coloring_Transforms_S14_MH
Batch Normalize的几点说明相关推荐
- batchnomal_pytorch的batch normalize使用详解
torch.nn.BatchNorm1d() 1.BatchNorm1d(num_features, eps = 1e-05, momentum=0.1, affine=True) 对于2d或3d输入 ...
- 五个角度解释深度学习中 Batch Normalization为什么效果好?
https://www.toutiao.com/a6699953853724361220/ 深度学习模型中使用Batch Normalization通常会让模型得到更好表现,其中原因到底有哪些呢?本篇 ...
- 【论文泛读】 Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
[论文泛读] Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift ...
- 深度学习(五十六)tensorflow项目构建流程
tensorflow项目构建流程 博客:http://blog.csdn.net/hjimce 微博:黄锦池-hjimce qq:1393852684 一.构建路线 个人感觉对于任何一个深度学习库 ...
- 深度学习(十四)基于CNN的性别、年龄识别
CNN应用之性别.年龄识别 原文地址:http://blog.csdn.net/hjimce/article/details/49255013 作者:hjimce 一.相关理论 本篇博文主要讲解201 ...
- 深度学习中,Batch_Normalization加速收敛并提高正确率的内部机制
文章转自https://blog.csdn.net/whitesilence/article/details/75667002, 初非常感谢作者的原创,转载一下方便自己以后的学习 在看 ladder ...
- CVPR2016:ResNet 从根本上解决深度网络退化问题
深度残差网络(Deep residual network, ResNet)的提出是CNN图像史上的一件里程碑事件,在2015年提出的时候便取得了五项第一,而何恺明大神也凭借这一paper斩获CVPR ...
- 莫烦Tensorflow教程(15~22)
十五.卷积神经网络 图像和语言方面结果突出 神经网络是由多层级联组成的,每层中包含很多神经元 卷积:神经网络不再是对每个像素做处理,而是对一小块区域的处理,这种做法加强了图像信息的连续性,使得神经网络 ...
- 【theano-windows】学习笔记十一——theano中与神经网络相关函数
前言 经过softmax和MLP的学习, 我们发现thenao.tensor中除了之前的博客[theano-windows]学习笔记五--theano中张量部分函数提到的张量的定义和基本运算外, 还有 ...
最新文章
- SQL SERVER2000中订阅与发布的具体操作
- QHBoxLayout
- 3481. 阶乘的和
- Linux内核奔溃分析
- 爱特php文件管理器2.8_查找「超级蜘蛛池开发者中心 抠:44564876易」安卓应用 - 豌豆荚...
- HTML的文本格式化
- 育碧2k微软服务器,育碧服务器出现大规模的BUG:影响到多个平台
- oracle sql 拆分字符串,oracle 拆分字符串
- 分布式定时任务调度框架
- cd linux自带系统安装,大神示范win7系统将CDLinux装入硬盘的法子
- 实战:入侵win10
- IT是什么意思?什么是IT行业?
- 电脑wifi密码查看
- Xcode 建立 UIKit 项目(Hello World)
- 腾讯2018秋招正式笔试题目——拼凑硬币
- 公众号回调,突破每月只能修改三次的限制
- 视频融合应用没听说过?
- 游戏推广中买量和导量是什么意思?
- css实现盾牌的动画效果
- 十、Java接口——特殊的抽象类
热门文章
- 【有趣的Python小程序】Pygame制作键盘彩色闪烁打字游戏KeyBoardFlash
- 用汇编语言写51单片机程序开头为什么一般都这样:ORG 0000H LJMP MAIN ORG 0030H
- 如何更改计算机上面的图表形式,excel表格数据转换图形-怎么把EXCEL中的一组数字转换成图表形式...
- 爱伦·坡:写作的哲学
- python复习。知识点小记
- matlab调用dyna,matlab调用ansysdyna及prepost
- 一些可以参考的文档集合4
- 内部UML培训文件,欢迎大家批评指正
- python动态页面元素爬取_Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过浏览器审查元素解析真实网页地址...
- 【必会系列】Switch详解