这周学习了优化算法,可以让神经网络运行的更快。
主要有:
原本的梯度下降算法,在每一次的迭代中,要把所有的数据都进行计算再取平均,那如果你的数据量特别大的话,每进行一次迭代就会耗费大量的时间。
所以就有了mini-batch,做小批量的计算迭代。也就是把训练集划分成n等分,比如数据量有500万个的时候,以1000为单位,将数据集划分为5000份,
$$x = {x^{\lbrace 1 \rbrace},x^{\lbrace 2 \rbrace},x^{\lbrace 3 \rbrace},…..,x^{\lbrace 5000 \rbrace}}$$
用大括弧表示每一份的mini-batch,其中每一份$x^{\lbrace t \rbrace}$都是1000个样本。
这个时候引入epoch的概念,1个epoch相当于是遍历了一次数据集,比如用mini-batch,1个epoch就可以进行5000次迭代,而传统的batch把数据集都一起计算,相当于1个epoch只进行了1次迭代。
具体计算步骤是:
for t in range(5000)
,循环每次迭代batch和mini-batch的对比如图:
mini-batch size的选择
因为电脑的内存和使用方式都是二进制的,而且是2的n次方,所以之前选1000也不太合理,可以选1024,但是1024也比较少见,一般是从64到512。也就是$64、128、256、512$
蓝色的点是每一天的气温,可以看到是非常抖动的,那如果可以把它平均一下,比如把10天内的气温平均一下,就可以得到如红色的曲线。
但是如果是单纯的把前面的10天气温一起平均的话,那么这样你就需要把前10天的气温全部储存记录下来,这样子虽然会更准一点,但是很浪费储存空间,所以就有了指数加权平均这样的概念。方法如下:
$$V_0 = 0$$
$$V_1 = \beta * V_0 + (1 - \beta) \theta_1$$
$……$
$$V_t = \beta * V_{t-1} + (1 - \beta) \theta_t$$
其中,$\theta_t$表示第t天的温度,而$V_t$表示指数加权平均后的第t天温度,$\beta$这个参数表示$\frac{1}{1-\beta}$天的平均,也就是,$\beta = 0.9$,表示10天内的平均,$\beta = 0.98$,表示50天内的平均。
我们再来看一下公式:
$$v_t = \beta v_{t-1} + (1 - \beta) \theta_t$$
假设$\beta = 0.9$,那么
$$v_{100} = 0.9v_{99} + 0.1\theta_{100}$$
$$v_{99} = 0.9v_{98} + 0.1\theta_{99}$$
$$v_{98} = 0.9v_{97} + 0.1\theta_{98}$$
展开一下,得到:
$$ v_{100} = 0.1 \theta_{100} + 0.1 \times 0.9 \times \theta_{99} + 0.1 \times 0.9^2 \times \theta_{98} + ……$$
看到没有,每一项都会乘以0.9,这样就是指数加权的意思了,那么为什么表示的是10天内的平均值呢?明明是10天以前的数据都有加进去的才对,其实是因为$0.9^{10} \approx 0.35 \approx \frac{1}{e}$,也就是10天以前的权重只占了三分之一左右,已经很小了,所以我们就可以认为这个权重就是10天内的温度平均,其实有详细的数学证明的,这里就不要证明了,反正理解了$(1-\epsilon)^{\frac{1}{\epsilon}} \approx \frac{1}{e}$,$\epsilon$为0.02的时候,就代表了50天内的数据。
因为指数加权平均不需要知道前面n个数据,只要一步一步进行迭代,知道当前的数据就行,所以非常节省空间。
如果你细心一点,你就会发现其实这个公式有问题,
$$V_0 = 0$$
$$V_1 = \beta * V_0 + (1 - \beta) \theta_1$$
$……$
$$V_t = \beta * V_{t-1} + (1 - \beta) \theta_t$$
如果第一天的温度是40摄氏度,那么$V_1 = 0.1 * 40 = 4$,显然是不合理的。因为初始值$V_0 = 0$,也就是前面几天的数据都会普遍偏低。所以特别是在估测初期,需要进行一些修正,这个时候就不要用$v_t$了,而是用$\frac{v_t}{1-\beta^t}$来代表第t天的温度平均,你会发现随着t的增加,$\beta^t$接近于0,所以偏差修正几乎就没有用了,而t比较小的时候,就非常有效果。
不过在大部分机器学习中,一般也不需要修正,因为只是前面的初始时期比较有偏差而已,到后面就基本不会有偏差了,所以也不太用。
用动量梯度下降法运行速度总是比标准的梯度下降法要来的快。它的基本思想是计算梯度的指数加权平均数,然后用该梯度来更新权重。
效果如图:
使用动量梯度下降法后,在竖直方向上的抖动减少了,而在水平方向上的运动反而加速了。
算法公式:
可以发现,就是根据指数平均计算出了$v_{dW}$,然后更新参数时把$dW$换成了$v_{dw}$,$\beta$一般的取值是0.9。可以发现,在纵向的波动经过平均以后,变得非常小了,而因为在横向上,每一次的微分分量都是指向低点,所以平均后的值一直朝着低点前进。
物理意义:
均方根传播。这是另一种梯度下降的优化算法。
顾名思义,先平方再开根号。
其实和动量梯度下降法公式差不多:
在更新参数的分母项加了一项$\epsilon = 10^{-8}$,来确保算法不会除以0
Adam算法其实就是结合了Momentum和RMSprop ,注意这个时候要加上偏差修正:
超参数有$\alpha,\beta_1,\beta_2,\epsilon$,一般$\beta_1 = 0.9,\beta_2 = 0.999,\epsilon = 10^{-8}$
在梯度下降时,如果是固定的学习率$\alpha$,在到达最小值附近的时候,可能不会精确收敛,会很抖动,因此很难达到最小值,所以可以考虑学习率衰减,在迭代过程中,逐渐减小$\alpha$,这样一开始比较快,后来慢慢的变慢。
常用的是:
$$a= \frac{1}{1 + decayrate * \text{epoch_num}} a_{0}$$
$$a =\frac{k}{\sqrt{\text{epoch_num}}}a_{0}$$
$$a =\frac{k}{\sqrt{t}}a_{0}$$