[神经网络与深度学习][7][网络优化与正则化]

第7章 网络优化与正则化

任何数学技巧都不能弥补信息的缺失.——科尼利厄斯·兰佐斯

应用神经网络模型到机器学习时依然存在一些难点问题.主要分为两大类:

  1. 优化问题
    1. 首先,神经网络的损失函数是一个非凸函数,找到全局最优解通常比较困难
    2. 其次,深度神经网络的参数通常非常训练数据也比较大,因此也无法使用计算代价很高的二阶优化方法
    3. 此外,深度神经网络存在梯度消失梯度爆炸问题,导致基于梯度的优化方法经常失效.
  2. 泛化问题
    1. 由于深度神经网络的复杂度比较高,并且拟合能力很强,很容易训练集上产生过拟合

7.1 网络优化

网络优化是指寻找一个神经网络模型来使得经验(或结构)风险最小化的过程,包括模型选择以及参数学习

7.1.1 网络结构多样性

网络结构的多样性表现在

  1. 神经网络的种类非常多,比如卷积网络、循环网络、图网络等.
  2. 不同网络的结构也非常不同,有些比较深,有些比较宽.
  3. 不同参数在网络中的作用也有很大的差异

由于网络结构的多样性,我们很难找到一种通用的优化方法.不同优化方法在不同网络结构上的表现也有比较大的差异.

7.1.2 高维变量的非凸优化

低维空间的非凸优化问题主要是存在一些局部最优点.基于梯度下降的优化方法会陷入局部最优点,因此在低维空间中非凸优化的主要难点是如何选择初始化参数和逃离局部最优点.但是高维空间是不同的。

鞍点

高维空间中,非凸优化的难点并不在于如何逃离局部最优点,,而是如何逃离鞍点。鞍点的梯度是0,但是在一些维度上是最高点,在另一些维度上是最低点,如下图所示.

在高维空间中,局部最小值(Local Minima)要求在每一维度上都是最低点,这种概率非常低.也就是说,在高维空间中大部分驻点都是鞍点

基于梯度下降的优化方法会在鞍点附近接近于停滞,很难从这些鞍点中逃离.因此,随机梯度下降对于高维空间中的非凸优化问题十分重要,通过在梯度方向上引入随机性,可以有效地逃离鞍点

平坦最小值

深度神经网络的参数非常多,并且有一定的冗余性,这使得每单个参数对最终损失的影响都比较小,因此会导致损失函数在局部最小解附近通常是一个平坦的区域,称为平坦最小值.图7.2给出了平坦最小值和尖锐最小值(Sharp Minima)的示例.

  • 在一个平坦最小值的邻域内,所有点对应的训练损失都比较接近,表明我们在训练神经网络时,不需要精确地找到一个局部最小解,只要在一个局部最小解的邻域内就足够了.
  • 平坦最小值通常被认为和模型泛化能力有一定的关系.一般而言,当一个模型收敛到一个平坦的局部最小值时,其鲁棒性会更好,即微小的参数变动不会剧烈影响模型能力;而当一个模型收敛到一个尖锐的局部最小值时,其鲁棒性也会比较差.
局部最小解的等价性

在非常大的神经网络中,大部分的局部最小解等价的,它们在测试集上性能都比较相似.此外,局部最小解对应的训练损失都可能非常接近于全局最小解对应的训练损失[

在训练神经网络时,我们通常没有必要全局最小值,这反而可能导致过拟合

7.1.3 神经网络优化的改善方法

改善神经网络优化的目标是

  1. 找到更好的局部最小值
  2. 提高优化效率

目前比较有效的经验性改善方法通常分为以下几个方面:

  1. 使用更有效的优化算法提高梯度下降优化方法的效率稳定性,比如动态学习率调整、梯度估计修正等.
  2. 使用更好的参数初始化方法、数据预处理方法来提高优化效率.
  3. 修改网络结构来得到更好的优化地形(Optimization Landscape), 比如使用ReLU 激活函数、残差连接、逐层归一化等.
  4. 使用更好的超参数优化方法

优化地形指在高维空间中损失函数的曲面形状.好的优化地形通常比较平滑.

7.2 优化算法

本节介绍一些在训练神经网络时常用的优化算法.这些优化算法大体上可以分为两类:

  1. 调整学习率,使得优化更稳定
  2. 梯度估计修正优化训练速度

7.2.1 小批量梯度下降

如果在梯度下降时,每次迭代都要计算整个训练数据上的梯度,这就需要比较多的计算资源。因此,在训练深度神经网络时,经常使用小批量梯度下降法(Mini-Batch Gradient Descent).

f(x;θ)f(\vec x; \theta)表示一个深度神经网络,θ\theta为网络参数,在使用小批量梯度下降进行优化时,每次选取KK个训练样本St={(x(k),y(k))}k=1KS_t = \{(\vec x^{(k)}, \vec y^{(k)})\}_{k=1}^K.第𝑡 次迭代(Iteration)时损失函数关于参数θ\theta的偏导数为

gt(θ)=1K(x,y)StδL(y,f(x;θ))δθg_t(\theta) = \frac 1K \sum _{(\vec x, \vec y) \in S_t} \frac {\delta L(\vec y, f(\vec x; \theta))}{\delta \theta}

  • 其中L(.)L(.)为可微分的损失函数
  • KK称为批量大小Batch Size).

tt次更新的梯度gt\boldsymbol g_t定义为

gtgt(θt1)\boldsymbol g_t \equiv g_t(\theta_{t-1})

使用梯度下降来更新参数

θtθt1αgt\theta_t \leftarrow \theta_{t-1} - \alpha g_t

每次迭代时参数更新的差值定义为

Δθtθtθt1\Delta \theta_t \equiv \theta_t - \theta_{t-1}

