深度学习-调参和优化(二)

Hits: 35

本文介绍Coursera-Deep Learning-Course2-Week2:Optimization algorithms的内容:深度学习的优化,主要是如何加速梯度下降。

梯度下降的优化

这部分主要介绍了三种梯度下降方法:Batch Gradient Descent, Mini-batch Gradient Descent和Stochastic Gradient Descent,这些内容已经在之前的文章(大规模机器学习)中已经解释的很清楚了,本文不再具体阐述。
先回顾下之前的梯度下降公式:
$$
\theta_{j} := \theta_{j} - \alpha \frac{1}{m}\sum_{i=1}^{m}\left ( h_{\theta}\left ( x^{(i)}\right )- y ^{(i)}\right ) x_{j}^{(i)}
$$

上面这个公式代表的是全批量的梯度下降(batch gradient descent),是梯度下降最原始的形式,也就是说梯度每下降一步都要把所有的样本数据算一遍,这个代价是非常昂贵的,如果m是百万级别的话(实际工程中很常见),那么训练就会变得非常缓慢。如何解决呢?有人提出了一个方法叫mini-batch gradient descent:在每一次迭代的过程中,不再是把所有的数据全部考虑进去,而是把数据集分成若干份,然后依次对这若干份数据进行梯度下降。而随机梯度下降Stochastic Gradient Descent,在每一次迭代过程中,每计算一个样本数据就会下降一次。
具体地,我们看一下代码(TensorFlow):

  • Batch Gradient Gescent:

  • Mini-batch Gradient Descent:

这两份代码很好懂,但你可能不禁会问:这两种方法从代码层面来看,复杂度是一样的呀,为什么mini-batch会更快呢?没错,虽然总的复杂度是一样的,但是同样一次迭代,前者只能下降一步,但是后者却能下降num_minibatches步,所以后者梯度下降更快!

  • 什么时候要选择使用Mini-batch?
    通常,当数据量大于2000时会选择Mini-batch,所以在实际工程应用中,mini-batch gradient descent已经成为标配了。
  • 如何选择mini-batch size?
    一般是2的n次方,64,128,256,512,1024等。

这三种梯度下降方法的batch-size如下表所示:

Batch Mini-batch Stochastic(SGD)
m (1,m) 1

Exponentially weighted averages

定义
在解释这个概念之前,我们先引入一个例子。假设有如下一些离散的数据,他们表示伦敦某三个月每天的气温:

$$
\theta_1 = 40 ^{\circ} \text{F} \\
\theta_2 = 49 ^{\circ} \text{F} \\
\theta_3 = 45 ^{\circ} \text{F} \\
... \\
\theta_{180} = 60 ^{\circ} \text{F} \\
\theta_{181} = 56 ^{\circ} \text{F}
$$
我们把这些离散的点投射到平面上:

Imgur

现在我们要找到一条曲线(一个函数\(V(t)\))来拟合这些离散的数据。这个函数的形式是这样的:

$$
V(t) = \beta_1 V(t-1) + (1-\beta_1) \theta_t
$$

这个函数有个特点:\(t\)时刻的值由\(t-1\)时刻的值和当前的温度\(\theta_t\)组成,通过参数\(\beta_1\)来控制两者的比例。

当\(\beta_1=0.9\)时,会得到如下红色的曲线:

Imgur

当\(\beta_1=0.98\)时,会得到如下绿色的曲线:
Imgur

当\(\beta_1=0.5\)时,会得到如下黄色的曲线:
Imgur

观察以上三个参数下拟合曲线,我们可以知道:当\(\beta_1\)变大时,\(V_t\)的值会越接近\(V_{t-1}\),而当前温度值\(\theta_t\)的比重会变小,所以拟合的曲线会更多地反应之前n天的平均气温,因此会很平缓;而当\(\beta_1\)变小时,\(V_t\)的值会越接近当前的温度值\(\theta_t\),所以拟合的曲线就越激进,震荡明显。

Bias Correction(偏差矫正)
当然,这个公式其实是有点小问题的,特别是在拟合前期数据时是非常不准确的,我们举个例子,假设\(\beta_1=0.98\):

$$
v_0 = 0;\\
v_1 = 0.98 \times v_0 + 0.02 \times \theta_1 = 0.02 \times \theta_1;\\
v_2 = 0.98 \times v_1 + 0.02 \times \theta_2 = 0.0196 \times \theta_1 + 0.02 \times \theta_2; \\
$$
很明显,\(v_2\)的值是非常不符合实际情况的,被严重减少,那么怎么办呢?很简单,我们通过下面的公式进行校正:
$$
v_t = \frac{v_t}{1-\beta^t}
$$
这就是Bias Correction(偏差矫正)。那么通过这个公式矫正之后,我们再次计算\(v_2\)就会发现它的值接近于真实值了:

$$
v_2 = \frac{v_2}{1-0.98^2} = \frac{0.0196\times \theta_1 + 0.02 \times \theta_2}{0.0396}
$$
那么,这个公式怎么理解呢?当\(t\)很小时,\(1-\beta^t\)的值就会很小,因此能得到很好的补偿;而当\(t\)很大时,\(1-\beta^t\)的值就会趋近于1,也因此可以被忽略了。

