暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【BN】认识批量归一化

端茶送水杂货铺 2020-04-05
801


点击蓝字关注我们

应用之道

存乎一心



《【BN】认识批量归一化》一文将要带大家了解归一化的作用和批量归一化的原理。阅读本文需要一定的线性代数和概率统计基础知识。

本文参考资料如下:

(一)台大 李宏毅 《机器学习》

(二)知乎 天雨粟 《BN 原理与实战》

(三)谷歌开发者平台及其它互联网资料

其中,李宏毅老师的讲解(参考资料一)通俗易懂,而天雨粟(参考资料二)的数理推导更详尽,读者可以根据自身基础灵活选择。本文中如有错误,欢迎大佬们指正!




前言



本文主要来从理论视角对深度学习中的批量归一化的思路进行讲解、归纳和总结。


01

特征缩放


在运用一些机器学习算法的时候不可避免地要对数据进行特征缩放(Feature Scaling)。特征缩放的目标就是数据规范化,使得特征的范围具有可比性。


样例一:特征缩放的意义


假如说我们现在有一个神经网络,它的一个输入为 1、2 数量级,另一个输入为100、200数量级。此时为了让输出的 a 维持一定的标准态,w1 的取值应该是一个很大的数,w2 的取值就应该是一个很小的数。这样两者相乘后的结果再相加才能得到一个比较合理的数。



如下图所示,w1、w2 和 Loss 的关系其是一个椭圆形的曲线。其原因就是 Loss 在 w1 方向上的梯度变化缓慢,而在 w2 方向上的梯度变化剧烈,最终整个曲线的形状像一个椭圆形。



在训练的过程中,我们为了避免这种情况发生,可以在 w1 方向上使用较大的学习率(Learning rate),而在 w2 方向上使用较小的学习率。


如果我们对两个输入实施特征缩放,使它们保持在同一个数量级(此处选定 1、2 数量级)。



w1、w2 和 Loss 的关系就会变成一个正圆形的曲线。此时,不管在哪个方向上 Loss 的梯度都一样,而在训练过程中,模型也能很快收敛



以下选取两种常用的特征缩放方法进行讲解:


调节比例( Rescaling)


这种方法是将数据都规范到 [0, 1] 或者 [-1, 1] 之间,至于缩放到什么范围,完全由数据的性质来决定。计算公式如下:



 其中 x 是最初的特征值,x’ 是缩放后的特征值。


归一化(Normalization)


归一化(又称称规范化)是一个统计学中的概念,它并不是一个完全定义好的数学操作(如加减乘除)。它通过将数据进行偏移和尺度缩放调整,在数据预处理时是非常常见的操作,如今在网络的中间层也很频繁的被使用。


特征标准化使每个特征的值有零均值(Zero-Mean)和单位方差(Unit-Variance),这个方法在机器学习地算法中被广泛地使用。例如SVM、逻辑回归和神经网络。其计算公式如下:



 其中 x 是最初的特征值,x’ 是缩放后的特征值,mean 代表均值,std 代表标准差。



相对来说,使用了特征缩放的梯度下降收敛速度会更快。


01

内部协方差平移


在深度学习中,由于问题的复杂性,我们往往会使用较深层数的网络进行训练,相信很多炼丹的朋友都对调参的困难有所体会,尤其是对深层神经网络的训练调参更是困难且复杂。在这个过程中,我们需要去尝试不同的学习率、初始化参数方法(例如 Xavier 初始化)等方式来帮助我们的模型加速收敛。深度神经网络之所以如此难训练,其中一个重要原因就是网络中层与层之间存在高度的关联性与耦合性。


对于神经网络而言,随着训练的进行,网络中的参数也随着梯度下降在不停更新:

  • 一方面,当底层网络中参数发生微弱变化时,由于每一层中的线性变换与非线性激活映射,这些微弱变化随着网络层数的加深而被放大(类似蝴蝶效应)。

  • 另一方面,参数的变化导致每一层的输入分布会发生改变,进而上层的网络需要不停地去适应这些分布变化,使得我们的模型训练变得困难。

上述这一现象叫做内部协方差平移(Internal Covariate Shift,ICS)。


批量归一化的原论文作者给了一个比较规范的定义:在深层网络训练的过程中,由于网络中参数变化而引起内部结点数据分布发生变化的这一过程被称作内部协方差平移。


样例二:内部协方差类比


内部协方差平移的定义并不是很好理解,下面我们将通过一个例子直观讲解这一效应。


