c2w2_优化算法

发布时间 2023-11-17 23:32:49作者: newbe3three

优化算法

机器学习是一个高度依赖经验的过程,需要在成千上万的数据上迭代多次来得到最小化损失函数的目的。所以对于如此大规模的数据,需要通过对算法进行优化来提高训练模型的效率。

mini-batch梯度下降法

此前,我们通过向量化,一次迭代就可以在所有的训练样本上进行梯度下降的运算,对此我们称之为batch梯度下降

batch梯度下降算法,在遍历所有(\(m\)个)训练样本之后才进行一次梯度下降的计算。随着样本数量\(m\)的增大,整个训练速度会变慢,那么进行一次梯度下降的算法成本就比较大。

为此,引入了mini-batch,即每次选择训练集中的一小部分数据来进行梯度下降的计算,就提高了一次梯度下降的效率。所以,我们将训练集整体按照mini-batch进行分隔,在每个mini-batch上都进行一次梯度下降的算法就是mini-batch梯度下降法。对整个训练集的一次遍历称为一个 epoch。

mini-batch的大小是一个超参数,通常选择的大小为64、128、256、1024等2n

mini-batch梯度下降算法的优点是,训练效率高,在一次迭代中进行多次梯度下降的计算。另外需要说明的是,由于不同mini-batch数据较少,不同batch之间数据的特征可能差异比较大,噪声比较大,所以损失函数在图像上可能体现为小范围内抖动。

image

mini-batch大小的选择

当mini-batch大小为1的随机梯度下降法(stochastic gradient descent,SGD),此时每个样本都是一个独立的mini-batch。

  • 对每个样本执行一次梯度下降,训练速度快,但是损失了向量化带来的计算加速
  • 有很多噪声,可以适当减小学习率
  • 成本函数总体趋势向全局最小值靠*,但永远不会收敛,而是一直在最小值附*波动。

当mini-batch大小为\(m\)(数据集大小)时,就是batch梯度下降法。

  • 对所有 m 个训练样本执行一次梯度下降,每一次迭代时间较长,训练过程慢
  • 相对噪声低一些,幅度也大一些;
  • 成本函数总是向减小的方向下降。

综上所示,要选择合适的mini-batch大小进行梯度下降,既可以实现快速学习,又可以应用向量化的优点,且容易得比较优秀的结果。

mini-batch大小的选择

  1. 如果训练样本比较少,数据小于2000时,可以采用batch梯度下降法
  2. 如果训练样本比较多,就采用mini-batch梯度下降法。mini-batch 大小为 2 的幂次时运行要快一些。所以通常的选择有64、128、256等。

获得mini-batch的步骤

  1. 将数据集打乱;
  2. 按照约定的大小分割数据集;

打乱数据集的代码

m = X.shape[1] 
permutation = list(np.random.permutation(m))
shuffled_X = X[:, permutation]
shuffled_Y = Y[:, permutation].reshape((1,m))

np.random.permutationnp.random.shuffle有两处不同:

  1. 如果传给permutation一个矩阵,它会返回一个洗牌后的矩阵副本;而shuffle只是对一个矩阵进行洗牌,没有返回值。
  2. 如果传入一个整数,它会返回一个洗牌后的arange

符号表示

  • 使用上角小括号 i 表示训练集里的值,\(x^{(i)}\)是第 i 个训练样本;
  • 使用上角中括号 l 表示神经网络的层数,\(z^{[l]}\)表示神经网络中第 l 层的 z 值;
  • 现在引入大括号 t 来代表不同的 mini-batch,因此有 \(X^t\)\(Y^t\)

指数加权*均

指数加权*均(Exponentially Weight Average)是一种常用的序列数据处理方式,计算公式为:

\[S_t = \begin{cases}Y_1\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,t=1\\\beta S_{t-1}+(1-\beta)Y_t,\,\,t>1\\\end{cases} \]

其中\(Y_t\)\(t\)下的实际值,\(S_t\)\(t\)下加权*均后的值,\(\beta\)为权重值。

指数加权*均数在统计学中被称为“指数加权移动*均值”。

image

给定一个时间序列,例如伦敦一年每天的气温值,图中蓝色的点代表真实数据。对于一个即时的气温值,取权重值 β 为 0.9,根据求得的值可以得到图中的红色曲线,它反映了气温变化的大致趋势。

当取权重值 β=0.98 时,可以得到图中更为*滑的绿色曲线。而当取权重值 β=0.5 时,得到图中噪点更多的黄色曲线。β 越大相当于求取*均利用的天数越多,曲线自然就会越*滑而且越滞后。

理解指数加权*均

当 β 为 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}\\ ...... \]

所以第100天的加权*均后的值为,