Gradient descent with momentum,RMSprop and Adam

费这么大周折讲解Exponentially weighted averages有什么用呢?原因是我们可以使用这个算法优化梯度下降,效果如下图所示:
Imgur
使用之前是蓝色的折线,使用之后变成红色的折线,下降更快了。
我们主要介绍三种方法:

  • Gradient descent with momentum
    他的公式如下:

$$
V_{dW} = \beta_1 V_{dW} + (1 - \beta_1) dW \\
V_{db} = \beta_1 V_{db} + (1 - \beta_1) db \\
W = W - \alpha V_{dW}\\
b = b - \alpha V_{db}
$$

  • RMSprop
    全称是Root Mean Square prop,他的公式如下:
    $$
    S_{dw} = \beta_2 S_{dw} + (1-\beta_2) dW^2 (1) \\
    S_{db} = \beta_2 S_{db} + (1-\beta_2) db^2 (2) \\
    W = W - \alpha \frac{dW}{\sqrt{S_{dw}} + \varepsilon } (3) \\
    b = b - \alpha \frac{db}{\sqrt{S_{db}} + \varepsilon } (4)
    $$
    \(\varepsilon\)是个安全系数,为了防止分母为0,一般会被设置的非常小,比如\(10^{-8}\)。
  • Adam optimization algorithm
    Adam的全称是Adaptive Moment Estimation,并不是人名。他是momentum和RMSprop的结合,相比于RMSprop而言,唯一的变化是公式3和4的分子被换成了momentum的形式。完整的公式如下:

$$
V_{dW} = \beta_1 V_{dW} + (1 - \beta_1) dW \\
V_{db} = \beta_1 V_{db} + (1 - \beta_1) db \\
S_{dw} = \beta_2 S_{dw} + (1-\beta_2) dW^2 \\
S_{db} = \beta_2 S_{db} + (1-\beta_2) db^2 \\
V_{dW}^{corrected} = \frac{V_{dW}}{1-\beta_1^t};V_{db}^{corrected} = \frac{V_{db}}{1-\beta_1^t} \\
S_{dW}^{corrected} = \frac{S_{dW}}{1-\beta_2^t};S_{db}^{corrected} = \frac{S_{db}}{1-\beta_2^t} \\
W = W - \alpha \frac{V_{dW}^{corrected}}{\sqrt{S_{dw}^{corrected}} + \varepsilon } \\
b = b - \alpha \frac{V_{db}^{corrected}}{\sqrt{S_{db}^{corrected}} + \varepsilon }
$$

看懂了这个公式,我们就知道:它之所以叫adaptive momentum是因为一次梯度下降的过程中有两次momentum,第一次是\(\beta_1\)参与计算的\(V\),第二次是\(\beta_2\)参与计算的\(S\)。Adam方法有好多个参数需要指定:\(\alpha,\beta_1,\beta_2,\varepsilon\),但一般只有\(\alpha\)需要被调优,其余的都用默认值:\(\beta_1=0.9;\beta_2=0.999;\varepsilon=10^{-8}\)。关于Adam方法的解释写了一大堆,但其实你并不必深究,大致知道它的原理就行了,因为现在任何一个深度学习或者机器学习的框架(caffe/tensorflow等)都封装了这个方法(甚至没有参数让你去调),比如在TensorFlow里就一行代码:

学习曲率衰减(Learning Rate Decay)

我们知道,随着梯度下降越接近最优解,下降的幅度和速度也会越小,那么如果这时候还保持和刚开始一样大的学习曲率下降,则很可能会不收敛。因此,学习曲率应该随着迭代次数的增加而变小,这是很直观的。学习曲率衰减有很多实现方式,比如:

  • 倒数(以epoch_num为分母)形式的衰减:

$$
\alpha = \frac{1}{1+decayrate * epochnum } * \alpha_0
$$

$$
\alpha = \frac{k}{\sqrt{epochnum}} * \alpha_0
$$

  • 倒数(以时间t为分母)形式的衰减:

$$
\alpha = \frac{k}{\sqrt{t}} * \alpha_0
$$

  • 指数级的衰减:

$$
\alpha = 0.95^{epochnum} * \alpha_0
$$

局部最优问题(Stuck In Local Optimal)

以前我们讨论机器学习时,都很担心梯度下降会陷入局部最优而得不到最优解。最先想到的就是如下图左边部分,这个cost function J的三维图形中有很多个局部最优。但其实,随着参数数量(也就是维度)的增加(深度学习通常有几千个),局部最优已经很难出现了。因为局部最优的点必须要求每一个参数都朝同一个方向,这个概率太低了,更多的是像右边这种马鞍形。(但这个只是举了二维的例子,当维度很高时,cost function J到底是什么样的,没人能想象得出来)
Imgur
因此在训练一个深度学习应用时,你不必担心会陷入局部最优

除了陷入局部最优之外还有另一个问题:Propblem of plateaus。
Imgur
如上图所示,梯度像是骑在了马背上一样缓慢滑下来,它下降的非常慢。但这个问题也不用过分担心,我们可以通过Adam等方法加速下降。


发表评论

电子邮件地址不会被公开。 必填项已用*标注