深度学习的实践秘诀:优化方法回顾

深度学习的实践秘诀:优化方法回顾

我们先来回顾我们进行深度学习建模的3个步骤

  1. 定义set of function: NN的结构
  2. 定义Loss function
  3. optimization:选定优化方法进行参数迭代

优化好之后:

  1. 检查在training set的结果如何。有问题则返回前3步
  2. 观察testing set上的performance。看是否overfitting (必须先检查训练集是否好)

深层神经网络的优化和正则化是即对立又统一的关系。一方面我们希望优化算法能找到一个全局最优解(或较好的局部最优解),另一方面我们又希望模型具有很好的泛化能力,让模型变得简单,避免陷入过拟合。优化和正则化的统一目标是期望风险最小化。

根据通用近似定理,无论是全连接神经网络还是循环神经网络,都可以表示任意的连续函数或者程序模式,从直觉上来说,神经网络的模型容量,足以过拟合。从上面两个问题出发,我们可以把神经网络应用到实际问题(或者说机器学习问题),分为两大类问题:

  1. 优化问题:在训练集上是否表现足够好。这里包括了
    • loss是否足够小
    • 计算效率是否足够快:神经网络往往参数很多,如何保证计算效率
    • 是否不可优化。即出现梯度消失和梯度爆炸的问题
  2. 泛化问题:

在进行deep learning之后,大部份方法都是在解决上述的两个问题,方法是解决训练集效果不好还是测试集效果不好的问题。

优化问题: 解决训练集效果不好的方法

我们从建模步骤的角度去看,来构建我们进行优化的思路。

调整模型结构

set of function: 结构需要调整。例如使用新的激活函数

ReLU

  • 快速计算
  • 符合生物学考虑
  • (hinton)相当于无穷多的不同bias的sigmoid函数叠加
  • 可以解决梯度弥散的问题

maxout, 可学习的激活函数 。

  1. 将每一层的输出值,选择n个element进行group,每个group输出最大的output。
  2. 然后将这组output,乘新的参数,又获得一组输出值,同时进行group+max。

性质:

  1. 可以拟合任意组的线性凸函数
  2. 组数由group中的元素数量决定。即每组中有n个元素,就会得到n段分段函数。

选择不同的优化算法

梯度下降是深度神经网络进行参数学习的主要方法,用于最小化结构风险,找到令损失函数最小的最优解。采用梯度优化就会考虑到如下几个问题:

  1. 收敛的效率和效果
  2. 如何初始化参数
  3. 数据要做何预处理
  4. 如何选择学习率
  5. 如何选择梯度优化的方向

一般的优化方法

我们简单来看一下优化算法的大致框架:

首先定义:待优化参数: $w$,目标函数: $f(w)$,初始学习率 $\eta$。

Optimization过程如下:

  1. 计算目标函数在当前参数下的梯度$g_t = \nabla f(w_t)$

  2. 根据历史梯度,计算一阶动量和二阶动量:$m_t = \phi(g_1, g_2, \cdots, g_t); V_t = \psi(g_1, g_2, \cdots, g_t)$。对于SGD,我们可以认为$m_t = g_t, V_t = I^2=1$

  3. 根据动量和梯度下降的方向,计算当前的下降梯度:$\theta_t = \eta \cdot \frac{m_t}{\sqrt{V_t}}$。分子分母的位置从直觉上理解,就是希望受当前梯度的影响,又要引入历史累积梯度来调整当前梯度。

  4. 更新梯度:

这里我们需要注意epoch和iterations的概念区分,对于整个神经网络的更新,是一回合epoch。而每次梯度的迭代都算一次iter。对于随机梯度下降,假设特征列大小N,batch size K,则一个epoch有$\frac{N}{K}$个iters。

一般来说,在训练深层神经网络时,经常使用小批量梯度下降算法,避免计算全量数据需要消耗过多的计算资源。对于SGD,我们可以认为$m_t = g_t, V_t = I^2=1$, 使用梯度下降进行参数更新:

一般批量大小较小时,需要设置较小的学习率,否则模型会不收敛。从图7.3a可以看出, 每次迭代选取的批量样本数越多,下降效果越明显,并且下降曲线越平滑。当 每次选取一个样本时(相当于随机梯度下降),损失整体是下降趋势,但局部看 会来回震荡。如果按整个数据集上的迭代次数(Epoch)的 来看损失变化情况,则是批量样本数越小,下降效果越明显。

image-20190528200944526