Δθt\Delta \theta_t和梯度gtg_t不需要完全一致.Δ𝜃𝑡 为每次迭代时参数的实际更新方向,gtg_t是我们的理论计算结果。在标准的小批量梯度下降中,Δθt=αgt\Delta \theta_t = - \alpha g_t

从上面公式可以看出,影响小批量梯度下降法的主要因素有:

  1. 批量大小KK
  2. 学习率α\alpha
  3. 梯度估计

下面三小节,我们分别从这三个方面来介绍在神经网络优化中常用的算法.

7.2.2 批量大小选择

批量大小不影响随机梯度的期望,但是会影响随机梯度的方差批量大小越大,随机梯度的方差越小,引入的噪声也越小,训练也越稳定,因此可以设置较大的学习率.而批量大小较小时,需要设置较小的学习率,否则模型会不收敛.学习率通常要随着批量大小的增大而相应地增大

下面给出回合和迭代的概念

迭代:每一次小批量更新为一次迭代

回合:所有训练集的样本更新一遍为一个回合

两者的关系为

1(Epoch)=(NK×(Iteration))1回合(Epoch) = (\frac {训练样本的数量N} {批量大小K} \times 迭代(Iteration))

批量大小和模型的泛化能力也有一定的关系.通过实验发现:批量越大,越有可能收敛到尖锐最小值;批量越小,越有可能收敛到
平坦最小值.

7.2.3 学习率调整

在梯度下降法中,学习率α\alpha的取值非常关键,如果过大不会收敛,如果过小收敛速度太慢

常用的学习率调整方法包括

  1. 学习率衰减
  2. 学习率预热
  3. 周期性学习率调整
  4. 自适应调整学习率的方法
7.2.3.1 学习率衰减

从经验上看,学习率在一开始要保持大些来保证收敛速度,在收敛到最优点附近时要小些以避免来回振荡.比较简单的学习率调整可以通过学习率衰减(Learning Rate Decay)的方式来实现。

image-20201027121822743

下图给出了不同衰减方法的示例

7.2.3.2 学习率预热

在小批量梯度下降法中,当批量大小的设置比较大时,通常需要比较大的学习率.但在刚开始训练时,由于参数是随机初始化的梯度往往也比较大再加上比较大的初始学习率,会使得训练不稳定

为了提高训练稳定性,我们可以在最初几轮迭代时采用比较小的学习率,等梯度下降到一定程度后再恢复到初始的学习率,这种方法称为学习率预热(Learning Rate Warmup).

7.2.3.3 周期性学习率调整

为了使得梯度下降法能够逃离鞍点或尖锐最小值,一种经验性的方式是在训练过程中周期性地增大学习率.当参数处于尖锐最小值附近时,增大学习率有助于逃离尖锐最小值;当参数处于平坦最小值附近时,增大学习率依然有可能在该平坦最小值的吸引域(Basin of Attraction)内.

循环学习率:一种简单的方法是使用循环学习率,即让学习率在一个区间内周期性地增大和缩小.

带热重启的随机梯度下降学习率每间隔一定周期后重新初始化为某个预先设定值然后逐渐衰减

7.2.3.4 AdaGrad 算法

标准的梯度下降法中,每个参数在每次迭代时都使用相同的学习率.但是由于每个参数收敛速度都不相同,因此应该根据不同参数的收敛情况 分别 设置学习率

AdaGrad 算法,每次迭代时自适应调整每个参数学习率

在第tt次迭代时,先计算每个参数梯度平方的累计值

Gt=τ=1tgτgτG_t = \sum ^t _{\tau = 1} \boldsymbol g_{\tau} \odot \boldsymbol g_{\tau}

  • \odot按元素乘积
  • gτRθ\boldsymbol g_{\tau} \in R^{|\theta|}τ\tau次迭代时的梯度

AdaGrad 算法的参数更新差值为

Δθt=αGt+ϵgt\Delta \theta_t = - \frac {\alpha} {\sqrt {G_t + \epsilon}} \odot \boldsymbol g_t

  • α\alpha是初始的学习率
  • ϵ\epsilon是为了保持数值稳定性而设置的非常小的常数,一般取值e7e^{−7}e10e^{−10}
  • 此外,这里的开平方加运算都是按元素进行的操作.(因为最后的计算结果是一个向量)

在AdaGrad 算法中

  • 如果某个参数的偏导数累积比较大,其学习率相对较小
  • 相反,如果其偏导数累积较小,其学习率相对较大.
  • 但整体是随着迭代次数的增加学习率逐渐缩小

AdaGrad 算法的缺点是在经过一定次数的迭代依然没有找到最优点时,由于这时的学习率已经非常小很难再继续找到最优点

7.2.3.5 RMSprop 算法

RMSprop 算法可以在有些情况下避免AdaGrad 算法中学习率不断单调下降以至于过早衰减的缺点.

RMSprop 算法使用下面的方式来计算GtG_t

Gt=βGt1=(1β)gtgt=(1β)τ=1tβtτgtgtG_t = \beta G_{t-1} = (1 - \beta) \boldsymbol g_t \odot \boldsymbol g_t = (1 - \beta)\sum ^t _{\tau = 1} \beta^{t-\tau} \boldsymbol g_t \odot \boldsymbol g_t

  • β\beta是衰减率,一般取0.90.9
  • 其中βtτ\beta^{t-\tau}tτt-\tau不是上标,它是次方的意思
  • 也就是说,离当前迭代越近的迭代对GtG_t影响越大,而之前的迭代影响相对较小

从上式可以看出,RMSProp 算法和AdaGrad 算法的区别在于**GtG_t的计算累积方式变成了指数衰减移动平均**.在迭代过程中,每个参数的学习率并不是呈衰减趋势,既可以变小也可以变大

