批标准化是优化深度神经网络中最激动人心的最新创新之一。实际上它并不是一个优化算法,而是一个自适应的重参数化的方法,试图解决训练非常深的模型的困难。非常深的模型会涉及多个函数或层组合。在其他层不变的假设下,梯度用于如何更新每一个参数。在实践中,我们同时更新所有层。当我们进行更新时,可能会发生一些意想不到的结果这是因为许多组合在一起的函数同时改变时,计算更新的假设是其他函数保持不变。举一个例子,假设我们有一个深度神经网络,每一层只有一个单元,并且在每个隐藏层不使用激活函数:y^=xw1w2w3⋅⋅⋅wl" role="presentation">y^=xw1w2w3⋅⋅⋅wl。此处,wi" role="presentation">wi表示用于层i" role="presentation">i的权重。层i" role="presentation">i的输出是hi=hi−1wi" role="presentation">hi=hi−1wi。输出y^" role="presentation">y^是输入x的线性函数,但是权重wi的非线性函数。假设代价函数y^" role="presentation">y^上的梯度为1,所以我们希望稍稍降低y^" role="presentation">y^。然后反向传播算法可以计算梯度g=▽wy^" role="presentation">g=▽wy^。想想我们在更新w←w−εg" role="presentation">w←w−εg时会发生什么。近似y^" role="presentation">y^的一阶泰勒级数会预测y^" role="presentation">y^的值下降εgTg" role="presentation">εgTg。如果我们希望y^" role="presentation">y^下降0.1" role="presentation">0.1,那么梯度中的一阶信息表明我们应设置学习率ϵ" role="presentation">ϵ为0.1gTg" role="presentation">0.1gTg。然而,实际的更新将包括二阶、三阶直到l" role="presentation">l阶的影响。y^" role="presentation">y^的更新值为:
x(w1−ϵg1)(w2−ϵg2)⋅⋅⋅(wl−ϵgl)" role="presentation">x(w1−ϵg1)(w2−ϵg2)⋅⋅⋅(wl−ϵgl)
这个更新中所产生的一个二阶项示例是ϵ2g1g2∏i=3lwi" role="presentation">ϵ2g1g2∏li=3wi。如果∏i=3lwi" role="presentation">∏li=3wi很小,那么该项可以忽略不计。而如果层3到层l的权重比1大时,该项可能会指数增大。这使得我们很难选择一个合适的学习率,因为某一层中参数更新的效果很大程度上取决于其他所有层。二阶优化算法通过考虑二阶互相影响来解决这个问题,但我么可以看到,在非常深的网络中,更高阶的互相影响会很显著,即使二阶优化算啊,计算代价也很高,并且通常需要大量近似,以免真正计算所有的重要二阶相互作用,因此对于n>2" role="presentation">n>2的情况,建立n阶优化算法似乎无望的。那么我们可以做些什么呢?
批标准化提出了一种机会可以重参数化所有深度网络的优雅方法。重参数化显著减少了多层之间协调更新的问题。批标准化可应用于网络的任何任何输入层或隐藏层。设H是需要标准化的某层的小批量激活函数,排列为设计矩阵,每个样本的激活出现在矩阵的每一行中。为了标准化H,我们将其替换为:
H′=H−μσ" role="presentation">H′=H−μσ
其中μ" role="presentation">μ是包含每个均值的向量,σ" role="presentation">σ是包含每个单元标准化的向量。此处的算术是基于广播向量μ" role="presentation">μ和向量σ" role="presentation">σ应用于矩阵H" role="presentation">H的每一行,运算是逐元素的,因此Hi,j" role="presentation">Hi,j标准化为减去μj" role="presentation">μj,再除以σj" role="presentation">σj。网络的其余部分操作H′" role="presentation">H′的方式和原网络操作H" role="presentation">H的方式一样。
在训练阶段,
μ=1m∑iHi;:" role="presentation">μ=1m∑iHi;:
和
σ=δ+1m∑i(H−μ)i2" role="presentation">σ=δ+1m∑i(H−μ)2i−−−−−−−−−−−−−−−√
其中δ" role="presentation" style="position: relative;">δ是个很小的正值,比如10−6" role="presentation" style="position: relative;">10−6,以强制避免遇到z" role="presentation" style="position: relative;">z√的梯度在z=0" role="presentation" style="position: relative;">z=0处未定义的问题。至关重要的是,我们反向传播这些操作。来计算均值和标准差,并应用于标准化H" role="presentation" style="position: relative;">H。这意味着,梯度不会再简单地增加hi" role="presentation" style="position: relative;">hi的标准差或均值:标准化操作会除掉这一操作的影响,归零其在梯度中的元素,这是批标准化方法的一个重大创新。以前的方法添加代价函数的惩罚,以鼓励单元标准化激活统计量,或者在每个梯度下降步骤之后重新标准化单元统计量。前者通常会导致不完全的标准化。而后者通常会显著地消耗时间,因为学习算法会反复改变均值和方差而标准化步骤会反复抵消这种变化。批标准化重参数化模型,以使一些单元总是被定义标准化,巧妙地回避了这两个问题。
在测试阶段,μ" role="presentation" style="position: relative;">μ和σ" role="presentation" style="position: relative;">σ可以被替换为训练阶段收集的运行均值。这使得模型可以对单一样本评估,而无须使用定义于整个小批量的μ" role="presentation" style="position: relative;">μ和σ" role="presentation" style="position: relative;">σ。回顾例子y^xw1w2⋅⋅\cdotwl" role="presentation" style="position: relative;">y^xw1w2⋅⋅\cdotwl,我们看到,可以通过标准化hl−1" role="presentation" style="position: relative;">hl−1很大程度上地解决学习这个模型的问题。假设x" role="presentation" style="position: relative;">x采样子一个单位高斯,那么hl−1" role="presentation" style="position: relative;">hl−1也是来自高斯,因为从x" role="presentation" style="position: relative;">x到hl" role="presentation" style="position: relative;">hl的变换是线性的。然而,hl−1" role="presentation" style="position: relative;">hl−1不再有零均值和单位方差。使用批标准化后,我们得到的归一化h^l−1" role="presentation" style="position: relative;">h^l−1恢复了零均值和单位方差的特性。对于底层的几乎任意更新而言,h^l−1" role="presentation" style="position: relative;">h^l−1仍然保持着单位高斯。然后输出y^" role="presentation" style="position: relative;">y^可以学习为一个简单的线性函数y^=wlh^l−1" role="presentation" style="position: relative;">y^=wlh^l−1.现在学习这个模型非常简单,因为底层的参数在大多数情况下没有什么影响。改变某个底层权重为零,可能使输出退化;改变底层权重的符号可能翻转h^l−1" role="presentation" style="position: relative;">h^l−1和y" role="presentation" style="position: relative;">y之间的关系。这些情况都是非常罕见的。没有标准化,几乎每一个更新都会对hl−1" role="presentation" style="position: relative;">hl−1的统计量有着极端的影响。因此,批标准化显著地使得模型更易学习。在这个示例中,容易学习的代价是使得底层网络没有用。在我们的线性示例中,较低层不再有任何有害的影响,但它们也不再有任何有益的影响。这是因为我们已经标准化了一阶和二阶统计量,这是线性网络可以影响的所有因素。在具有非线性激活函数的深度网络中,较低层可以进行数据的非线性变换,所以它们仍然是有用的。批标准化仅标准化每个单元的均值和方差,以稳定化学习,但允许单元和单个的非线性统计量之间的关系发生变化。
由于网络的最后一层能够学习线性变换,实际上我们可以希望移除一层内单元之间的所有线性关系。事实上,这是Guillaume中采用的方法,为批标准化提供了灵感。令人遗憾的是,消除所有的线性关联比标准化各个独立单元的均值和标准代价函数更高,因此批标准化仍是迄今最实用的方法。
标准化一个单元的均值和标准差会降低包含该单元的神经网络的表达能力。为了保持网络的表现力,通常会将批量隐藏单元激活H替换为γH′+β" role="presentation" style="position: relative;">γH′+β,而不是简单地使用标准化的H'。变量γ" role="presentation" style="position: relative;">γ和β" role="presentation" style="position: relative;">β是允许新变量有任意均值和标准差的学习参数。乍一看,这似乎是无用的------为什么我们将均值设为0" role="presentation" style="position: relative;">0,然后又引入了参数允许它被重设为任意值β" role="presentation" style="position: relative;">β?答案是新的参数可以表示旧参数作为输入的同一族函数,但是新参数有不同的学习动态。在旧参数中,H的均值取决于H下层中参数的复杂关联。在新参数中,γH′+β" role="presentation" style="position: relative;">γH′+β的均值仅由β" role="presentation" style="position: relative;">β确定。新参数很容易通过梯度下降来学习。大多数神经网络层会取ϕ(XW+b)" role="presentation" style="position: relative;">ϕ(XW+b)的形式,其中ϕ" role="presentation" style="position: relative;">ϕ是某个固定的非线性激活函数,如整流线线性变换。自然想到我们应该将批标准化应用于输入X" role="presentation" style="position: relative;">X还是变换后的值XW+b" role="presentation" style="position: relative;">XW+b。更具体地讲,XW+b" role="presentation" style="position: relative;">XW+b应替换为XW" role="presentation" style="position: relative;">XW的标准化形式。偏置项应被忽略,因为参数β" role="presentation" style="position: relative;">β会加入批标准化重参数化,它是冗余的。一层的输入通常是前一层的非线性激活函数(如整流线性函数)的输出。因此,输入的统计量更符合非高斯,而更不服从线性操作的标准化。