\[v_{100} = 0.1\theta_{100}+0.1\times0.9\theta_{99}+0.1\times(0.9)^2\theta_{98}+...... \]

其中$ θ_i \(指第 i 天的实际数据。所有\) θ$ 前面的系数(不包括 0.1)相加起来为 1 或者接*于 1,这些系数被称作偏差修正(Bias Correction)

当 β 为 0.9 时,可以当作把过去 10 天的气温指数加权*均作为当日的气温,因为 10 天后权重已经下降到了当天的 1/3 左右。同理,当 β 为 0.98 时,可以把过去 50 天的气温指数加权*均作为当日的气温。

因此,在计算当前时刻的*均值时,只需要前一天的前一天的*均值和当前时刻的值。

\[v_t = \beta v_{t-1} + (1-\beta)\theta_t \]

所以,在代码中只需要不断更新v即可,

\[v:=\beta v+ (1-\beta)\theta_t \]

指数*均加权并不是最精准的计算*均数的方法,你可以直接计算过去 10 天或 50 天的*均值来得到更好的估计,但缺点是保存数据需要占用更多内存,执行更加复杂,计算成本更加高昂。

指数加权*均数公式的好处之一在于它只需要一行代码,且占用极少内存,因此效率极高,且节省成本

指数加权*均的偏差修正

通常,我们会初始化\(v_0=0\)来开始计算指数加权*均,那么根据公式\(v_1=0.98v_0+0.02\theta_1\),此时可以得到\(v_1=0.02\theta_1\),显然不准确。往后递推同理。

因此,修改公式为

\[v_t = \frac{\beta v_{t-1} + (1-\beta)\theta_t}{1-\beta^t} \]

随着 t 的增大,β 的 t 次方趋*于 0。因此当 t 很大的时候,偏差修正几乎没有作用,但是在前期学习可以帮助更好的预测数据。在实际过程中,一般会忽略前期偏差的影响。

实际上,这种偏差的影响会随着迭代次数的增大而越来越小。

动量梯度下降法

动量梯度下降(Gradient Descent with Momentum)用指数加权*均的值来做为梯度进行梯度下降运算。具体的过程为:

\[v_{dW^{[l]}}=\beta v_{dW^{[l]}}+(1-\beta)dW^{[l]}\\ v_{db^{[l]}}=\beta v_{db^{[l]}}+(1-\beta)db^{[l]}\\ W^{[l]}:=W^{[l]}-\alpha v_{dW^{[l]}}\\ b^{[l]}:=b^W{[l]}-\alpha v_{db^{[l]}} \]

其中,动量衰减超参数β通常会设置为0.9,即使得梯度下降变得*滑,又能保证指数加权*均的误差不会太大。

image

随机梯度下降算法的表现如图上蓝色曲线,由于在竖轴上波动较大,所以只能选择较小的学习率来进行迭代。如果选择学习率较大,结果可能会像紫色曲线所示,下降得太快导致错过到最优解。所以只能选择小的学习率缓慢学习。

使用动量梯度下降法时,将前面几层的梯度以加权*均的方式带入当前层的梯度中,使得梯度下降的曲线变得*缓(就像之前天气的例子),降低了竖轴方向上的波动,加速了收敛,因此在横轴方向上移动得更快,就像图中红色曲线所示。

当前后梯度方向一致时,动量梯度下降能够加速学习;而前后梯度方向不一致时,动量梯度下降能够抑制震荡。

其实就是通过前面几层的*均结果来影响当前层的梯度,梯度方向相同,加快学习;梯度方向不同,减缓下降的速度。就像给下落的球施加力,方向相同力更大;方向不同,力的作用会中和一下。所以就是动量梯度下降。。因为,实现指数加权*均值计算的代价小,所以不用*均数。

此外,在 多次迭代之后,指数加权*均值的偏差的影响以及微乎其微,所以在实际的动量梯度下降法中,一般不会进行偏差的修正。

RMSProp算法

RMSProp(Root Mean Square Propagation,均方根传播)算法是在对梯度进行指数加权*均的基础上,引入*方和*方根。具体过程为:

\[s_{dw} = \beta s_{dw} + (1 - \beta)(dw)^2 \\ s_{db} = \beta s_{db} + (1 - \beta)(db)^2 \\ w := w - \alpha \frac{dw}{\sqrt{s_{dw} + \varepsilon}} \\ b := b - \alpha \frac{db}{\sqrt{s_{db} + \varepsilon}} \]

其中,ϵ 是一个实际操作时加上的较小数(例如10^-8),为了防止分母太小而导致的数值不稳定。