我们都知道神经网络通常会有很多层,此处我们以一个二层网络为例。参数在调整的时候,前一个层是后一个层的输入,而前一个层的参数变动之后也会改变后一层的参数。所以每轮迭代中,整个网络的参数都是在变化的。即使输入数据是固定的,但由于后面层的参数在不断变化以至于很难算出其均值和标准差。



整个过程就像下图,我们给四个小人分配传声筒,只有每个小人的话筒连接在一条线时,讯息才能顺利地从第一个人传送到最后一个人。



现在,我们看到第二个小人在训练时,为了将两个话筒拉到同一个水平高度,他会将左手边的话筒放低一点,同时右手的话筒放高一点。但因为两边同时改变,改变幅度不好控制,所以就可能出现下图,小人两边的话筒最后还是没怼上:



事实上,学习率太大造成了上述现象。虽然调小学习率可以很好地解决这个问题,但又会导致训练速度变慢。


要缓解 ICS 的问题,就要明白它产生的原因。ICS 产生的原因是由于参数更新带来的网络中每一层输入值分布的改变,并且随着网络层数的加深而变得更加严重因此我们可以通过固定每一层网络输入值的分布来对减缓 ICS 问题。


白化(Whitening)


白化是机器学习里面常用的一种规范化数据分布的方法,主要是 PCA 白化与 ZCA 白化。白化是对输入数据分布进行变换,进而达到以下两个目的:

  • 使得输入特征分布具有相同的均值与方差。其中 PCA 白化保证了所有特征分布均值为 0,方差为 1,而 ZCA 白化则保证了所有特征分布均值为 0,方差相同。

  • 去除特征之间的相关性。

通过白化操作,我们可以减缓 ICS 的问题,进而固定了每一层网络输入分布,加速网络训练过程的收敛。


批量归一化(Batch Normalization)


虽然白化可以解决 ICS 问题,但它仍然具有一定的缺陷,其主要有以下两个:

  • 白化过程计算成本太高,并且在每一轮训练中的每一层我们都需要执行高成本计算的白化操作。

  • 白化过程由于改变了网络每一层的分布,因而改变了网络层中本身数据的表达能力。底层网络学习到的参数信息会被白化操作丢失掉。


基于白化的两个问题,我们的解决思路就很简单,一方面,我们提出的归一化方法要能够简化计算过程。另一方面又需要经过规范化处理后让数据尽可能保留原始的表达能力。于是就有了简化改进版的白化——批量归一化。


01

BN 算法


批量(Batch)


在讲解批量归一化之前,我们再来回顾下批量的实现原理。


假设我们现有 x1、x2、x3 三组数据,将它们通过同一组参数 w1 后得到 z1、z2、z3,然后再将 z1、z2、z3 经过 Sigmoid 激活函数后得到 a1、a2、a3,依此类推不断传递下去:



我们可以把 x1、x2、x3 都同时放进一个矩阵里得到 [x1, x2, x3] ,再将 [x1, x2, x3] 与 w1 相乘后得到 [z1, z2, z3],这个矩阵化过程就叫批量处理。



比起分别计算三次矩阵乘法,批量处理法只需要平行计算一次。另外,它还可以利用 GPU 加速运算。


训练过程


我们可以根据第一层的输出 [z1, z2, z3] 求出其均值 𝜇 和标准差 𝜎 。


接下来,我们通过用 zi 减去均值 𝜇 再除以标准差 𝜎 的方式,得到批量归一化后的 z ̃。



随后,我们再让 [z ̃1, z ̃2, z ̃3] 通过 Sigmoid 激活函数,得到新的输出 [a1, a2, a3]。



但这就产生了一个新的问题:在训练过程中,我们在激活函数之前都做了一次批量归一化,那之后的反向传播又该如何进行?


其实在每次做反向传播的过程中,由于网络会通过参数 σ 和 μ 来更新第一层输出 zi ,但这一操作又会使得 zi 的均值 𝜎  和标准差 𝜇 的数值自然而然地发生变化。因此,(𝜇, 𝜎)和 zi 存在依赖关系,我们在训练过程中也必须要考虑(𝜇, 𝜎)。



为此,我们引入一组独立的参数(𝛽, 𝛾),这组参数和输入的批量数据无关,它们是神经网络通过学习得到,而(𝜇, 𝜎)和输入的批量数据有关。



网络的整体结构如下图所示:



我们可以进一步分析(𝜇, 𝜎)和(𝛽, 𝛾)这两组参数之间的关系:

  • 当(𝜇, 𝜎)与(𝛽, 𝛾)对应相等的时候,这就相当于没有进行批量归一化。

  • 当 (𝜇, 𝜎)与(𝛽, 𝛾)不等的时候,批量归一化起作用。


