Batch Normalize的几点说明

来源:互联网 发布:天心软件 编辑:程序博客网 时间:2024/06/07 00:50

前言

  前面也讲过部分Batch Normalize的内容,单独拿出来成文,是因为感觉这方法非常赞,加快训练速度十几倍不等,模型越复杂越受益。
  一句话总结BN:对每层输入加同分布约束,再加参数线性变换学习其表达能力。

BN解决的问题

  Problem :: Internal Covariate Shift
  神经网络训练的难题之一,在前层参数变化时,每层的输入分布也随之变化。这就造成了当层的训练困难,老是变来变去,还能不能好好地玩耍啊~通常地解决思路是使用很小的学习率,并且小心地初始化。
  Batch Normalize的基本思想是,将每层的输入做std-normalize,y=xx¯var(x),使得变换后,是N(0 1)高斯分布。

疑问解答

1)Batch Normalize是怎么做的?

  假设输入m-size的batch样本x,对其中的所有特征都做如下处理:

x^=xx¯var(x)BN(x)=γx^+βstdnormalizescaleshift
  其中x¯=1mmi=1xivar(x)=1mmi=1(xix¯)2

2)单纯地std-normalize能行么?

  只是将输入约束到同分布下,岂不是所有层的输入都一样了,那还学个毛线啊。在normalize上,Sergey更向前走了一步,一不做二不休,干脆再搞它俩参数γβ,将输入恢复出来,通过不断学习调整这两个参数,使得重构输入的能力也能被搞定。

3)梯度消失的现象在带有BN的网络结构里还存在么?

  误差后传,传递的是误差项导数项其他项;传递的动作是链式法则的体现。随着传递路径越长,越容易出现为0的现象。
  原因1: sigmoid激活函数,自身带有的饱和域(导数近似为0)。
  原因2: 串联网络本身的参数累乘所带来的梯度消失问题没有解决掉。
  ReLU激活函数,只是解决了由于激活函数的饱和域(导数近似0)所带来的的梯度消失问题。
  BN方法,会将训练早期的数据约束到[-1,+1]范围内,避开了饱和区域,也能解决饱和域带来的梯度消失问题。

4)BN在网络中,放到哪里适合?

  在非卷积网络中,通常是放到激活函数前面,处理之后做激活函数输入:σ(BN(wx))
  notice:由于BN(wx+b)=BN(wx),会将bias去掉,后面的β起到类似bias的作用。
  在卷积网络中,则要服从卷积的特性。利用固定filter-blank抽取某一特征feature-map,相当于每个f-map是一个抽取之后的特征(是个整体),那么对只需要对feature-map加统一的γβ即可,同样放到激活函数前。详细如下图。

5)如何解释 BN使得网络更稳定的特性

  假设权重参数w变为aw,对新旧参数下的x求导如下:

BN(awx)x=γawvar(awx)=a|a|rwvar(wx)=sign(a)BN(wx)x
  发现,虽然参数虽然放缩a倍,但是参数的变化率并没有变化(除了方向),所以参数的放缩对参数变化率无影响。这是很好的特性,表明不会因为参数值的变化,就导致参数变化率飞速增长/缩小,从而使得依赖参数的前向和后向计算值都失控。

6)如何理解 BN对大学习率更友好

  对于大学习率learning rate, BN是更为友好的。
  BN(wx)=γ(wx)wx¯¯¯var(wx)+βBN(awx)=γawxawx¯¯¯¯var(awx)+β==>BN(wx)w=rxvar(wx)BN(awx)(aw)=rxvar(awx)
  得到:

BN(awx)(aw)=1|a|BN(wx)w
  对BN而言,权重变化wnew=woldαBNw=awold时,其中权重的导数,也会按照对应比例1|a|变化。
  若是学习率α较大,训练初始则容易使得|a|>1,新参数下的梯度反而会压缩到旧参数时的梯度1|a|倍,对梯度更新是更安全的,不会无端地放大跑偏。
  当参数前后两次变化幅度较小,比如a=0.9时,则新梯度是之前梯度的10/9倍,再乘以α,更容易跳出梯度过小而陷入的局部解,或者马鞍部位。
  更新前后两个梯度和学习率之间互相牵制,是其他方法所不具备的特点。