如下图所示,蓝色轨迹代表初始的移动,可以看到在 b 方向上走得比较陡峭(即\(db\)较大),相比起来\(dw\)较小,这影响了优化速度。因此,在采用 RMSProp 算法后,由于\((dw)^2\)较小、\((db)^2\)较大,进而\(s_{dw}\)也会较小、\(s_{db}\)也会较大,最终使得\(\frac{dw}{\sqrt{s_{dw} + \varepsilon}}\)较大,而\(\frac{db}{\sqrt{s_{db} + \varepsilon}}\)较小。后面的更新就会像绿色轨迹一样,明显好于蓝色的更新曲线。RMSProp 减小某些维度梯度更新波动较大的情况,使下降速度变得更快。

image

RMSProp 有助于减少抵达最小值路径上的摆动,并允许使用一个更大的学习率 α,从而加快算法学习速度。并且,它和 Adam 优化算法已被证明适用于不同的深度学习网络结构。

Adam优化算法

Adam 优化算法(Adaptive Moment Estimation,自适应矩估计)基本上就是将 Momentum 和 RMSProp 算法结合在一起,通常有超越二者单独时的效果。具体过程如下(省略了 l):

首先进行初始化:

\[v_{dW} = 0, s_{dW} = 0, v_{db} = 0, s_{db} = 0 \]

用每一个mini-batch计算dW、db,第t次迭代时:

\[v_{dW} = \beta_1 v_{dW} + (1 - \beta_1) dW \\ s_{dW} = \beta_2 s_{dW} + (1 - \beta_2) (dW)^2\\ v_{db} = \beta_1 v_{db} + (1 - \beta_1) db \\ s_{db} = \beta_2 s_{db} + (1 - \beta_2) (db)^2 \]

一般Adam算法需要计算偏差修正

\[v^{corrected}_{dW} = \frac{v_{dW}}{1 - (\beta_1)^t} \\ s^{corrected}_{dW} = \frac{s_{dW}}{1 - (\beta_2)^t}\\ v^{corrected}_{db} = \frac{v_{db}}{1 - (\beta_1)^t} \\ s^{corrected}_{db} = \frac{s_{db}}{1 - (\beta_2)^t}\\ \]

所以,更新 W、b 时有:

\[W = W - \alpha \frac{v^{corrected}_{dW}}{\sqrt{s^{corrected}_{dW}} + \varepsilon}\\ b = b - \alpha \frac{v^{corrected}_{db}}{\sqrt{s^{corrected}_{db}} + \varepsilon} \]

超参数的选择

Adam优化算法有很多超参数,其中

  • 学习率 α:需要尝试一系列的值,来寻找比较合适的;
  • β1:常用的缺省值为 0.9;
  • β2:Adam 算法的作者建议为 0.999;
  • ϵ:不重要,不会影响算法表现,Adam 算法的作者建议为 10−810−8

β1、β2、ϵ 通常不需要调试。

学习率衰减

如果设置一个固定的学习率\(\alpha\),当损失处于最小值附*时,由于不同batch中特征的微小区别,会导致一些噪声使得结果不能精确收敛,而是在最小值附*的一个范围内波动。

但是如果学习率\(\alpha\)能随着训练慢慢减小,那么在初期\(\alpha\)较大时,梯度下降的步长比较大,能以较快的速度进行梯度下降;而在后期逐渐减小\(\alpha\),减小下降的步长,有助于函数的收敛,更容易接*最优解。

  • 最常用的学习率衰减方法:

\[\alpha := \frac{1}{1 + decay\_rate * epoch\_num} \alpha \]

其中,decay_rate为衰减率(超参数),epoch_num为将所有的训练样本完整过一遍的次数。

  • 指数衰减

\[\alpha := 0.95^{epoch\_num} * \alpha \]

  • 其他

\[\alpha := \frac{k}{\sqrt{epoch\_num}} * \alpha \]

甚至于在较小模型时,也有人会在训练时根据进度手动调小学习率。

局部最优解问题

image

鞍点(saddle)是函数上的导数为零,但不是轴上局部极值的点。当我们建立一个神经网络时,通常梯度为零的点是上图所示的鞍点,而非局部最小值。减少损失的难度也来自误差曲面中的鞍点,而不是局部最低点。因为在一个具有高维度空间的成本函数中,如果梯度为 0,那么在每个方向,成本函数或是凸函数,或是凹函数。而所有维度均需要是凹函数的概率极小,因此在低维度的局部最优点的情况并不适用于高维度。

结论:

  • 在训练较大的神经网络、存在大量参数,并且成本函数被定义在较高的维度空间时,困在极差的局部最优中是不大可能的;
  • 鞍点附*的*稳段会使得学习非常缓慢,而这也是动量梯度下降法、RMSProp 以及 Adam 优化算法能够加速学习的原因,它们能帮助尽早走出*稳段。