在此,我们可以总结下(𝛽, 𝛾)的作用,(𝛽, 𝛾)两参数相当于将归一化后的数据再扩展和平移。这是为了让神经网络自己去学习、使用和修改扩展参数 𝛾 以及平移参数 𝛽。神经网络就能借此自己慢慢琢磨出归一化操作到底有没有起到优化的作用。如果没有起到作用, 神经网络使用 𝛾 和 𝛽 来抵消一些归一化操作。


批量归一化的完整算法如下:



测试过程


测试过程与训练过程仍有较大区别。在训练过程中,我们可以喂入全部批量的训练数据。而在测试过充中,我们只能喂入一个批量的数据,因此我们无法估计出 𝜇 和 𝜎 的值。



我们提供两个在测试阶段估计 𝜇 和 𝜎 值的方法:

  • 理想方法:由于网络已经训练完毕,其参数已经固定,我们可以通过整个训练集上的 𝜇 和 𝜎 值来代表测试时的 𝜇 和 𝜎 值。但这个方法存在明显的不足,它需要计算整个训练集过于浪费时间。

  • 实际方法:在训练过程中,我们把每个批量所得到的 𝜇 和 𝜎 值都保存下来,然后用其平均值来代替我们最终测试时的 𝜇 和 𝜎 值。



由上图可以看出,训练之初(即 𝜇1)的准确率其实并不高,而越靠后( 如 𝜇100、𝜇300)的准确率反而越高,如果直接使用训练的均值来代替测试的均值 𝜇 反而会拉低网络的效果。


因此,我们也可以不用训练过程的均值代替测试过程的数值 𝜇,而是根据准确度的不同赋予 𝜇i 不同的权重。准确度越高的 𝜇i 赋更大的权重,准确度越低的 𝜇i 赋更小的权重,最后我们得到一个加权后的数值用来当做测试时的参数 𝜇。同理,我们对于 𝜎 也执行类似的操作。


01

BN 优势


批量归一化在实际工程中被证明了能够缓解神经网络难以训练的问题,其优点主要包括:


1. 批量归一化使得网络中每层输入数据的分布相对稳定,加速模型学习速度


批量归一化通过规范化与线性变换使得每一层网络的输入数据的均值与方差都在一定范围内,使得后一层网络不必不断去适应底层网络中输入的变化,从而实现了网络中层与层之间的解耦,允许每一层进行独立学习,有利于提高整个神经网络的学习速度。


2. 批量归一化使得模型对网络中的参数不那么敏感,简化调参过程,使得网络学习更加稳定


在神经网络中,我们经常会谨慎地采用一些权重初始化方法或者合适的学习率来保证网络稳定训练。


3. 批量归一化允许网络使用饱和性激活函数,可以缓解梯度消失问题


在不使用批量归一化层的时候,由于网络的深度与复杂性,很容易使得底层网络变化累积到上层网络中,导致模型的训练很容易进入到激活函数的梯度饱和区。通过归一化操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题。另外,通过自适应学习 𝛽 与 𝛾 又让数据保留更多的原始信息。


样例三:缓解梯度消失举例


批量归一化层通常放在激活函数之前。进入激励函数前的值的分布很重要。只有数值大多分布在这个区间的数据, 才能进行更有效的传递。


我们以几乎函数 tanh 为例,对比激活之前的两个数值分布,上者没有进行批量归一化,而下者进行了批量归一化。



由下图可知,没有批量归一化的数据在使用 tanh 激活函数以后,其激活值大部分都分布到了饱和阶段。也就是说,大部分的激活值不是 -1 就是 1。而批量归一化后大部分的激活值在每个分布区间都还有存在。显然可见,进行批量归一化后的数值能够更有效地利用 tanh 激活函数进行非线性化过程.



我们再将经过批量归一化并且激活后的分布传递到下一层神经网络进行后续计算。相较于未经过批量归一化的极端分布,经过批量归一化的分布对于神经网络来说更有价值。



4. 批量归一化具有一定的正则化效果


在批量归一化中,由于我们使用 mini-batch 的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个批量中的数据都是从总体样本中抽样得到,但不同 mini-batch 的均值与方差会有所不同。这就为网络的学习过程中增加了随机噪音,在一定程度上对模型起到了正则化的效果。



应用之道

END

存乎一心


 

本文作者:Bingunner


一位头发浓郁的信息安全工程师

爱摄影/爱数码/爱跑步的经济学人死忠粉

文章转载自端茶送水杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论