7.2.3.6 AdaDelta 算法

AdaDelta 算法在RMSProp算法的基础上,将初始学习率α\alpha改为了动态计算的ΔXt12\sqrt{\Delta X^2_{t-1}}

AdaDelta算法引入了每次**Δθ\Delta \theta的平方指数衰减权移动平均**.第tt次迭代时,参数更新差值Δθ\Delta \theta的平方的指数衰减权移动平均为

ΔXt12=β1ΔXt22+(1β1)Δθt1Δθt1\Delta X^2_{t-1} = \beta_1\Delta X^2_{t-2} + (1-\beta_1)\Delta \theta_{t-1} \odot \Delta \theta_{t-1}

AdaDelta 算法的参数更新差值为

Δθt=ΔXt22+ϵGt+ϵgt\Delta \theta_t = - \frac {\sqrt{\Delta X^2_{t-2} + \epsilon}} {\sqrt {G_t + \epsilon}} \odot \boldsymbol g_t

  • 其中GtG_t的计算方式和RMSprop 算法一样

这种算法可以在一定程度上平抑学习率的波动

7.2.4 梯度估计修正(Gradient Estimation)

除了调整学习率之外,还可以进行梯度估计(Gradient Estimation)的修正.随机梯度下降方法中每次迭代的梯度估计和整个训练集上的最优梯度并不一致,具有一定的随机性. 一种有效地缓解梯度估计随机性的方式是通过使用最近一段时间内的平均梯度代替当前时刻的随机梯度来作为参数更新的方向,从而提高优化速度.

7.2.4.1 动量法

动量法(Momentum Method)是用之前积累历史梯度来替代真正的梯度。

Δθ=ρΔθt1αgt=ατ=1tρtτgτ\Delta \theta = \rho \Delta \theta_{t-1} - \alpha \boldsymbol g_t = - \alpha \sum ^t _{\tau = 1} \rho^{t-\tau} \boldsymbol g_{\tau}

  • 其中ρ\rho动量因子,通常设为0.9,ρtτ\rho^{t-\tau}代表的是ρ\rhotτt-\tau次方
  • α\alpha学习率

这样,每个参数的实际更新差值取决于最近一段时间内梯度的加权平均值.

  • 当某个参数在最近一段时间内的梯度方向不一致时,其真实的参数更新幅度变小
  • 相反,当在最近一段时间内的梯度方向都一致时,其真实的参数更新幅度变大,起到加速作用
  • 一般而言,在迭代初期,梯度方向都比较一致,动量法会起到加速作用可以更快地到达最优点
  • 在迭代后期,梯度方向会不一致,在收敛值附近振荡,动量法会起到减速作用增加稳定性
  • 从某种角度来说,当前梯度叠加上部分的上次梯度,一定程度上可以近似看作二阶梯度
7.2.4.2 Nesterov 加速梯度

Nesterov 加速梯度是对动量法的一种优化。

在动量法中,Δθ=ρΔθt1αgt=ρΔθt1αgt(θt1)\Delta \theta = \rho \Delta \theta_{t-1} - \alpha \boldsymbol g_t = \rho \Delta \theta_{t-1} - \alpha \boldsymbol g_t(\theta_{t-1}),相当于在θt1\theta_{t-1}这个点计算了梯度。然而如下图所示,实际上在θt1+ρΔθt1\theta_{t-1} + \rho \Delta \theta_{t-1}处计算梯度更恰当。这就是Nesterov算法的优化思想。

优化后的Δθ\Delta \theta

Δθ=ρΔθt1αgt(θt1+ρΔθt1)\Delta \theta = \rho \Delta \theta_{t-1} - \alpha \boldsymbol g_t(\theta_{t-1} + \rho \Delta \theta_{t-1})

  • 其中gt(θt1+ρΔθt1)\boldsymbol g_t(\theta_{t-1} + \rho \Delta \theta_{t-1}),表示损失函数在点θt1+ρΔθt1\theta_{t-1} + \rho \Delta \theta_{t-1}上的偏导数

7.2.4.3 Adam 算法

Adam算法可以看作动量法和RMSprop 算法的结合,不但使用动量法作为参数更新方向,而且可以使用RMSprop来自适应调整学习率.

Adam 算法,一方面计算梯度gt\boldsymbol g_t指数加权平均MtM_t(和动量法类似),一方面计算梯度平方gt2\boldsymbol g_t^2指数加权平均GtG_t(和RMSprop 算法类
似)

Mt=β1Mt1+(1β1)gt,M_t = \beta_1 M_{t−1} + (1 − \beta_1)\boldsymbol g_t,

Gt=β2Gt1+(1β2)gtgtG_t = \beta_2 G_{t-1} + (1 - \beta_2) \boldsymbol g_t \odot \boldsymbol g_t

  • 其中β1\beta_1β2\beta_2 分别为两个移动平均的衰减率
  • 通常取值为β1=0.9\beta_1 = 0.9, β2=0.99\beta_2 = 0.99

然后我们将这两个平均进行标准化

M^t=Mt1β1t\hat M_t = \frac {M_t} {1 - \beta^t_1}

G^t=Gt1β2t\hat G_t = \frac {G_t} {1 - \beta^t_2}

Adam 算法的参数更新差值为

Δθ=αG^t+ϵM^t\Delta \theta = \frac \alpha {\sqrt {\hat G_t + \epsilon}} \hat M_t

7.2.4.4 梯度截断

在基于梯度下降的优化过程中,如果梯度突然增大,用大的梯度更新参数反而会导致其远离最优点(越过去了).为了避免这种情况,当梯度的 大于一定阈值时,就对梯度进行截断,称为梯度截断(Gradient Clipping)

