BatchNorm
实现过程: 计算训练阶段 mini_batch 数量激活函数前结果的均值和方差, 然后对其进行归一化, 最后对其进行缩放和平移。
作用:
- 可以使用更高的学习率进行优化;
- 移除或使用较低的 dropout;
- 降低 L2 权重衰减系数;
- 调整了数据的分布, 不考虑激活函数, 它让每一层的输出归一化到了均值为 0 方差为 1 的分布, 这保证了梯度的有效性, 可以解决反向传播过程中的梯度问题
滑动平均
- 训练时使用一个minibatch的训练数据计算均值和方差然后标准化数据,在test的时候我们也希望作相同的处理,比较直接的方法是在训练集上重新计算一遍统计量,但是,如果有1000w数据,这种计算就比较花费时间,而test的速度越快越好,所以在训练的时候,顺便就把均值和方差计算出来了,当然不是精确值,是近似值,这就是moving average。
running_mean = momentum * running_mean + (1 - momentum) * sample_mean
running_var = momentum * running_var + (1 - momentum) * sample_var
上述公式中的 momentum 为动量参数,在 TF/Keras 中,该值为0.99,在 Pytorch 中,这个值为0.9
初始值,moving_mean=0,moving_var=1,相当于标准正态分布,当然,理论上初始化为任意值都可以
-
可以理解为每次更新running mean相当于把之前的值衰减一些(* momentum),然后把当前的minibatch sample mean加进去一部分(* (1-momentum))。其实也就是一阶指数平滑平均
var同理,两个值在训练迭代过程中相当于是在不断的moving。完全是经验主义,没什么道理可讲,所以batch normalization本身是个次优的normalization,可能今后会被更优的normalization模型所取代。 -
在test时,直接使用训练得到的running mean/var标准化数据:都是对单个样本进行测试。 这个时候的均值和方差是全部训练数据的均值和方差, 这两个数值是通过移动平均法求得。
当一个模型训练完成之后, 它的所有参数都确定了, 包括均值和方差, gamma 和 bata
x_stand = (x - running_mean) / np.sqrt(running_var) out = x_stand * gamma + beta
BatchNorm和LayerNorm的区别
BatchNorm: 对一个batch-size样本内的每个特征做归一化
LayerNorm: 针对每条样本,对每条样本的所有特征做归一化
简单举例:
假设现在有个二维矩阵:行代表batch-size, 列表示样本特征
BatchNorm就是对这个二维矩阵中每一列的特征做归一化,也就是竖着做归一化
LayerNorm就是对这个二维矩阵中每一行数据做归一化
相同点: 都是在深度学习中让当前层的参数稳定下来,避免梯度消失或者梯度爆炸,方便后面的继续学习
不同点
- 如果你的特征依赖不同样本的统计参数,那BatchNorm更有效, 因为它不考虑不同特征之间的大 小关系,但是保留不同样本间的大小关系
- Nlp领域适合用LayerNorm, CV适合BatchNorm,
- 对于Nlp来说,它不考虑不同样本间的大小关系,保留样本内不同特征之间的大小关系*