[DeepLearning]Batch normalization笔记
Batch normalizaion是normalization的一种。BN并不是在数据的预处理阶段,而是运用在模型的层与层之间。BN是以batch的粒度进行的,它的作用是用来加快模型的计算速度,能够在训练以及推理阶段用一个相对较高的学习率来进行收敛。
在实际的运用中,我们通常将batch normalization层加在激活函数之前。
整个顺序为
Linear transformation; z = g(w, x) + b
Batch normalization; z_n = gamma * (z - mean) / std + beta
Activation function; a = f(z_n)
其中mean为输入的平均值(以batch作为粒度);std为输入的标准差;gamma和beta为可学习参数,它们的作用时在训练阶段修改输入的分布。
由于在测试/推理阶段,输入的数据只有一条,我们不能像在训练阶段一样通过mini-batch获得对应的mean和std。因此在测试/推理阶段,我们使用exponentially weighted average来预估测试/推理阶段的mean和std。即使用训练阶段各个batch的mean和std来作为测试/推理阶段的mean和std。
Exponentially weighted average, 也叫exponential moving average(EMA),是用来将最近的数据和以前的数据通过加权的方式来求取新的平均值。在BN的中,每训练一个batch,我们将当前batch的mean和std和之前计算的mean和std做加权平均,通过这样的方式我们来更新mean和std。因此我们在每训练一个新的batch,我们都会更新mean和std(也叫running mean和running std)。EMA的公式为:
EMA(t) = alpha * data(t) + (1 - alpha) * EMA(t-1)
其中t为时间;alpha是一个取值在0-1之间的一个数,通过修改alpha可以改变新增的数据在平均值中的权重。在BN中alpha通常取0.9。
因此使用在测试/推理阶段running_mean和running_std的计算为:
self.running_mean = 0.9 * self.running_mean + 0.1 * current_mean
self.running_std = 0.9 * self.running_std + 0.1 * current_std
在训练阶段我们就能得到running mean和running std,然后我们使用这个running mean和running std作为测试/推理阶段的mean和std。