梯度截断是一种比较简单的启发式方法,把梯度的模限定在一个区间,当梯度的模小于或大于这个区间时就进行截断

有两种梯度截断方法

按值截断:在第tt次迭代时,梯度为gt\boldsymbol g_t,给定一个区间[a,b][a, b],如果一个参数的梯度小于aa时,就将其设为aa;如果大于bb时,就将其设为bb

gt=max(min(gt,b),a)\boldsymbol g_t = max(min(\boldsymbol g_t, b), a)

按模截断:按模截断是将梯度的模截断到一个给定的截断阈值bb,如果gt2b||\boldsymbol g_t||^2 \leq b,保持gt\boldsymbol g_t不变.如果gt2>b||\boldsymbol g_t||^2 > b,令gt=bgtgt\boldsymbol g_t = \frac b {||\boldsymbol g_t||}\boldsymbol g_t截断阈值bb是一个超参数,也可以根据一段时间内的平均梯度来自动调整.

7.2.5 优化算法小结

本节介绍的几种优化方法大体上可以分为两类:

  1. 调整学习率,使得优化更稳定;
  2. 梯度估计修正,优化训练速度.

这些优化算法可以使用下面公式来统一描述概括

Δθt=αtGt+ϵMt\Delta \theta_t = - \frac {\alpha_t} {\sqrt {G_t + \epsilon}}{M_t}

Gt=ψ(g1,...,gt)G_t = \psi(\boldsymbol g_1, ..., \boldsymbol g_t)

Mt=ϕ(g1,...,gt)M_t = \phi(\boldsymbol g_1, ... , \boldsymbol g_t)

  • 其中gt\boldsymbol g_t是第tt步的梯度
  • αt\alpha_t是第tt步的学习率,可以进行衰减,也可以不变;
  • ψ(.)\psi(.)学习率缩放函数,可以取1或历史梯度的模的移动平均;
  • ϕ(.)\phi(.)优化后的参数更新方向,可以取当前的梯度gt\boldsymbol g_t或历史梯度的移动平均.

表7.1汇总了本节介绍的几种神经网络常用优化算法.

图7.8给出了这几种优化方法在MNIST 数据集上收敛性的比较(学习率为0.001,批量大小为128)

7.3 参数初始化

参数初始化的方式通常有以下三种:

  1. 预训练初始化:不同的参数初始值会收敛到不同的局部最优解.虽然这些局部最优解在训练集上的损失比较接近,但是它们的泛化能力差异很大.一个好的初始值会使得网络收敛到一个泛化能力高局部最优解。通常情况下,一个已经在大规模数据上训练过的模型可以提供一个好的参数初始值,这种初始化方法称为预训练初始化(Pre-trained Initialization)
  2. 随机初始化:在线性模型的训练(比如感知器和Logistic 回归)中,我们一般将参数全部初始化为0.但是这在神经网络的训练中会存在一些问题.因为如果参数都为0,在第一遍前向计算时,所有的隐藏层神经元的激活值都相同;在反向传播时,所有权重的更新也都相同,这样会导致隐藏层神经元没有区分性.这种现象也称为对称权重现象.为了打破这个平衡,比较好的方式是对每个参数都随机初始化(Random Initialization),使得不同神经元之间的区分性更好.
  3. 固定值初始化:对于一些特殊的参数,我们可以根据经验用一个特殊的固定值来进行初始化.比如偏置(Bias)通常用0 来初始化

虽然预训练初始化通常具有更好的收敛性和泛化性,但是灵活性不够不能在目标任务上任意地调整网络结构.因此,好的随机初始化方法对训练神经网络模型来说依然十分重要

这里我们介绍三类常用的随机初始化方法:

  • 基于固定方差的参数初始化
  • 基于方差缩放的参数初始化
  • 正交初始化方法

7.3.1 基于固定方差的参数初始化

一种最简单的随机初始化方法是从一个固定均值方差的分布中采样来生成参数的初始值.

通常有两种

  1. 高斯分布初始化:N(0,σ2)N(0, \sigma^2)
  2. 均匀分布初始化

在基于固定方差的随机初始化方法中,比较关键的是如何设置方差

  1. 如果参数范围取的太小
    1. 一是会导致神经元的输出过小,经过多层之后信号就慢慢消失了;
    2. 二是还会使得Sigmoid 型激活函数丢失非线性的能力.以Sigmoid 型函数为例,在0 附近基本上是近似线性的.这样多层神经网络的优势也就不存在了.
  2. 如果参数范围取的太大,会导致输入状态过大.对于Sigmoid 型激活函数来说,激活值变得饱和,梯度接近于0,从而导致梯度消失问题.

为了降低固定方差对网络性能以及优化效率的影响,基于固定方差的随机初始化方法一般需要配合逐层归一化来使用.

7.3.2 基于方差缩放的参数初始化

参数初始化的区间应该根据神经元的性质进行差异化的设置.如果一个神经元的输入连接很多,它的每个输入连接上的权重就应该小一些,以避免神经元的输出过大(当激活函数为ReLU 时)或过饱和(当激活函数为Sigmoid 函数时).

初始化一个深度网络时,为了缓解梯度消失或爆炸问题,我们尽可能保持每个神经元输入输出方差一致根据神经元的连接数量来自适应地调整初始化分布的方差,这类方法称为方差缩放

7.3.2.1 Xavier初始化

假设在一个神经网络中,第ll层的一个神经元a(l)a^{(l)},其接收前一层的Ml1M_{l-1}个神经元的输出ai(l1)a^{(l−1)}_ i1iMl11 \leq i \leq M_{l-1}

在计算出参数的理想方差后,可以通过高斯分布或均匀分布来随机初始化参数。这种根据每层的神经元数量自动计算初始化参数方差的方法称为Xavier 初始化

