第七章 网络优化与正则化
虽然神经网络具有非常强的表达能力,但是当应用神经网络模型到机器学习时依然存在一些难点问题。主要分为两大类:
(1)优化问题:神经网络模型是一个非凸函数,再加上在深度网络中的梯度消失问题,很难进行优化;另外,深度神经网络模型一般参数比较多,训练数据也比较大,会导致训练的效率比较低。
(2)泛化问题:因为神经网络的拟合能力强,反而容易在训练集上产生过拟合。因此在训练深度神经网络时,同时也需要通过一定的正则化方法来改进网络的泛化能力。
网络优化
深度神经网络是一个高度非线性的模型,其风险函数是一个非凸函数,因此风险最小化是一个非凸优化问题,会存在很多局部最优点。
网络优化的难点
网络结构多样性
- 没有通用的优化方法
- 网络的超参数太多
高维变量的非凸优化
低维空间的非凸优化问题主要是存在一些局部最优点。基于梯度下降的优化方法会陷入局部最优点,因此低维空间的非凸优化问题的主要难点是如何选择初始参数和逃离局部最优点。
在高维空间中,非凸优化的难点主要是两个:
-
如何逃离鞍点(鞍点的梯度是0,但是在一些维度上是最高点,在另一些维度上是最低点)。在高维空间中,局部最优点要求在每一维度上都是最低点,这种概率非常低。也就是说高维空间中,大部分梯度为0 的点都是鞍点。基于梯度下降的优化方法会在鞍点附近接近于停滞,同样很难从这些鞍点中逃离。
- 如何避免陷入平坦底部,因为深度神经网络的参数非常多,并且有一定的冗余性,这使得每单个参数对最终损失的影响都比较小,这导致了损失函数在局部最优点附近是一个平坦的区域,称为平坦最小值(Flat Minima)。并且在非常大的神经网络中,大部分的局部最小值是相等的。虽然神经网络有一定概率收敛于比较差的局部最小值,但随着网络规模增加,网络陷入局部最小值的概率大大降低。
目前,深度神经网络的参数学习主要是通过梯度下降法来寻找一组可以最小化结构风险的参数。在具体实现中,梯度下降法可以分为:批量梯度下降、随机梯度下降以及小批量梯度下降三种形式。根据不同的数据量和参数量,可以选择一种具体的实现形式。除了在收敛效果和效率上的差异,这三种方法都存在一些共同的问题,比如1)如何改进优化算法;2)如何初始化参数;3)如何预处理数据等。
优化算法
小批量梯度下降
令f(x; θ) 表示一个深度神经网络,θ 为网络参数,在使用小批量梯度下降进行优化时,每次选取K个训练样本。第t次迭代时损失函数关于参数θ的偏导数为:,其中为可微分的损失函数,K称为批量大小。
第t次更新的梯度gt定义为:
使用梯度下降来更新参数,,其中α>0为学习率。
每次迭代时参数更新的差值Δθt 定义为:
Δθt 和梯度gt 并不需要完全一致。Δθt 为每次迭代时参数的实际更新方向,即θt = θt−1 + Δθt。在标准的小批量梯度下降中,Δθt = −αgt。
从上面公式可以看出,影响小批量梯度下降法的因素有:1)批量大小K;2)学习率α以及3)梯度估计。
批量大小选择
批量大小不影响随机梯度的期望,但是会影响随机梯度的方差。
批量大小越大,随机梯度的方差越小,引入的噪声也越小,训练也越稳定,因此可以设置较大的学习率。而批量大小较小时,需要设置较小的学习率,否则模型会不收敛。学习率通常要随着批量大小的增大而相应地增大。
一个简单有效的方法是线性缩放规则(Linear Scaling Rule):当批量大小增加m倍时,学习率也增加m倍。线性缩放规则往往在批量大小比较小时适用,当批量大小非常大时,线性缩放会使得训练不稳定。
学习率调整
常用的学习率调整方法包括学习率衰减、学习率预热、周期性学习率调整以及一些自适应调整学习率的方法,比如AdaGrad、RMSprop、AdaDelta 等。自适应学习率方法可以针对每个参数设置不同的学习率。
学习率衰减
从经验上看,学习率在一开始要保持大些来保证收敛速度,在收敛到最优点附近时要小些以避免来回震荡。比较简单的学习率调整可以通过学习率衰减(Learning Rate Decay)的方式来实现,也称为学习率退火。
不失一般性,这里的衰减方式设置为按迭代次数进行衰减。假设初始化学习率为α0,在第t 次迭代时的学习率αt。常见的衰减方法有以下几种:
- 分段常数衰减:即每经过T1, T2, · · · , Tm 次迭代将学习率衰减为原来的β1, β2, · · · , βm 倍,其中Tm 和βm < 1 为根据经验设置的超参数。分段常数衰减也称为阶梯衰减(Step Decay)
- 逆时衰减:,其中β为衰减率。
- 指数衰减:,其中β<1为衰减率。
- 自然指数衰减:,其中β为衰减率。
- 余弦衰减:,其中T为总的迭代次数。
学习率预热
为了提高训练稳定性,我们可以在最初几轮迭代时,采用比较小的学习率,等梯度下降到一定程度后再恢复到初始的学习率,这种方法称为学习率预热。
一个常用的学习率预热方法是逐渐预热。假设预热的迭代次数为T′,初始学习率为α0,在预热过程中,每次更新的学习率为:,当预热过程结束,再选择一种学习率衰减方法来逐渐降低学习率。
周期性学习率调整
周期性学习率调整可以使得梯度下降法在优化过程中跳出尖锐的局部极小值,虽然会短期内会损害优化过程,但最终会收敛到更加理想的局部极小值。
循环学习率:即让学习率在一个区间内周期性地增大和缩小。通常可以使用线性缩放来调整学习率,称为三角循环学习率。假设每个循环周期的长度相等都为2ΔT,其中前ΔT 步为学习率线性增大阶段,后ΔT 步为学习率线性缩小阶段。在第t 次迭代时,其所在的循环周期数m为:,第t 次迭代的学习率为,其中分别为第m个周期中学习率的上界和下界。,可以随着m的增大而逐渐降低;b ∈ [0, 1] 的计算为:
带热重启的随机梯度下降:用热重启方式来替代学习率衰减的方法。学习率每间隔一定周期后重新初始化为某个预先设定值,然后逐渐衰减。每次重启后模型参数不是从头开始优化,而是从重启前的参数基础上继续优化。
假设在梯度下降过程中重启M 次,第m次重启在上次重启开始第Tm 个回合后进行,Tm 称为重启周期。在第m次重启之前,采用余弦衰减来降低学习率。第t 次迭代的学习率为:,其中分别为第m个周期中学习率的上界和下界。,可以随着m的增大而逐渐降低;Tcur 为从上次重启之后的回合(Epoch)数。Tcur 可以取小数,比如0.1、0.2 等,这样可以在一个回合内部进行学习率衰减。重启周期Tm 可以随着重启次数逐渐增加,比如Tm = Tm−1 × κ,其中κ ≥ 1 为放大因子。
AdaGrad 算法
在标准的梯度下降法中,每个参数在每次迭代时都使用相同的学习率。由于每个参数的维度上收敛速度都不相同,因此根据不同参数的收敛情况分别设置学习率。
AdaGrad(Adaptive Gradient)算法是借鉴ℓ2 正则化的思想,每次迭代时自适应地调整每个参数的学习率。在第t 次迭代时,先计算每个参数梯度平方的累计值:,其中为按元素乘积。迭代时的梯度。
AdaGrad 算法的参数更新差值为:,其中α 是初始的学习率,ϵ 是为了保持数值稳定性而设置的非常小的常数,一般取值e−7 到e−10。此外,这里的开平方、除、加运算都是按元素进行的操作。
在AdaGrad 算法中,如果某个参数的偏导数累积比较大,其学习率相对较小;相反,如果其偏导数累积较小,其学习率相对较大。但整体是随着迭代次数的增加,学习率逐渐缩小。
AdaGrad 算法的缺点是在经过一定次数的迭代依然没有找到最优点时,由于这时的学习率已经非常小,很难再继续找到最优点。
RMSprop算法
是一种自适应学习率的方法,可以在有些情况下避免AdaGrad 算法中学习率不断单调下降以至于过早衰减的缺点。
RMSprop算法首先计算每次迭代梯度gt 平方的指数衰减移动平均,
其中β 为衰减率,一般取值为0.9。
RMSprop算法的参数更新差值为:,其中α 是初始的学习率。
从上式可以看出,RMSprop 算法和AdaGrad 算法的区别在于Gt 的计算由累积方式变成了指数衰减移动平均。在迭代过程中,每个参数的学习率并不是呈衰减趋势,既可以变小也可以变大。
AdaDelta 算法
也是AdaGrad算法的一个改进。和RMSprop算法类似,AdaDelta 算法通过梯度平方的指数衰减移动平均来调整学习率。此外,AdaDelta 算法还引入了每次参数更新差Δθ 的平方的指数衰减权移动平均。
第t 次迭代时,每次参数更新差的平方的指数衰减权移动平均为:
其中β1 为衰减率。此时Δθt 还未知,因此只能计算到ΔXt−1。
AdaDelta 算法的参数更新差值为:,其中Gt 的计算方式和RMSprop 算法一样,为参数更新差Δθ 的指数衰减权移动平均。在一定程度上平抑了学习率的波动。
梯度估计修正
动量法
动量(Momentum)是模拟物理中的概念,是用之前积累动量来替代真正的梯度。每次迭代的梯度可以看作是加速度。
在第t 次迭代时,计算负梯度的“加权移动平均”作为参数的更新方向,,其中为动量因子,通常设为0.9,α为学习率。
根据梯度方向是否一致,可以保证在初始时加速度快,在迭代后期加速度小。
Nesterov 加速梯度
是一种对动量法的改进。在动量法中,实际的参数更新方向Δθt 为上一步的参数更新方向Δθt−1 和当前梯度的反方向−gt 的叠加。这样,Δθt 可以被拆分为两步进行,先根据Δθt−1更新一次得到参数,再用−gt 进行更新。
其中梯度gt 为点θt−1 上的梯度,因此在第二步更新中有些不太合理。更合理的更新方向应该为上的梯度。
这样,合并后的更新方向为:,其中表示损失函数在点上的偏导数。
Adam算法
自适应动量估计(Adam)算法可以看作是动量法和RMSprop 算法的结合,不但使用动量作为参数更
新方向,而且可以自适应调整学习率。
Adam 算法一方面计算梯度平方 的指数加权平均(和RMSprop 算法类似),另一方面计算梯度的指数加权平均(和动量法类似)。
Mt 可以看作是梯度的均值(一阶矩),Gt 可以看作是梯度的未减去均值的方差(二阶矩)。
假设M0 = 0,G0 = 0,那么在迭代初期Mt 和Gt 的值会比真实的均值和方差要小。特别是当β1 和β2 都接近于1 时,偏差会很大。因此,需要对偏差进行修正。
Adam 算法是RMSProp 算法与动量法的结合,因此一种自然的Adam 算法的改进方法是引入Nesterov 加速梯度,称为Nadam算法。
梯度截断
当梯度的模大于一定阈值时,就对梯度进行截断,称为梯度截断。为了把梯度的模限定在一个区间。
按值截断:大于或小于边界值,就设为边界值。
按模截断:是将梯度的模截断到一个给定的截断阈值b。如果∥gt∥2 ≤ b,保持gt 不变。如果∥gt∥2 > b,令
优化算法小结
几种优化方法大体上可以分为两类:一是调整学习率,使得优化更稳定;二是梯度估计修正,优化训练速度。
这些优化算法可以使用下面公式来统一描述概括:
参数初始化
在感知器和logistic 回归的训练中,参数可以全部初始化为0。
但在神经网络的训练中不可以。因为如果参数都为0,在第一遍前向计算时,所有的隐层神经元的激活值都相同。这样会导致深层神经元没有区分性。这种现象也称为对称权重现象。为了打破这个平衡,比较好的方式是对每个参数都随机初始化。同时,为了高效地训练神经网络,给参数选取一个合适的随机初始化区间是非常重要的。
经常使用的初始化方法有两种:高斯分布初始化、均匀分布初始化。
Xavier 初始化
当网络使用Logistic 激活函数时,Xavier 初始化可以根据每层的神经元数量来自动计算初始化参数的方差。
假设第l 层神经元的激活函数为Logistic 函数,对于第l − 1 到l 层的权重参数区间r 可以设置为:
对于Tanh 函数,r 可以设置为:
假设第l 层的一个隐藏层神经元zl,其接收前一层的nl−1 个神经元的输出ai(l-1),1 ≤ i ≤ n(l-1),则:,为了避免初始化参数使得激活值变得饱和,就需要让zl处于激活函数的线性区间,也就是其绝对值比较小。这时该神经元的激活值。
假设的均值都为0,并且相互独立,则的均值为:
的方差为:
也就是说,输入信号的方差在经过该神经元后被放大或缩小了倍。为了使得在经过多层网络后,信号不被过分放大或过分减弱,需要尽可能保持每个神经元的输入和输出的方差一致。也就是让倍数=1。即:,同理,为了使得在反向传播中,误差信号也不被放大或缩小,也需要让的方差保持为,作为折中,同时考虑信号在前向和反向传播中都不被放大或缩小,可以设置。
在计算出参数的理想方差后,可以通过高斯分布或均匀分布来随机初始化参数。
高斯分布初始化:连接权重可以按的高斯分布进行初始化。
均匀分布初始化:方差计算公式为:,若采用区间为的均匀分布来初始化,并满足,则。
He 初始化
相当于Xavier 初始化中只考虑前向传播的情况。
数据预处理
对于基于相似度比较的机器学习方法,必须先对样本进行预处理,将各个维度的特征归一化到同
一个取值区间,并且消除不同特征之间的相关性,才能获得比较理想的结果。
以下是几种在神经网络中经常使用的归一化方法。
缩放归一化:是一种非常简单的归一化方法,通过缩放将每一个特征
的取值范围归一到[0, 1] 或[−1, 1] 之间。假设有N 个样本,对于每一维特征x,,其中min(x) 和max(x) 分别是特征x 在所有样本上的最小值和最大值。
标准归一化:也叫z-score 归一化,来源于统计上的标准分数。将每一个维特征都调整为均值为0,方差为1。假设有N 个样本,对于每一维特征x,我们先计算它的均值和方差,然后,将特征x(n) 减去均值,并除以标准差,得到新的特征值。这里σ 不能为0。如果方差为0,说明这一维特征没有任务区分性,可以直接删掉。
白化:是一种重要的预处理方法,用来降低输入数据特征之间的冗余性。输入数据经过白化处理后,特征之间相关性较低,并且所有特征具有相同的方差。白化的一个主要实现方式是使用主成分分析。
逐层归一化
浅层发生的小偏移,会导致深层发生大的偏移(蝴蝶效应)。
从机器学习角度来看,如果某个神经层的输入分布发生了改变,那么其参数需要重新学习,这种现象叫做内部协变量偏移。
协变量是一个统计学概念,是可能影响预测结果的统计变量。在机器学习中,协变量可以看作是输入。一般的机器学习算法都要求输入在训练集和测试集上的分布是相似的。如果不满足这个假设,在训练集上学习到的模型在测试集上的表现会比较差。
为了解决内部协变量偏移问题,就要使得每一个神经层的输入的分布在训练过程中保持一致。最简单直接的方法就是对每一个神经层都进行归一化操作,使其分布保存稳定。
批量归一化(BN)
BN方法是一种有效的逐层归一化方法,可以对神经网络中任意的中间层进行归一化操作。
对于一个深度神经网络,令第l 层的净输入为z(l),神经元的输出为a(l),即:
。
为了减少内部协变量偏移问题,就要使得净输入z(l) 的分布一致,比如都归一化到标准正态分布。虽然归一化操作可以应用在输入a(l−1) 上,但其分布性质不如z(l) 稳定。因此,在实践中归一化操作一般应用仿射变换之后,激活函数之前。
为了提高归一化效率,一般使用标准归一化,将净输入z(l) 的每一维都归一到标准正态分布。
因为目前主要的训练方法是基于小批量的随机梯度下降法,所以准确地计算z(l) 的期望和方差是不可行的。因此,z(l) 的期望和方差通常用当前小批量样本集的均值和方差近似估计。
给定一个包含K 个样本的小批量样本集合,第l 层神经元的净输入 的均值和方差为:
对净输入z(l) 的标准归一化会使得其取值集中到0 附近,如果使用sigmoid型激活函数时,这个取值区间刚好是接近线性变换的区间,减弱了神经网络的非线性性质。因此,为了使得归一化不对网络的表示能力造成负面影响,可以通过一个附加的缩放和平移变换改变取值区间。
其中γ 和β 分别代表缩放和平移的参数向量。从最保守的角度考虑,可以通过标准归一化的逆变换来使得归一化后的变量可以被还原为原来的值。当。
加入归一化操作后:
其中因为批量归一化本身具有平移变换,所以仿射变换不再需要偏置参数。
层归一化
批量归一化是对一个中间层的单个神经元进行归一化操作,因此要求小批量样本的数量不能太小,否则难以计算单个神经元的统计信息。此外,如果一个神经元的净输入的分布在神经网络中是动态变化的,比如循环神经网络,那么就无法应用批量归一化操作
层归一化是和批量归一化非常类似的方法。和批量归一化不同的是,层归一化是对一个中间层的所有神经元进行归一化。
对于一个深度神经网络,令第l 层神经元的净输入为z(l),其均值和方差为:
循环神经网络中的层归一化:
层归一化的循环神经网络,可以有效地缓解循环神经网络的梯度爆炸或消失。
其它归一化方法
权重归一化
是对神经网络的连接权重进行归一化,通过再参数化方法,将连接权重分解为长度和方向两种参数。假设第l 层神经元,我们将W再参数化为:,其中表示权重W 的第i 行,为神经元数量。新引入的参数为标量,和 维数相同。
由于在神经网络中权重经常是共享的,权重数量往往比神经元数量要少,因此权重归一化的开销会比较小。
局部响应归一化
是一种受生物学启发的归一化方法,通常用在基于卷积的图像处理上。
超参数优化
常见的超参数有以下三类:
- 网络结构,包括神经元之间的连接关系、层数、每层的神经元数量、激活函数的类型等。
- 优化参数,包括优化方法、学习率、小批量的样本数量等。
- 正则化系数。
超参数优化主要存在两方面的困难。(1)超参数优化是一个组合优化问题,无法像一般参数那样通过梯度下降方法来优化,也没有一种通用有效的优化方法。(2)评估一组超参数配置的时间代价非常高,从而导致一些优化方法(比如演化算法)在超参数优化中难以应用。
对于超参数的配置,比较简单的方法有网格搜索、随机搜索、贝叶斯优化、动态资源分配和神经架构搜索。
网格搜索
通过尝试所有超参数的组合来寻址合适一组超参数配置。对于连续的超参数,需要根据超参数自身的特点进行离散化。
随机搜索
是针对不同超参数对模型性能的影响差异性,对网格搜索的改进。随机搜索在实践中更容易实现,一般会比网格搜索更加有效。
网格搜索和随机搜索都没有利用不同超参数组合之间的相关性,即如果模型的超参数组合比较类似,其模型性能也是比较接近的。因此这两种搜索方式一般都比较低效,都不是自适应的。
贝叶斯优化
是一种自适应的超参数优化方法,根据当前已经试验的超参数组合,来预测下一个可能带来最大收益的组合。
时序模型优化:一种比较常用的贝叶斯优化方法。
贝叶斯优化过程是根据已有的N 组试验结果来建模高斯过程,并计算f(x)的后验分布。
为了使后验分布尽可能接近真实分布,就需要对样本空间进行足够多的采样,但是超参数优化中每一个样本的生成成本很高,需要用尽可能少的样本达到更好的效果,这可以通过定义一个收益函数来判断一个样本是否能够给建模提供更多的收益。收益越大,其修正的高斯过程会越接近目标函数的真实分布。
收益函数的定义有很多种方式。一个常用的是期望改善函数:假设是当前已有样本中的最优值,期望改善函数为:
除了期望改善函数之外,收益函数还有其它定义形式,比如改善概率、高斯过程置信上界等。
动态资源分配
动态资源分配的一种有效方法是逐次减半方法,将超参数优化看作是一种非随机的最优臂问题(,即在给定有限的机会次数下,如何玩这些赌博机并找到收益最大的臂)。假设要尝试N 组
超参数配置,总共可利用的资源预算(摇臂的次数)为B,我们可以通过轮逐次减半的方法来选取最优的配置。其中,尝试的超参数配置数量N 十分关键。
神经架构搜索
是一个新的比较有前景的研究方向,通过神经网络来自动实现网络架构的设计。一个神经网络的架构可以用一个变长的字符串来描述。利用元学习的思想,神经架构搜索利用一个控制器来生成另一个子网络的架构描述。控制器可以由一个循环神经网络来实现。控制器的训练可以通过强化学习来完成,其奖励信号为生成的子网络在开发集上的准确率。
网络正则化
正则化是一类通过限制模型复杂度,从而避免过拟合,提高泛化能力的方法,比如引入约束、增加先验、提前停止等。
在深度学习中,仅仅用ℓ1 和ℓ2 正则化是不够的,还会用到其他的正则化方法,比如数据增强、提前停止、丢弃法、集成法等。
ℓ1 和ℓ2 正则化
优化问题可以写为:
从上图可以看出,ℓ1 范数的约束通常会使得最优解位于坐标轴上,从而使得最终的参数为稀疏性向量。此外,ℓ1 范数在零点不可导,因此经常用来近似。
一种折中的正则化方法是弹性网络正则化:同时加入ℓ1 和ℓ2 正则化:
权重衰减
权重衰减也是一种有效的正则化方法,在每次参数更新时,引入一个衰减系数:。
提前停止
当验证集上的错误率不再下降,就停止迭代。
丢弃法
当训练一个深度神经网络时,可以随机丢弃一部分神经元(同时丢弃其对应的连接边)来避免过拟合。每次选择丢弃的神经元是随机的。最简单的方法是设置一个固定的概率p。对每一个神经元都以概率p 来判定要不要保留。
对于一个神经层,我们可以引入一个丢弃函数mask(·),使得。丢弃函数d(·) 的定义为:
丢弃法一般是针对神经元进行随机丢弃,但是也可以扩展到对神经元之间的连接进行随机丢弃,或每一层进行随机丢弃。
集成学习的解释:每做一次丢弃,相当于从原始的网络中采样得到一个子网络。如果一个神经网络有n个神经元,那么总共可以采样出2n 个子网络。每次迭代都相当于训练一个不同的子网络,这些子网络都共享原始网络的参数。那么,最终的网络可以近似看作是集成了指数级个不同网络的组合模型。
贝叶斯学习的解释:丢弃法也可以解释为一种贝叶斯学习的近似。用y = f(x; θ) 来表示要学习的神经网络,贝叶斯学习是假设参数θ 为随机向量,并且先验分布为q(θ),贝叶斯方法的预测为:
其中为第m次应用丢弃方法后的网络,其参数θm 为对全部参数θ 的一次采样。
循环神经网络上的丢弃法
一种简单的方法是对非时间维度的连接(即非循环连接)进行随机丢失,如图所示,虚线边表示进行随机丢弃,不同的颜色表示不同的丢弃掩码。
对循环神经网络上使用丢弃法时,需要对参数矩阵的每个元素进行随机丢弃,并在所有时刻都使用相同的丢弃掩码。这种方法称为变分丢弃法。
数据增强
通过数据增强来增加数据量,提高模型鲁棒性,避免过拟合。目前,数据增强还主要应用在图像数据上,在文本等其它类型的数据上还没有太好的方法。
标签平滑
可以给样本的标签引入一定的噪声来避免过拟合。
一个样本x的标签一般用onehot 向量表示:,这种标签可以看作是硬目标。
如果使用softmax 分类器并使用交叉熵损失函数,最小化损失函数会使得正确类和其它类的权重差异变得很大。根据softmax 函数的性质可知,如果要使得某一类的输出概率接近于1,其未归一化的得分需要远大于其它类的得分,可能会导致其权重越来越大,并导致过拟合。此外,如果样本标签是错误的,会导致更严重的过拟合现象。为了改善这种情况,我们可以引入一个噪声对标签进行平滑,即假设样本以ϵ 的概率为其它类。平滑后的标签为:,其中K 为标签数量,这种标签可以看作是软目标。
标签平滑可以 避免模型的输出过拟合到硬目标上,并且通常不会损害其分类能力。
上面这种做法没有考虑标签之间的相关性。一种更好的做法是按照类别相关性来赋予其它标签不同的概
率。比如先训练另外一个更复杂(一般为多个网络的集成)的教师网络,并使用大网络的输出作为软目标来训练学生网络。这种方法也称为知识精炼