这周的内容是神经网络的性能优化,分别从mini-batch, exponentially weighted averages, momentum, RMSprop, Adam和learning rate decay上做了系统性的描述,这里面包含了非常多的超参数,那么让我们一起来回顾一下这周的内容吧。

Mini-batch

让我们假设原先数据:

  • X=[X(1),X(2),X(3),,X(m)]X = [X^{(1)}, X^{(2)}, X^{(3)}, \cdots, X^{(m)}],矩阵XX的结构为(nx,m)(n_x, m)
  • Y=[y(1),y(2),y(3),,y(m)]Y = [y^{(1)}, y^{(2)}, y^{(3)}, \cdots, y^{(m)}],矩阵YY的结构为(1,m)(1, m)

假设我们有5million条样本,也就是m=500,000m = 500,000,样本数量过大导致单次梯度下降变得非常缓慢,因为每次梯度下降算法都需要计算这5m条样本,而且只有全部处理结束之后才进行下一步的迭代过程。而且这些海量数据也很难一次性的全部加载到内存中,这就直接导致mini-batch方法的诞生。

怎么使用?

我们把这5m条样本划分为5k个子集,每一个子集有500,000÷5,000=1,000500,000 \div 5,000 = 1,000个,上面原先的数据也就变成了:

首先我们先进行符号确认:

  • X(i)X^{(i)}代表训练集中的第i个训练样本
  • Z[i]Z^{[i]}代表神经网络中l层的z值
  • X{t}X^{\{t\}}代表第t个mini-batch

为什么?

如果使用全部数据的好处是:

  • 每次迭代都向最优解靠近,不存在噪声

但是与此带来的坏处是:

  • 电脑内存不足以一次加载这么多数据
  • 一次迭代的时间过慢

但是噪声我们可以通过一些诸如momentum等的优化算法来达到优化的目的,所以我们引入mini-batch来解决原始梯度下降的不足之处。

我们先看一下对比:

  1. mini-batch size = m: batch gradient descent,这就是普通的梯度下降问题;
  2. mini-batch size = m/t: mini-batch gradient descent,这是mini-batch梯度下降问题;
  3. mini-batch size = 1,这是随机梯度下降,但是这个方法无法向量化达到优化效果。

综上,mini-batch实际上是这两种方法的折中,防止梯度下降针对超大数据量迭代一次速度缓慢的问题,同时也也解决了划分太细向量化不起作用的问题。在日常使用中,mini-batch(每个子集)的大小应根据于实际的硬件水平决定,一般是64-512之间的2的指数,还有些人使用1024但这种情况比较少。

Exponentially Weighted Averages

ERA是接下来介绍的momentum和RMSprop两种优化方案的核心。首先展示EWA的公式Vt=βVt1+(1β)θtV_t = \beta V_{t-1} + (1 - \beta) \theta_t,其中β\beta是一个超参数(hyperparameter),其值为对于上一个结果的保留权重,Vt1V_{t-1}是上一个的值,θt\theta_t是本次的值。从这个公式中我们能看出当β\beta越大,本次的值就越低,上次的值就越高,这样曲线变得平滑,可以理解为对新值不敏感;反过来则对新值敏感,导致曲线浮动越大,噪声就越大。其实我们用EWA就可以近似求得一段时间内的平均值。

怎么工作?

假设tmax=100t_{max} = 100β=0.9\beta = 0.9,根据公式可得,V100=0.1θ100+0.1×0.9V99+0.1×0.92V98++0.1×0.910theta90+V_{100} = 0.1\theta_{100} + 0.1 \times 0.9 V_{99} + 0.1 \times 0.9^2 V_{98} + \cdots + 0.1 \times 0.9^ {10}theta_{90} + \cdots,特别的在0.9100.30.9^{10} \approx 0.3,说明在第10次时已经下降到原先的30%左右。通过公式可以推出这相当于求11β\frac{1}{1 - \beta}次的平均值。

优点