虽然在Xavier 初始化中我们假设激活函数为恒等函数,但是Xavier 初始化也适用于Logistic 函数和Tanh 函数.这是因为神经元的参数和输入的绝对值通常比较小,处于激活函数的线性区间.这时Logistic 函数和Tanh 函数可以近似为线性函数.

7.3.2.2 He 初始化

当第𝑙 层神经元使用ReLU 激活函数时,通常有一半的神经元输出为0,因此其分布的方差也近似为使用恒等函数时的一半.这样,只考虑前向传播时,参数wi(l)w^{(l)}_i理想方差

var(wi(l))=2Ml1var(w^{(l)}_i) = \frac 2 {M_{l-1}}

  • 其中Ml1M_{l-1}是第l1l-1层神经元个数.

这种初始化方法称为He 初始化

He初始化适用于ReLu,而Xavier初始化适用于Logistic和tanh,如下表

7.3.3 正交初始化

由于采样的随机性,采样出来的权重矩阵依然可能存在梯度消失或梯度爆炸问题.

一种更加直接的方式是将𝑾(𝑙) 初始化为正交矩阵,即W(l)(W(l))T=IW^{(l)}(W^{(l)})^T = I,这种方法称为正交初始化。根据正交矩阵的性质,这个线性网络在信息的前向传播过程和误差的反向传播过程中都具有范数保持性(W(l)=1||W^{(l)}|| = 1)

当在非线性神经网络中应用正交初始化时,通常需要将正交矩阵乘以一个缩放系数β\beta.比如当激活函数为ReLU 时,激活函数在0 附近的平均梯度可以近似为0.5.为了保持范数不变,缩放系数ρ\rho可以设置为2\sqrt2

7.4 数据预处理

一般而言,样本特征由于来源以及度量单位不同,它们的尺度(Scale)(即取值范围)往往差异很大.以描述长度的特征为例,当用“米”作单位时令其值为𝑥,那么当用“厘米”作单位时其值为100𝑥.不同机器学习模型对数据特征尺度的敏感程度不一样.如果一个机器学习算法在缩放全部或部分特征后不影响它的学习和预测,我们就称该算法具有尺度不变性(Scale Invariance)

因此,对于尺度敏感的模型,必须先对样本进行预处理,将各个维度的特征转换到相同的取值区间,并且消除不同特征之间的相关性,才能获得比较理想的结果.

从理论上,神经网络应该具有尺度不变性,可以通过参数的调整来适应不同特征的尺度.但尺度不同的输入特征会增加训练难度。,如果数据维数很多时,我们很难这样精心去选择每一个参数的初始化.

除了参数初始化比较困难之外,不同输入特征的尺度差异比较大时,梯度下降法的效率也会受到影响尺度不同造成在大多数位置上的梯度方向并不是最优的搜索方向.当使用梯度下降法寻求最优解时,会导致需要很多次迭代才能收敛.如下图

归一化(Normalization)方法泛指把数据特征转换为相同尺度的方法,比如把数据特征映射到[0, 1] 或[−1, 1] 区间内,或者映射为服从均值为0、方差为1的标准正态分布

这里,我们介绍几种在神经网络中经常使用的归一化方法.

7.4.1 最小最大值归一化

最小最大值归一化(Min-Max Normalization)是一种非常简单的归一化方法,通过缩放每一个特征取值范围归一到[0, 1] 或[−1, 1]
之间.假设有𝑁 个样本x(n)n=1N{x^{(n)}}^N_{n=1},对于每一维特征xx,归一化后的特征为

x^(n)=x(n)minn(x(n))maxn(x(n))minn(x(n))\hat x ^{(n)} = \frac {x^{(n)} - min_n(x^{(n)})} {max_n(x^{(n)}) - min_n(x^{(n)})}

7.4.2 标准化

标准化(Standardization)也叫Z 值归一化(Z-Score Normalization),来源于统计上的标准分数.将每一个维特征都调整为均值为0,方差为1.假设有𝑁 个样本x(n)n=1N{x^{(n)}}^N_{n=1},对于每一维特征xx,我们先计算它的均值方差

然后,将特征x(n)x^{(n)}减去均值,并除以标准差,得到新的特征值

x^(n)=x(n)μσ\hat x^{(n)} = \frac {x^{(n)} - \mu} {\sigma}

其中标准差𝜎 不能为0.如果标准差为0,说明这一维特征没有任何区分性,可以直接删掉.

7.4.3 白化

白化(Whitening)是一种重要的预处理方法,用来降低输入数据特征之间的冗余性.输入数据经过白化处理后特征之间相关性较低,并且所有特征具有相同的方差.白化的一个主要实现方式是使用主成分分析(Principal Component Analysis,PCA)方法去除掉各个成分之间的相关性.

7.5 逐层归一化

逐层归一化(Layer-wise Normalization)是将传统机器学习中的数据归一化方法应用到深度神经网络中,对神经网络中隐藏层的输入进行归一化,从而使得网络更容易训练.

逐层归一化可以有效提高训练效率的原因有以下几个方面:

1 更好的尺度不变性

在深度神经网络中,一个神经层的输入是之前神经层的输出.给定一个神经层𝑙,它之前的神经层(1, ⋯ , 𝑙 − 1) 的参数变化
输入的分布发生较大的改变.当使用随机梯度下降来训练网络时,每次参数更新都会导致该神经层的输入分布发生改变.越高的层,其输入分布会改变得越明显.就像一栋高楼,低楼层发生一个较小的偏移,可能会导致高楼层较大的偏移.从机器学习角度来看,如果一个神经层的输入分布发生了改变,那么其参数需要重新学习,这种现象叫作内部协变量偏移(Internal Covariate Shift).

