本文尝试理解Batch Normalization算法
- BN在做什么
- BN为什么这么做
- BN的反向求导
一些约定/常识
Batch Normalization层简称BN层,或者就叫BN;
神经网络中连续的多个线性变换层,等效于一个线性变换层(x=WU+B),因而往往是每个线性层后面接一个非线性变换层(激活函数层);
所谓网络可学习参数,是说网络建立时给它初值,随后每次BP都进行更新,最典型的是weights和bias,BN层中的
γ
γ
和
β
β
也是。
BN在做什么
假定batch_size
=
m
m
,网络中的某层输出为,并且
x⃗
x
→
为BN层的输入。我们约定“一次操作=平移和伸缩变换”,那么BN做了两次这种操作,使得
x⃗
x
→
先被标准化,再被逆标准化。
首先,BN将 x⃗ x → 转化到标准正态分布 N(0,1) N ( 0 , 1 ) ,得到 x^⃗ x ^ → (x hat):
xi^=xi−μσ x i ^ = x i − μ σ
其中
μ=1mΣxiσ=1m(xi−μ)2−−−−−−−−−−√ μ = 1 m Σ x i σ = 1 m ( x i − μ ) 2其次,BN将 x^⃗ x ^ → 转化到非标准正态分布 N(γ,β) N ( γ , β ) ,得到 x~⃗ x ~ → (x tilde):
xi~=xi^γi+βi x i ~ = x i ^ γ i + β i
其中 γi γ i 和 βi β i 是可学习参数。
BN为什么这么做
网上说法认为BN的前后两次“平移和缩放”操作,使得 x⃗ x → 的分布得到了改变,既不至于都在激活函数的非线性区(例如sigmoid的饱和区),也不至于都在线性区(都在线性区导致激活函数退化为线性变换,让整个网络表达能力退化为单层线性变换)。
个人理解为BN是在为激活函数打补丁,单层的非线性激活函数表达能力理论上可以很强,但出于求导计算方便的考虑,用的都是形式简单的例如ReLU,但缺点是表达能力会不太够,或者说表达出来的特征容易跑偏,就需要调小学习率,但调小学习率又让收敛变慢。BN+ReLU这样的组合,里面包含了 γ γ 和 β β 这两个可学习参数,那么BN+ReLU的整体,就是在学习一个更好的激活函数。按照这样的理解,Conv+BN+ReLU是可以的,Conv+ReLU+BN也是可以的;甚至可以尝试想一些其他的激活函数。
Caffe中的BN算法实现
需要使用BatchNorm层和Scale层来一起实现。
BatchNorm层:负责减均值、除标准差。 BatchNorm层的blob依次存储了:(0) mean, (1) variance, and (2) moving average factor