6)BN怎么计算导数?

    假设其中ZLj=BN(wLjhL1)=rLjiwLj,ihL1iwLjhL1¯¯¯¯¯¯¯¯var(wLjhL1)+βLj
    对wLj,i求导得:ZjwLj,i=rLjhL1ivar(wLjhL1);若无BN,则ZjwLj,i=hL1i
    对βLj求导得:BNβLj=1
    对γLj求导得:BNγLj=wLjhL1var(wLjhL1)
  在网络中误差后传如下:h=h(z)
  W(L)记做第L层的权重,连接L1L之间的权重,γ(L)βL作为本层学习的标准差向量和偏倚向量,其各自的维度等于本层节点数。
  a)计算L层的输出误差:
    a.1)δ(L)={δ(L+1)W(L+1)hy,δ,hy()
    a.2)δ(L)=δ(L)h(L)r(L)var(W(L)h(L1)) ,乘本层激活导数,再乘BN对w的导数。
  b)更新wΔW(L)=h(L1)δ(L) 前层输出*本层的δ
  c)更新βΔβ(L)=δ(L)h(L)
  d)更新γΔγ(L)=δ(L)h(L)w(L)h(L1)var(w(L)h(L1))
  实际计算时,会在分母的var上叠加个随机很小的正数,防止分母为0。最开始初始化时,每对γβ分别都初始化到1和0附近。注意,批量计算均值和方差。
  补充梯度求导,与paper里面的对比。不是特别明白为什么论文里有对估计参数uσ的求导。
  训练过程:用batch-GD训练;记录每个batchBuBσB,用以最后估计全局的uσ

9)BN在预测时怎么玩?

  这个问题的由来:因为预测是单样本依次预测。不存在batch训练的情况,所以预测是与训练不同的,如何利用训练过程及结果参数是个问题。
  预测时,计算总体的均值和方差是不实际的,也是无法实现的,因为无法采样到所有样本。用总采样来估计总体的均值和方差呢?也是需要大量计算的,在训练过程中的batch下的均值uB和方差σB,可以加以利用来估计总体,如下:  

E[x]=E[uB]=1KB=1KuBVar[x]=mm1E[σB]
  如上,估计总体的均值和方差,预测时BN不再生效,但是仍然利用x^=γxE[x]Var[x]+β 来重构,否则岂不是白学习了重构参数,哈哈。(论文里的那个式子是这个式子稍微变换之后的样子)
  作者说”Using moving averages instead, we can track the accuracy of a model as it trains”?说的不甚明了,难道是追踪均值和方差的情况。

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) 通过Y=WX变换为 (Y1,Y2,...,Ym),称后者为白噪声,其协方差矩阵为单位对角矩阵,各变量间无相关性(,使得aY=0成立),Var[Ym]=1
  whiten的求解:假设X有non-singular 协方差矩阵M,and mean=0。
  方法一:W=M1/2 ZCA白化。
  方法二:cholesky分解 of M1
  方法三:特征分解 of M (PCA类方法)。
  其他相关变换:
  decorrelation transform:去相关,但是对variance不处理。
  standard transform: mean=0,variance=1;相关性不处理。
  corloring transform:白化的逆向处理,将白噪声处理成具有指定协方差矩阵的变换。
  具体例子见参考3.
  而BN使用标准化变换,不再考虑相关性,又把全局均值和方差用batch均值和方差来代替,省了大量的计算需要,并且效果还很不错。
  BN本质,使得同分布;约束范围(量纲归一)。

Reference

  1. 《Batch Nomalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》
  2. 《A Convergence analysis of log-linear training》
  3. https://www.projectrhea.org/rhea/index.php/ECE662_Whitening_and_Coloring_Transforms_S14_MH
原创粉丝点击