如果求平均值,正常的方式是将全部的数据都存储起来一起求,但是在数据大的情况下,这种方式就变得不可取,所以我们可以利用EWA来近似的估计平均值,在β\beta参数的调整下近似求出指定次数之内的平均值,这将大大改善计算效率。

Momentum

这个算法的引入主要是因为使用了mini-batch后导致数据不总是沿着最优解移动,之所以这样是因为之前提到过每次的训练不是整个训练集,无法保证每次梯度下降总能沿着最优的方向前进,但可以肯定的是在全局来讲一定是这样的,所以momentum就是为了减缓优化方向不向着最优解移动的情景。

首先对于梯度下降(mini-batch size = m)每次迭代都是考虑了全部样本,优化方向是全局性,但是mini-batch就是不一定的了,每次都是读取的一部分数据,所以就会带来噪声影响。

如上图我们可以看到绿色的线虽然总体上是向最优化点靠近的,但是上下波动比较明显,所以momentum这个方法就是着重于解决上下波动的问题。我们可以观察一下,这种上下波动有一个最大的特点就是一段时间之内可以互相抵消,所以借助EWA我们可以求一段时间的平均值来抵消上下的走动,因为总方向是向最优化点靠近的,所以求平均值并不会对水平移动有太大的影响。

最终的公式为:

  1. 赋初值,VdW=0V_{\mathrm{d}W} = 0

  2. 使用EWA求平均值,VdW=βVdW+(1β)dWV_{\mathrm{d}W} = \beta V_{\mathrm{d}W} + (1 - \beta) \mathrm{d}W以及Vdb=βVdb+(1β)dbV_{\mathrm{d}b} = \beta V_{\mathrm{d}b} + (1 - \beta) \mathrm{d}b

  3. 更新参数,W=WαVdWW = W - \alpha V_{\mathrm{d}W}以及b=bαVdbb = b - \alpha V_{\mathrm{d}b}

这里需要注意的是这里的β\beta实际上就是一种超参数,Andrew Ng推荐使用0.9为该超参数的值。

RMSprop

与上面的Momentum差不多,RMSprop同样也是解决在mini-batch梯度下降中的摆动问题,理解这个的基础是对于神经网络而言每一层其实都是一个线性变换,他的思路是一般WW的值较小(小于1),bb的值较大(大于1),所以为了让在水平移动更多(WW控制)和垂直移动更少(bb控制):

  1. dW\mathrm{d}Wdb\mathrm{d}b的大小关系如上,dW2\mathrm{d}W^2则更小和db2\mathrm{d}b^2则更大,这样再利用EWA得出SdW=β2SdW+(1β2)dW2S_{\mathrm{d}W} = \beta_2 S_{\mathrm{d}W} + (1 - \beta_2) \mathrm{d}W^2Sdb=β2Sdb+(1β2)db2S_{\mathrm{d}b} = \beta_2 S_{\mathrm{d}b} + (1 - \beta_2) \mathrm{d}b^2
  2. 更新参数,W=WαdWSdW+ϵW = W - \alpha \frac{\mathrm{d}W}{\sqrt{S_{\mathrm{d}W}} + \epsilon}以及b=bαdWSdb+ϵb = b - \alpha \frac{\mathrm{d}W}{\sqrt{S_{\mathrm{d}b}} + \epsilon}

Adam