为了缓解这个问题,我们可以对每一个神经层的输入进行归一化操作,使其分布保持稳定.把每个神经层输入分布归一化标准正态分布,可以使得每个神经层对其输入具有更好的尺度不变性.不论低层的参数如何变化,高层的输入保持相对稳定.另外,尺度不变性可以使得我们更加高效地进行参数初始化以及超参选择.

2 更平滑的优化地形

逐层归一化

  1. 一方面可以使得大部分神经层的输入处于不饱和区域,从而让梯度变大,避免梯度消失问题
  2. 另一方面还可以使得神经网络的优化地形(Optimization Landscape)更加平滑,以及使梯度变得更加稳定,从而允许我们使用更大的学习率,并提高收敛速度

7.5.1 批量归一化

批量归一化(Batch Normalization,BN)方法是一种有效逐层归一化方法,可以对神经网络中任意的中间层进行归一化操作

对于一个深度神经网络,令第ll层的净输入z(l)\boldsymbol z^{(l)},神经元的输出a(l)\boldsymbol a^{(l)},即

a(l)=f(z(l))=f(Wa(l1)+b)\boldsymbol a^{(l)} = f(\boldsymbol z^{(l)}) = f(W\boldsymbol a^{(l-1)} + \boldsymbol b)

为了提高优化效率,就要使得净输入z(l)\boldsymbol z^{(l)}分布一致,比如都归一化到标准正态分布.

实践中归一化操作一般应用在仿射变换(Affine Transformation)Wa(l1)+bW\boldsymbol a^{(l-1)} + \boldsymbol b激活函数之前

这相当于每一层都进行一次数据预处理,从而加速收敛速度.但是逐层归一化需要在中间层进行操作要求效率比较高,因此复杂度比较高的白化方法就不太合适.为了提高归一化效率,一般使用标准化将净输入z(l)\boldsymbol z^{(l)}的每一维都归一到标准正态分布

z^(l)=z^(l)E[z(l)]var(z(l))+ϵ\boldsymbol {\hat z^{(l)}} = \frac {\boldsymbol {\hat z^{(l)}} - E[\boldsymbol z^{(l)}]} {\sqrt{var(\boldsymbol z^{(l)}) + \epsilon}}

其中E[z(l)]E[\boldsymbol z^{(l)}]var(z(l))var(\boldsymbol z^{(l)})是指当前参数下z(l)\boldsymbol z^{(l)}的每一维在整个训练集上的期望方差。由于使用整个训练集代价太大了,所以z(l)\boldsymbol z^{(l)}期望方差通常当前小批量样本集的均值和方差近似估计

对净输入𝒛(𝑙) 的标准归一化使得其取值集中到0 附近,如果使用Sigmoid型激活函数时,这个取值区间刚好是接近线性变换的区间,减弱了神经网络的非线性性质.因此,为了使得归一化不对网络的表示能力造成负面影响,可以通过一个附加的缩放平移变换改变取值区间

z^(l)=z(l)μσ2+ϵγ+βBNγ,β(z(l))\boldsymbol {\hat z^{(l)}} = \frac {\boldsymbol z^{(l)} - \boldsymbol \mu} {\sqrt{\boldsymbol \sigma^2 + \boldsymbol \epsilon}} \odot \boldsymbol \gamma + \boldsymbol \beta \equiv BN_{\boldsymbol \gamma, \boldsymbol \beta}(\boldsymbol z^{(l)})

批量归一化操作可以看作一个特殊的神经层,加在每一层非线性激活函数之前,即

a(l)=f(BNγ,β(Wa(l1)))\boldsymbol a^{(l)} = f(BN_{\boldsymbol \gamma, \boldsymbol \beta}(W\boldsymbol a^{(l-1)}))

值得一提的是,逐层归一化不但可以提高优化效率,还可以作为一种隐形正则化方法.在训练时,神经网络对一个样本的预测不仅和该样本自身相关,也和同一批次中的其他样本相关.由于在选取批次时具有随机性,因此使得神经网络不会“过拟合”到某个特定样本,从而提高网络的泛化能力

7.5.2 层归一化

批量归一化是对一个中间层单个神经元进行归一化操作,因此要求小批量样本数量不能太小,否则难以计算单个神经元的统计信息

层归一化对一个中间层的所有神经元进行归一化.

对于一个深度神经网络,令第𝑙 层神经元的净输入为z(l)\boldsymbol z(l),其均值方差

μ(l)=1Mli=1Mlzi(l)\mu^{(l)} = \frac 1 {M_l} \sum ^{M_l} _{i=1} z^{(l)}_i

σ(l)2=1Mli=1Ml(zi(l)μ(l))2{\sigma^{(l)}}^2 = \frac 1 {M_l} \sum ^{M_l} _{i=1} (z^{(l)}_i - \mu^{(l)})^2

  • 其中MlM_l为第ll层神经元的数量.

层归一化定义为

z^(l)=z(l)μσ2+ϵγ+βLNγ,β(z(l))\boldsymbol {\hat z^{(l)}} = \frac {\boldsymbol z^{(l)} - \mu} {\sqrt{\sigma^2 + \epsilon}} \odot \boldsymbol \gamma + \boldsymbol \beta \equiv LN_{\boldsymbol \gamma, \boldsymbol \beta}(\boldsymbol z^{(l)})

  • 其中γ\boldsymbol \gammaβ\boldsymbol \beta分别代表缩放平移的参数向量,和z(l)\boldsymbol z^{(l)}维数相同.
7.5.2.1 循环神经网络中的层归一化

层归一化可以应用在循环神经网络中,对循环神经层进行归一化操作.假设在时刻𝑡,循环神经网络的隐藏层为hth_t,其层归一化的
更新为

zt=Uht1+Wxt\boldsymbol z_t = U \boldsymbol h_{t-1} + W \boldsymbol x_t

