前言
前面也讲过部分Batch Normalize的内容,单独拿出来成文,是因为感觉这方法非常赞,加快训练速度十几倍不等,模型越复杂越受益。
一句话总结BN:对每层输入加同分布约束,再加参数线性变换学习其表达能力。
BN解决的问题
Problem :: Internal Covariate Shift
神经网络训练的难题之一,在前层参数变化时,每层的输入分布也随之变化。这就造成了当层的训练困难,老是变来变去,还能不能好好地玩耍啊~通常地解决思路是使用很小的学习率,并且小心地初始化。
Batch Normalize的基本思想是,将每层的输入做std-normalize, y=x−x¯var(x)√ y = x − x ¯ v a r ( x ) ,使得变换后,是 N(0 1) N ( 0 1 ) 高斯分布。
疑问解答
1)Batch Normalize是怎么做的?
假设输入m-size的batch样本 x x ,对其中的所有特征都做如下处理:
2)单纯地std-normalize能行么?
只是将输入约束到同分布下,岂不是所有层的输入都一样了,那还学个毛线啊。在normalize上,Sergey更向前走了一步,一不做二不休,干脆再搞它俩参数 γ γ 和 β β ,将输入恢复出来,通过不断学习调整这两个参数,使得重构输入的能力也能被搞定。
3)梯度消失的现象在带有BN的网络结构里还存在么?
误差后传,传递的是误差项 ∗ ∗ 导数项
其他项;传递的动作是链式法则的体现。随着传递路径越长,越容易出现为0的现象。
原因1: sigmoid激活函数,自身带有的饱和域(导数近似为0)。
原因2: 串联网络本身的参数累乘所带来的梯度消失问题没有解决掉。
ReLU激活函数,只是解决了由于激活函数的饱和域(导数近似0)所带来的的梯度消失问题。
BN方法,会将训练早期的数据约束到[-1,+1]范围内,避开了饱和区域,也能解决饱和域带来的梯度消失问题。
4)BN在网络中,放到哪里适合?
在非卷积网络中,通常是放到激活函数前面,处理之后做激活函数输入: σ(BN(wx)) σ ( B N ( w x ) ) 。
notice:由于 BN(wx+b)=BN(wx) B N ( w x + b ) = B N ( w x ) ,会将bias去掉,后面的 β β 起到类似bias的作用。
在卷积网络中,则要服从卷积的特性。利用固定filter-blank抽取某一特征feature-map,相当于每个f-map是一个抽取之后的特征(是个整体),那么对只需要对feature-map加统一的 γ γ 和 β β 即可,同样放到激活函数前。详细如下图。
5)如何解释 BN使得网络更稳定的特性
假设权重参数 w w 变为 ,对新旧参数下的 x x 求导如下: