为什么要归一化?
归一化已经成为深度神经网络的重要组成部分,可以补偿某些激活函数(如ReLU,ELU等)的无界性质。利用这些激活函数,输出层不会受限于有界范围内(例如:[-1,1]对于tanh而言)。为了限制无限激活增加输出层值,在激活函数之前使用归一化。在深度神经网络中使用了两种常见的规范化技术,并且经常被初学者误解。在本教程中,将讨论两种归一化技术的详细说明,重点介绍它们的主要区别。
局部响应归一化
局部响应归一化(LRN)最初是在AlexNet体系结构中引入的,当时使用的激活函数是ReLU,而不是更常见的tanh和sigmoid。使用LRN的原因是为了鼓励侧抑制。这是一个神经生物学的概念,指的是神经元降低其相邻活性的能力。在DNN中,这种侧抑制的目的是进行局部对比度增强,使局部最大像素值作为下一层的激励。
LRN是一个不可训练的层,它将局部邻域内的特征图中的像素值进行平方归一化。根据定义的邻域,LRN有两种类型,如下图所示
Inter-Channel LRN:这是AlexNet论文最初使用的内容。定义的邻域跨越Channel 。对于每个(x,y)位置,归一化在深度维度中执行,并由下面的公式给出
其中i表示filter i的输出,a(x,y), b(x,y)分别为归一化前后(x,y)位置的像素值,N为通道总数。常数(k,α,β,n) 是超参数。k是用来避免奇异点(除零),α作为归一化常数,β是对比常数。常数n用于定义邻域长度,即在进行归一化时需要考虑多少个连续像素值。(k,α,β,n) = (0, 1, 1, n)是标准的归一化。在上图中,n取2而N = 4。
我们来看一个Inter-channel LRN的例子。请看下图
不同的颜色表示不同的通道,因此N=4。让超参数为(k,α,β,n) = (0, 1, 1, 2)。n=2表示在计算位置(i,x,y)的归一化值时,我们考虑上一个和下一个filter i在相同位置的值,即(i-1, x, y)和(i + 1, x, y)。对于(i,x,y)=(0,0,0),我们有值(i,x,y)= 1,值(i-1,x,y)不存在和值(i +1,x, y)= 1。因此归一化值(i (x, y) = 1 /(12+ 12) = 0.5,可以在上图的下半部分看到。其余的归一化值以类似的方式计算。
Intra-Channel LRN:在Intra-channel LRN中,邻域在同一通道内进行扩展,如图所示。公式由
其中(W,H)为特征映射的宽度和高度(如上图(W,H) =(8,8))。Inter和Intra Channel LRN的唯一区别是归一化的邻域。在Intra-channel LRN中,围绕未考虑的像素定义2D邻域(相对于通道内的一维邻域)。例如,下图显示了5x5 feature map上的Intra-Channel归一化,其中n=2(即大小为(n+1)x(n+1)的2D邻域,以(x,y)为中心)。
批归一化
批处理标准化(BN)是一个可训练的层,通常用于处理ICF(Internal Covariate Shift)问题。ICF的产生是由于隐藏神经元/激活的分布发生了变化。考虑下面的二元分类示例,其中我们需要对玫瑰和非玫瑰进行分类
假设我们已经训练了一个神经网络,现在我们从数据集中选择两个截然不同的外观batches进行推理(如上所示)。如果我们使用这两个batches进行forward pass并绘制隐藏层(deep in the network)的特征空间,我们将看到分布的显著变化,如上图右侧所示。这被称为输入神经元的Covariate shift。这在训练期间有什么影响呢?在训练过程中,如果我们选择了属于不同分布的batches,那么它就会减慢训练的速度,因为对于给定的batch,它试图学习特定的分布,而对于下一个batch,该分布是不同的。因此,它继续在分布之间来回反弹,直到它收敛为止。这种Covariate shift可以通过确保batch中的成员不属于相同/类似的分布来缓解。这可以通过随机选择batches图像来完成。隐藏神经元存在类似的Covariate shift。即使随机选择batches,隐藏的神经元也可能最终具有一定的分布,这会减慢训练速度。隐藏层的这种Covariate Shift称为Internal Covariate Shift。问题是我们不能像输入神经元那样直接控制隐藏神经元的分布,因为它随着训练更新训练参数而不断变化。批归一化有助于缓解此问题。
在批归一化中,隐藏神经元的输出在被馈送到激活函数之前以下列方式处理。
1.将整个batch B归一化为零均值和单位方差
- 计算整个mini-batch输出的均值:u_B
- 计算整个mini-batch输出的方差:sigma_B
- 通过减去均值并除以方差来归一化mini-batch
2.引入两个可训练参数(Gamma: scale_variable和Beta: shift_variable)来scale和shift归一化的mini-batch输出
3.将这个scaled和shifted归一化的mini-batch提供给激活函数。
BN算法可以在下图中看到
对batch中的所有激活中的每个像素进行归一化。考虑下图。假设我们有一个大小为3的mini-batch。隐藏层产生大小为 (C,H,W) =(4,4,4)的激活。由于batch大小为3,我们将有3个这样的激活。现在,对于激活中的每个像素(即对于每个4x4x4=64像素),我们将通过找到所有激活中该像素位置的均值和方差对其进行归一化,如下图的左侧所示。一旦找到均值和方差,我们将从每个激活项中减去均值,并将其除以方差。下图的右侧描述了这一点。减法和除法是逐点进行的。
步骤2即scaling和shifting的原因是让训练来决定我们是否需要归一化。在某些情况下,不进行归一化可能会产生更好的结果。因此,BN让训练来决定是否包含归一化层,而不是预先选择。当Gamma = sigma_B和Beta = u_B时,不进行归一化,恢复原始激活。
比较:
LRN具有多个方向来执行归一化(Inter或Intra Channel),BN仅具有一种执行方式(对于所有激活中的每个像素位置)。下表比较了两种归一化技术。
本文暂时没有评论,来添加一个吧(●'◡'●)