学习记录
Batch Normalization,一个非常有用的技巧。本来想自己写这一部分的,但是在网上看到两个写得感觉特别好,感觉就没必要自己纯粹自己写了。抱着学习的目的,抄过来简单做个记录,省的下次再找了。下面是相应的链接,BN原理那个是知乎上PENG的一篇文章,BN的TensorFlow应用那个是CSDN博主shuzfan的一篇博客,详细的可以点进链接学习
BN原理 https://zhuanlan.zhihu.com/p/26138673
BN的TensorFlow应用 https://blog.csdn.net/shuzfan/article/details/79054561
BN原理
简介
一般来说,如果模型的输入特征不相关且满足标准正态分布N(0, 1)时,模型的表现一般较好。在训练神经网络模型时,我们可以事先将特征去相关并使得它们满足一个比较好的分布,这样,模型的第一层网络一般都会有一个比较好的输入特征,但是随着模型的层数加深,网络的非线性变换使得每一层的结果变得相关了,且不再满足N(0, 1)分布。更糟糕的是,可能这些隐藏层的特征分布已经发生了偏移。
为了解决这个问题,可以在层与层之间加入Batch Normalization层。训练时,BN层利用隐藏层输出结果的均值与方差来标准化每一层特征的分布,并且维护所有mini-batch数据的均值与方差,最后利用样本的均值与方差的无偏估计量用于测试时使用。
鉴于在某些情况下非标准化分布的层特征可能是最优的,标准化每一层的输出特征反而会使得网络的表达能力变得不好,可以在BN层加上了两个可学习的缩放参数gamma和偏移参数beta来允许模型自适应地去调整层特征分布。
BN层的作用:
1. 使得模型训练收敛的速度更快
2. 模型隐藏输出特征的分布更稳定,更利于模型的学习
BN的推导过程
前向算法
Batch Normalization层的实现很简单,主要的过程由如下算法给出
下面给出相应的代码实现
def batchnorm_forward(x, gamma, beta, bn_param):
"""
Forward pass for batch normalization.
Input:
- x: Data of shape (N, D)
- gamma: Scale parameter of shape (D,)
- beta: Shift paremeter of shape (D,)
- bn_param: Dictionary with the following keys:
- mode: 'train' or 'test'; required
- eps: Constant for numeric stability
- momentum: Constant for running mean / variance.
- running_mean: Array of shape (D,) giving running mean of features
- running_var Array of shape (D,) giving running variance of features
Returns a tuple of:
- out: of shape (N, D)
- cache: A tuple of values needed in the backward pass
"""
mode = bn_param['mode']
eps = bn_param.get('eps', 1e-5)
momentum = bn_param.get('momentum', 0.9)
N, D = x.shape
running_mean = bn_param.get('running_mean', np.zeros(D, dtype=x.dtype))
running_var = bn_param.get('running_var', np.zeros(D, dtype=x.dtype))
out, cache = None, None
if mode == 'train':
sample_mean = np.mean(x, axis=0)
sample_var = np.var(x, axis=0)
out_ =