ht=f(LNγ,β(zt))\boldsymbol h_t = f(LN_{\gamma, \beta}(\boldsymbol z_t))

  • 其中输入为xt\boldsymbol x_t为第tt时刻的输入,
  • U\boldsymbol UW\boldsymbol W为网络参数.

标准循环神经网络中,循环神经层的净输入一般会随着时间慢慢变大或变小,从而导致梯度爆炸消失.而层归一化的循环神经网络可以有效地缓解这种状况.

7.5.2.1 比较层归一化和批量归一化

层归一化和批量归一化整体上是十分类似的,差别在于归一化的方法不同.对于𝐾 个样本的一个小批量集合Z(l)=[z(1,l);...;z(K,l)]\boldsymbol Z^{(l)} = [\boldsymbol z^{(1, l)}; ... ; \boldsymbol z^{(K, l)}],层归一化是对矩阵𝒁(𝑙) 的每一列进行归一化,而批量归一化是对每一行进行归一化.一般而言批量归一化是一种更好的选择.当小批量样本数量比较小时,可以选择层归一化.

7.5.3 权重归一化

权重归一化(Weight Normalization)是对神经网络的连接权重进行归一化,通过再参数化(Reparameterization)方法,将连接权
分解长度方向两种参数.假设第ll层神经元a(l)=f(Wa(l1)+b)\boldsymbol a^{(l)} = f(\boldsymbol Wa^{(l-1)} + \boldsymbol b),我们将W\boldsymbol W再参数化为

Wi,:=givivi\boldsymbol W_{i,:} = \frac {g_i} {||\boldsymbol v_i||} \boldsymbol v_i

  • 其中𝑾𝑖,∶ 表示权重𝑾 的第𝑖 行,
  • gig_i表示长度
  • $\frac {\boldsymbol v_i} {||\boldsymbol v_i||} $表示方向

7.5.4 局部响应归一化

局部响应归一化通常用在基于卷积的图像处理上.

假设一个卷积层的输出特征映射 YRM×N×P\boldsymbol Y \in R^{M'\times N' \times P}三维张量,其中每个切片矩阵YRM×NY \in R^{M' \times N'}为一个输出特征映射,1 ≤ 𝑝 ≤ 𝑃.

局部响应归一化是对邻近的特征映射进行局部归一化.

局部响应归一化和生物神经元中的侧抑制(lateral inhibition)现象比较类似,即活跃神经元对相邻神经元具有抑制作用.当使用ReLU 作为激活函数时,神经元的活性值是没有限制的,局部响应归一化可以起到平衡和约束作用.如果一个神经元的活性值非常大,那么和它邻近的神经元就近似地归一化为0,从而起到抑制作用,增强模型的泛化能力

7.6 超参数优化

在神经网络中,除了可学习的参数之外,还存在很多超参数.这些超参数对网络性能的影响也很大.不同的机器学习任务往往需要不同的超参数.常见的超参数有以下三类:

  • 网络结构,包括神经元之间的连接关系层数每层的神经元数量激活函数的类型等.
  • 优化参数,包括优化方法学习率小批量的样本数量等.
  • 正则化系数

超参数优化(Hyperparameter Optimization)主要存在两方面的困难:

  1. 超参数优化是一个组合优化问题,无法像一般参数那样通过梯度下降方法来优化,也没有一种通用有效的优化方法;
  2. 评估一组超参数配置(Configuration)的时间代价非常高,从而导致一些优化方法(比如演化算法(Evolution Algorithm))在超参数优化中难以应用.

对于超参数的配置,比较简单的方法有网格搜索随机搜索贝叶斯优化动态资源分配神经架构搜索

具体方法略

7.7 网络正则化

机器学习模型的关键是泛化问题,即在样本真实分布上的期望风险最小化.而训练数据集上的经验风险最小化和期望风险并不一致.由于神经网络的拟合能力非常强,其在训练数据上的错误率往往都可以降到非常低,甚至可以到0,从而导致过拟合.因此,如何提高神经网络的泛化能力反而成为影响模型能力的最关键因素

正则化(Regularization)是一类通过限制模型复杂度,从而避免过拟合,提高泛化能力的方法,比如引入约束增加先验提前停止等.

7.7.1 l1l_1l2l_2正则化

l1l_1l2l_2正则化是机器学习中最常用的正则化方法,通过约束参数l1l_1l2l_2范数减小模型在训练数据集上的过拟合现象.

通过加入$ l_1l_2$正则化,优化问题可以写为

θ=argminθ1Nn=1NL(y(n),f(x(n);θ))+λlp(θ)\theta^* = argmin_\theta \frac 1 N \sum ^N _{n=1} L(y^{(n)}, f(\boldsymbol x^{(n)} ; \theta)) + \lambda l_p(\theta)

  • 就是不仅要θ\theta在损失函数上小,而且要引入正则项之后的和小
  • lpl_p是范数函数,pp的取值通常为1,2{1, 2}代表l1l_1l2l_2范数,λ\lambda为正则化系数

l1l_1范数零点不可导,因此经常用下式来近似:

l1(θ)=d=1Dθd2+ϵl_1(\theta) = \sum ^D _{d=1} \sqrt{\theta^2_d + \epsilon}

  • 其中DD为参数数量,ϵ\epsilon为一个非常小的常数.

但是,ℓ1 范数的约束通常会使得最优解位于坐标轴上,从而使得最终的参数为稀疏性向量.因此,一种折中的正则化方法是同时加入ℓ1 和ℓ2 正则化,称为弹性网络正则化

θ=argminθ1Nn=1NL(y(n),f(x(n);θ))+λ1l1(θ)+λ2l2(θ)\theta^* = argmin_\theta \frac 1 N \sum ^N _{n=1} L(y^{(n)}, f(\boldsymbol x^{(n)} ; \theta)) + \lambda_1 l_1(\theta) + \lambda_2 l_2(\theta)