Adam优化算法实际上是RMSprop和momentum的结合体,它的优点是适用性广泛,在很多NN模型中都可以使用。具体算法如下:

  • 赋初值,$V_{\mathrm{d}W} = 0 V_{\mathrm{d}b} = 0 S_{\mathrm{d}W} = 0 以及 S_{\mathrm{d}b} = 0 $;
  • 在第t次迭代中:
    • 使用mini-batch方式计算$ \mathrm{d}W, \mathrm{d}b $;
    • momentum: $ V_{\mathrm{d}W} = \beta_1V_{\mathrm{d}W} + (1 - \beta_1) \mathrm{d}W V_{\mathrm{d}b} = \beta_1V_{\mathrm{d}b} + (1 - \beta_1) \mathrm{d}b $
    • RMSprop: $ S_{\mathrm{d}W} = \beta_2 S_{\mathrm{d}W} + (1 - \beta_2) \mathrm{d}W^2 S_{\mathrm{d}b} = \beta_2 S_{\mathrm{d}b} + (1 - \beta_2) \mathrm{d}b^2 $
    • 参数修正(bias correction),稍后会介绍参数修正的作用:
      • $ V_{\mathrm{d}W}^{corrected} = \frac{V_{\mathrm{d}W}}{1 - \beta_1^t} $
      • $ V_{\mathrm{d}b}^{corrected} = \frac{V_{\mathrm{d}b}}{1 - \beta_1^t} $
      • $ S_{\mathrm{d}W}^{corrected} = \frac{S_{\mathrm{d}W}}{1 - \beta_2^t} $
      • $ S_{\mathrm{d}b}^{corrected} = \frac{S_{\mathrm{d}b}}{1 - \beta_2^t} $
  • 更新参数(perform the update): 更新$ W $: $ W = W - \alpha \frac{V_{\mathrm{d}W}{corrected}}{\sqrt{S_{\mathrm{d}W}{corrected}} + \epsilon} b,更新b: b = b - \alpha \frac{V_{\mathrm{d}b}{corrected}}{\sqrt{S_{\mathrm{d}b}{corrected}} + \epsilon} $

最后对于上述方法,前人给出了几个默认值:

  • α\alpha:学习率,这个需要自行调试;
  • β1\beta_1:momentum的参数,默认值为0.9;
  • β2\beta_2:RMSprop的参数,默认值为0.999;
  • ϵ\epsilon:防止RMSprop的分母趋近于0,这个一般不要调整,默认值为10810^{-8}

Bias Correction(参数修正)

虽然使用Exponentially weighted averages会得到性能上的好处,但是这个方法在一开始数据不充分时会造成计算的平均值不准确,例如:

  1. 第一步中我们可以计算得出,V1=βV0+(1β)θ1V_1 = \beta V_0 + (1 - \beta) \theta_1,由于V0=0V_0 = 0,则V1=(1β)θ1V_1 = (1 - \beta) \theta_1
  2. 第二步中我们可以计算得出,V2=βV1+(1β)θ2V_2 = \beta V_1 + (1 - \beta) \theta_2,则V2=β(1β)θ1+(1β)θ2V_2 = \beta (1 - \beta) \theta_1 + (1- \beta) \theta_2

注意这里的V2V_2就是计算的平均值的近似值,但是可以很明显的看出,正确的平均值的公式为θ1+θ22\frac{\theta_1 + \theta_2}{2},假设β=0.98\beta = 0.98那么V2=0.0196θ1+0.02θ2V_2 = 0.0196\theta_1 + 0.02\theta_2,所以与真实的平均值还差的远。这时候偏差修正就开始起作用了,其公式为V1βt\frac{V}{1 - \beta^t},可以看到当t越小偏差修正起到的作用越大,当t越大分母就越趋近于1,起到的作用就越大。

Learning Rate Decay(学习率衰减)

主要的思路就是通过调整学习率的方式来加快学习,前期学习率大,因为距离远可以大步向最优值前进,这有点像粗调,后期学习率小,距离近就需要小步慢走,也就是细调。公式有很多,如α=11+decay_rate×epoch_num\alpha = \frac{1}{1 + decay\_rate \times epoch\_num},其中decay_ratedecay\_rate衰减率,epoch_numepoch\_num迭代次数,或α=0.95epoch_timeα\alpha = 0.95^{epoch\_time} \cdot \alpha。Andrew Ng不推荐一上来就使用这种优化方法,可以先指定一个固定的α\alpha,最后尝试学习率衰减。

The Problem of Local Optima

在高维空间中,很多时候导数为0不意味着我们找到了局部最优解,而可能是我们找到了一个鞍点(Saddle Point),比如有20000个维度,局部最优解是一个凸函数或凹函数,需要20000个向量同方向,那么其可能性为1220000\frac{1}{2^{20000}},鞍点则是导数为0的点,但不是全部向量同方向,其他方向可能由于相互抵消作用而使整体导数为0。

References