SGD的缺点同样明显,受学习率和batch size影响大,如果设置不好,容易下降速度慢,陷入局部最优震荡。

自适应的学习率 adaptive learning rate

.我们想象一下,梯度优化就是一个球在进行最快速的下山。平坦的地方小的lr就行,梯度陡峭的地方需要大的lr。

AdaGrad

借鉴L2正则化的思想,每次迭代时自适应地调整每个参数的学习率,引入了二阶动量。在第 t 迭代时,先计算每 个参数梯度平方的累计值(分母部份,可以加拉普拉斯平滑$\epsilon \in [e^{-7}, \ e^{-10}]$;如果某个参数经常更新,偏导数累积比较大,其学习率相对较小;相反,如果其偏导数累积较小,其学习率相对较大。但整体是随着迭代次 数的增加,学习率逐渐缩小。缺点是在经过一定次数的迭代依然没有找到最优点时,由 于这时的学习率已经非常小,很难再继续找到最优点。这里的二阶动量就是$Vt = \sum\{i=0}^t(g^{i})^2$,代入公式(1)。

RMSProp

Hinton,为了避免AdaGrad过早衰减的问题,有原来的计算累计梯度变成了计算移动平均$\sigma$,只关注过去一段时间的梯度累积。此时,$V_t = \beta \cdot V_{t-1} + (1- \beta)g_t^2$

简单认为调整新旧的gradient的影响。原理上还是计算梯度的RMS(Root Mean Square),但是前一个权重下降了(根据$\beta$进行变化,$\beta$为衰减率,一边取0.9)。

Momentum

物理世界惯性的特性,梯度下降的方向会存在一点惯性。即:现在gradient移动的方向,会带有前一步移动的方向。对于初始点$\theta ^0$,假设上一步的移动方向(movement)为$v_0 = 0$,计算梯度$g_0 =\nabla L\left(\theta^{0}\right) $,则新的移动方向为

梯度的更新为:

同时,$m_t$实际上就是此前所有梯度的加权和,越久远的梯度所带来的惯性越小,$\rho$为动量因子,一般取[0.85, 0.95]。而Momentum,就是上一个时间点的movement : $m_{i-1}$.

设想,在plateau或者local minima或者saddle point鞍点附近,当前的原始梯度为0或接近0,但是还有momentum的惯性,同样可以进行参数的更新。但是,同样也不能保证到gloabal。这样,每个参数的实际更新差值取决于最近一段时间内梯度的加权平均值。 当某个参数在最近一段时间内的梯度方向不一致时,其真实的参数更新幅度变 小;相反,当在最近一段时间内的梯度方向都一致时,其真实的参数更新幅度 变大,起到加速作用。一般而言,在迭代初期,梯度方法都比较一致,动量法 会起到加速作用,可以更快地到达最优点。在迭代后期,梯度方法会取决不一致,在收敛值附近震荡,动量法会起到减速作用,增加稳定性。从某种角度来说,当前梯度叠加上部分的上次梯度,一定程度上可以近似看作二阶梯度。

NAG,Nesterov Accelerated Gradient

对于动量法,在t时刻的主要下降方向是有累积动量决定的,因此,与其跟着当前梯度进行调整,不如先按照累积梯度调整之后,再看梯度如何更新,即优化了步骤1 $g_t$的计算方式:

Adam=RMSProp + Momentum。

由Momentum提供一阶动量,RMSProp提供二阶动量:

如果简化一阶动量的考虑,对于任意时刻的学习率$\eta_t=\eta / \sqrt{V_t}$,如果需要保证学习率递减来保证最终收敛不震荡的话,可以简单的发现,只需要保证$\left|V_t\right| \geq\left|V_{t-1}\right|$就能让学习率递减。但,对于$V_t = \beta \cdot V_{t-1} + (1- \beta)g_t^2$,发现当$g_t^2 < V_{t-1}$时,会导致动量变小,就可能使得学习率震荡变大。因此,我们可以做一些修改,保证学习率递减。

但是,这样也没办法保证收敛到全局最优解,可能在学习率降到0时,就提前收敛了。

但,Adam已经很好的简化了优化方法的调参和计算效率。对于是否落到最优解,我们自然而然的也会想到一种方案,前期使用Adam快速下降,后期使用SGD进行最优化调整。

Nadam = Adam + NAG

根据NAG修改$g_t$的计算方式

梯度截断

除了常见的梯度消失问题以外,梯度爆炸也是影响训练集不收敛的原因。包括按值截断和按模截断。一般选择按模截断。

0%