7.7.2 权重衰减

权重衰减(Weight Decay)是一种有效的正则化方法,在每次参数更新时,引入一个衰减系数

θt(1β)θt1αgt\theta_t \leftarrow (1 - \beta) \theta_{t-1} - \alpha g_t

  • 其中gtg_t为第tt步更新时的梯度
  • α\alpha学习率
  • β\beta权重衰减系数,一般取值比较小,比如0.0005.

标准的随机梯度下降中,权重衰减正则化ℓ2 正则化效果相同.因此,权重衰减在一些深度学习框架中通过ℓ2正则化来实现.

7.7.3 提前停止

提前停止(Early Stop)对于深度神经网络来说是一种简单有效的正则化方法.由于深度神经网络的拟合能力非常强,因此比较容易在训练集上过拟合.在使用梯度下降法进行优化时,我们可以使用一个和训练集独立的样本集合,称为验证集(Validation Set),并用验证集上的错误来代替期望错误.当验证集上的错误率不再下降,就停止迭代

7.7.4 丢弃法

当训练一个深度神经网络时, 我们可以随机丢弃一部分神经元(同时丢弃其对应的连接边)来避免过拟合,这种方法称为丢弃法

每次选择丢弃的神经元是随机的.最简单的方法是设置一个固定的概率pp.对每一个神经元都以概率pp来判定要不要保留.对于一个神经层y=f(Wx+b)\boldsymbol y = f(W \boldsymbol x + \boldsymbol b),我们可以引入一个掩蔽函数 mask(.)mask(.) 使得y=f(Wmask(x)+b)\boldsymbol y = f(W mask(\boldsymbol x) + \boldsymbol b).掩蔽函数mask(⋅) 的定义为

mask(x)train=mxmask(\boldsymbol x)_{train} = \boldsymbol m \odot \boldsymbol x

mask(x)test=pxmask(\boldsymbol x)_{test} = p \boldsymbol x

  • 其中m{0,1}Dm \in \{0,1\}^D丢弃掩码(Dropout Mask),通过以概率为𝑝的伯努利分布随机生成.
  • 训练时,激活神经元的平均数量为原来的𝑝倍
  • 而在测试时,所有的神经元都是可以激活的,这会造成训练和测试时网络的输出不一致.为了缓解这个问题,在测试时需要将神经层的输入𝒙 乘以𝑝,也相当于把不同的神经网络做了平均.

pp的选取

  • 一般来讲,对于隐藏层的神经元,其保留率𝑝 = 0.5 时效果最好,这对大部分的网络和任务都比较有效.当𝑝 = 0.5 时,在训练时有一半的神经元被丢弃,只剩余一半的神经元是可以激活的,随机生成的网络结构最具多样性.
  • 对于输入层的神经元,其保留率通常设为更接近1 的数,使得输入变化不会太大.对输入层神经元进行丢弃时,相当于给数据增加噪声,以此来提高网络的鲁棒性
7.7.4.1 集成学习角度的解释

每做一次丢弃,相当于从原始的网络中采样得到一个子网络.如果一个神经网络有𝑛 个神经元,那么总共可以采样出2𝑛 个子网络.每次迭代都相当于训练一个不同的子网络,这些子网络都共享原始网络的参数.那么,最终的网络可以近似看作集成了指数级个不同网络的组合模型

7.7.4.1 循环神经网络上的丢弃法

当在循环神经网络上应用丢弃法时,不能直接对每个时刻的隐状态进行随机丢弃,这样会损害循环网络在时间维度上的记忆能力.一种简单的方法是对非时间维度的连接(即非循环连接)进行随机丢失。如图7.13所示,虚线边表示进行随机丢弃,实线表示不能丢弃,不同的颜色表示不同的丢弃掩码.

但是,根据贝叶斯理论,循环神经网络应该在所有时刻上共用相同的丢弃掩码,称为变分丢弃法,如下图

7.7.5 数据增强

深度神经网络一般都需要大量的训练数据才能获得比较理想的效果.在数据量有限的情况下,可以通过数据增强(Data Augmentation)来增加数据量提高模型鲁棒性,避免过拟合.目前,数据增强还主要应用在图像数据上,在文本等其他类型的数据上还没有太好的方法.

增强的方法主要有几种:旋转、翻转、缩放、平移、加噪声

7.7.6 标签平滑

在数据增强中,我们可以给样本特征加入随机噪声来避免过拟合.同样,我们也可以给样本的标签引入一定的噪声.假设训练数据集中有一些样本的标签是被错误标注的,那么最小化这些样本上的损失函数会导致过拟合.一种改善的正则化方法是标签平滑(Label Smoothing),即在输出标签中添加噪声来避免模型过拟合

一个样本x\boldsymbol x的标签可以用one-hot 向量表示,即

y=[0,...,0,1,0,...,0]T.\boldsymbol y = [0, ..., 0, 1, 0, ... , 0]^T.

这种标签可以看作硬目标(Hard Target),可能导致过拟合

我们可以引入一个噪声对标签进行平滑,即假设样本以ϵ\epsilon的概率为其他类.平滑后的标签为

y^=[ϵK1,...,ϵK1,1ϵ,ϵK1,...,ϵK1]\boldsymbol {\hat y} = [\frac {\epsilon} {K -1},...,\frac {\epsilon} {K -1},1 - \epsilon, \frac {\epsilon} {K -1},...,\frac {\epsilon} {K -1}]

其中𝐾 为标签数量,这种标签可以看作软目标(Soft Target).标签平滑可以避免模型的输出过拟合到硬目标上,并且通常不会损害其分类能力.