算法面试高频知识点:BN层详解(全网最全)

图片说明

这是我之前写在公众号里的一篇文章,在此分享到牛客上,一来是希望能和牛客上的朋友们一起交流学习CV算法以及相应的知识,也欢迎大家关注我的公众号*********。

一.Batch Normalization基本原理及公式

BN的基本原理

Batch Normalization又称为“批归一化”。
首先,在进行训练之前,一般要对数据做归一化,使其分布一致。

那么为什么要归一化呢?归一化后有什么好处呢?

因为神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大下降,另一方面,深度神经网络训练过程中,通常以送入网络的每一个Batch训练,一般每一个Batch具有不同的分布,那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。

此外,为了解决internal covarivate shift问题,这个问题定义是随着Batch Normalization这篇论文提出的,在训练过程中,数据分布会发生变化,对下一层网络的学习带来困难。

所以Batch Normalization就是强行将数据拉回到均值为0,方差为1的正态分布上,这样不仅可以让数据保持相近的分布,而且避免发生梯度消失。

此外,internal corvariate shift和covariate shift是两回事,前者是网络内部,后者是针对输入数据,比如我们在训练数据前做归一化等预处理操作。

BN的公式

在这里插入图片描述

上图就是一个标准的数据减均值除方差的归一化流程。

加入缩放和平移变量的原因

可以变换回原始的分布,保证每一次数据经过归一化后还保留原有学习来的特征,同时又能完成归一化操作,提高模型的容纳能力(capacity)。这两个参数是用来学习的参数。

在这里插入图片描述

如上图中左边是没有任何处理的输入数据,曲线是激活函数sigmoid的曲线。如果数据如上图所示在梯度很小的区域,那么学习速率就会很慢甚至陷入长时间的停滞。减去均值再除以方差之后,数据被移到了中心区域,如上图右边所示。对于大多数激活函数而言,这个区域的梯度都是最大的或是有梯度的,比如ReLU函数,==这可以看作是一种对抗梯度消失的手段。== 对于一层是如此,如果对于每一层数据都这么操作,那么数据的分布就总是在随输入变化敏感的区域,相当于不用考虑数据分布变来变去了(解决了internal covarivate shift),这样训练起来效率就高多了。不过到这里问题并没有结束,因为减去均值除方差未必是最好的分布。比如数据本身就很不对称,或者激活函数未必是对方差为1的数据有最好的效果。所以要加入缩放及平移变量来完善数据分布以达到比较好的效果。

训练和测试阶段的不同

在训练阶段,BN层是对每一批的训练数据进行归一化,也即用每一批数据的均值和方差。(每一批数据的方差和标准差不同)

而在测试阶段,我们一般只输入一个测试样本,并没有batch的概念。因此这个时候用的均值和方差是整个数据集训练后的均值和方差,可以通过滑动平均法求得:

图片说明

上面式子简单理解就是:对于均值来说直接计算所有batch u值的平均值;然后对于标准偏差采用每个batch σB的无偏估计。

在测试时,BN使用的公式是:

图片说明

二.BN训练时为什么不用整个训练集的均值和方差?

因为用整个训练集的均值和方差容易过拟合,对于BN,其实就是对每一批数据进行归一化到一个相同的分布,而每一批数据的均值和方差会有一定的差别,而不是固定的值,这个差别能够==增加模型的鲁棒性==,也会在一定程度上减少过拟合。

三.BN用在哪里?

在CNN中,BN层应该用在非线性激活函数前面,即对做归一化。由于神经网络隐藏层的输入是上一层非线性激活函数的输出,在训练初期其分布还在剧烈改变,此时约束其一阶矩和二阶矩无法很好地缓解 Covariate Shift;而BN的分布更接近正态分布,限制其一阶矩和二阶矩能使输入到激活函数的值分布更加稳定。

四.BN层的参数量

我们知道是需要学习的参数,所以其实BN的本质就是利用优化改变方差大小和均值的位置。在CNN中,因为网络的特征是对应到一整张特征图上的,所以做BN的时候也是以特征图为单位而不是按照各个维度。比如在某一层,Batch大小为,那么做BN的参数量

五.BN的反向传播算法

在这里插入图片描述

接下来我们详细的解释一下各个式子的推导过程:

对于上图第二个式子:
在这里插入图片描述

对于第三个式子:

在这里插入图片描述

对于第四个式子:

在这里插入图片描述

六.BN的优缺点

优点:

  1. 可以选择较大的初始学习率。因为这个算法收敛很快。
  2. 可以不用dropout,L2正则化。
  3. 不需要使用局部响应归一化。
  4. 可以把数据集彻底打乱。
  5. 模型更加健壮。

缺点:
Batch Normalization非常依赖Batch的大小,当Batch值很小时,计算的均值和方差不稳定。
所以BN不适用于以下几个场景:

  1. 小Batch
  2. RNN

七.Python代码实现

import numpy as np

def Batchmorm(x, gamma, beta, bn_param):

    #x_shape:[B,C,H,W]
    running_mean = bn_param['running_mean']
    running_var = bn_param['running_var']
    results = 0
    eps = 1e-5

    x_mean = np.mean(x, axis=(0, 2 ,3), keepdims=True)
    x_var = np.var(x, axis=(0, 2, 3), keepdims=True)
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
    results = gamma * x_normalized + beta

    #因为在测试时是单个图片测试,这里保留训练时的均值和方差,用在后面测试时用
    runnng_mean = momentum * running_mean + (1 - momentum) * x_mean
    running_var = momentum * running_var + (1 - momentum) * x_var

    bn_param['running_mean'] = running_mean
    bn_param['running_var'] = running_var

    return results, bn_param
#面经##秋招##实习##面试八股文##面霸的自我修养#
全部评论
看上去好高深啊
点赞 回复 分享
发布于 2022-08-12 20:15

相关推荐

昨天 16:00
门头沟学院 Java
点赞 评论 收藏
分享
评论
4
22
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务