深度篇——神经网络(五) 细说 优化器

返回主目录

返回神经网络目录

上一章:深度篇——神经网络(四)  细说 调优神经网络

下一章:深度篇——神经网络(六)  细说 数据增强与fine-tuning

本小节,细说 优化器,下一小节细说 数据增强与fine-tuning

对优化器的选择,包括后面的数据增强与fine-tuning,也都属于对神经网络的调优过程。

 

5. 调优神经网络

(9). 优化器

优化器示图:

a. BGD (Batch Gradient Descent, BGD) 批量梯度下降法

    BGD 采用整个训练集的数据 \large x_{sample} 来计算 cost function 和 参数的梯度:

                 \large \theta = \theta - \alpha g_{sample}

                 \large g_{sample}:为所有样本的梯度

     优点:

            对于凸函数可以收敛到全局极小值,对于非凸函数可以收敛到局部极小值

     缺点:

            由于这种方法是在一次更新中,就对整个数据集计算梯度,所以计算起来非常慢,遇到很大量的数据集也会非常棘手,而且不能投入新数据实时更新模型。

 

b. SGD (Stochastic Gradient Descent, SGD) 随机梯度下降法

    SGD 随机梯度下降更新时针对每一个样本集 \large x_{i} 和 \large y_{i}

    BGD 在数据量很大时会产生大量冗余的计算,而 SGD 每次只更新一个,因此 SGD 算法通常更快,并且适合 online,可以新增样本。

                \large \theta = \theta - \alpha g_{i}

                \large g_{i}:为样本 \large i 的梯度。

     优点:

            SGD 的震荡可能会跳到更好的局部极小值处,从而获得更好的局部最优解。

     缺点:

            SGD 因为更新比较频繁,容易造成 cost function 严重的震荡。

 

c. MBGD (Mini Batch Gradient Descent, MBGD) 小批量梯度下降法

   MBGD 小批量梯度下降法,每次利用一小批样本,即 m 个样本进行计算。这样它可以降低参数更新时的方差,收敛更稳定。可以充分利用深度学习库中高度优化的矩阵来进行更有效的梯度计算。

                 \large \theta = \theta - \alpha g_{i, \; i + m}

                 \large m:为小批量样本数,一般取值在 50 ~ 2 56

                 \large g_{i,\; i + m}:为第 \large i 到 \large i + m 个样本的梯度

     优点:

            减少了参数更新的变化,这可以带来更加稳定的收敛。

            可以充分利用矩阵优化,最终计算更加高效

     缺点:

            不能保证很好的收敛。

 

d. BGD,SGD,MBGD 算法都需要预先设置学习率,学习率的设置,往往会带来一些问题:

   (a). 选择一个合适的学习率是非常困难的事。如果整个模型计算过程中都采用相同的学习率进行计算:如果学习率太小,收敛速度将会很慢,并且容易困在并不怎么理想的局部最优解处。而学习率较大时,收敛过程将会变得非常抖动,而且有可能不能收敛到最优。

   (b). 有一种措施是先设定大一点的学习率,当两次迭代之间变化低于某个阈值后,就减少学习率。不过需要提前设定好阈值和减小学习率的规则

   (c). 当数据非常稀疏的时候,可能不希望所有数据都以相同的方式进行梯度更新,而是对这种极少的特征进行一次大的更新

   (d).对于非凸函数,关键的挑战是要避免陷于局部极小值处,或者鞍点处,因为鞍点周围的 error 都是一样的,所有维度的 梯度都接近于 零, SGD 特别容易被困在此处。 

 

e. Momentum 动量法

     momentum 是模型里动量的概念,积累之前的动量来替代真正的梯度。公式如下:

                \large g = \triangledown _{\theta} J(\theta)

                \large v_{t} = \lambda v_{t - 1} + \alpha g

                \large \theta = \theta - v_{t}

                \large g:为 梯度

                \large v_{t}:为 \large t- 1 时刻的速度(变化量)

                \large \lambda:为动量因子,一般常取 0.9

                \large \alpha:为学习率

      通过添加一个衰减因子到历史更新向量,并加上当前的更新向量。当梯度保持相同方向时,动量因子加速参数更新;而梯度方向改变时,动量因子能降低梯度的更新速度。

     优点:

            下降初期时,使用上一次参数更新,下降方向一致,乘上较大的 \large \lambda 能够进行很好的加速。

            下降中后期时,在局部最小值来回震荡的时候,梯度 \large g 趋近于 零,\large \lambda 动量因子使得更新幅度增大,跳出鞍点,加速收敛

     缺点:

            具有一定的盲目性,相当于小球从山上滚下来时,盲目地沿着坡滚,如果它能具备一些先知,例如快要上坡时,就知道需要减速的话,适应性会更好。

 

f. NAG (Nesterov Accelarated Gradient, NAG) 

   NAG 在梯度更新时,做了一个校正,避免前进太快,同时提高灵敏度。即对 Momentum 做了优化,用 \large \theta - \lambda v_{t - 1} 来近似当作参考下一步会变成的值,则在计算梯度时,不是在当前的位置,而是在未来的位置上。从而达到算法能够在目标函数有增高趋势之前,减缓更新速率,公式如下:

                  \large g = \triangledown _{\theta} J(\theta - \lambda v_{t - 1})

                  \large v_{t} = \lambda v_{t - 1} + \alpha g

                  \large \theta = \theta - v_{t}

                  \large \lambda:为动量因子,一般常取 0.9

                  \large g:为在 \large \theta - \lambda v_{t - 1} 上的梯度

  

     蓝色是 Momentum 的过程,会先计算当前的梯度,然后在更新后的累积梯度后会有一个大的跳跃。

      NAG 在梯度跳跃后,进行计算当前梯度,然后进行校正 (NAG 会先在前一步的累积梯度上(brown vector)有一个大的跳跃,然后衡量一下梯度做一下修正(red vector),这种预期的更新可以避免我们走的太快)。

 

g. AdaGrad (Adaptive Gradient Algorithm)

   AdaGrad 优化算法是一种自适应优化算法,针对高频特征更新步长较小,而低频特征更新较大。因此该算法适合应用在特征稀疏的场景。先前的算法对每一次参数更新都是采用同一个学习率,而 AdaGrad 算法每一步采用不同的学习率进行更新。公式如下:

               \large g_{t} = \triangledown _{\theta} J(\theta_{t})

               \large \theta_{t + 1} = \theta _{t} - \frac{\alpha}{\sqrt{\sum_{i = 1}^{t} g_{i}^{2} + \varepsilon }} \cdot g_{t}

               \large \alpha:为学习率,大部分采用默认值 0.01

               \large \varepsilon:为无穷小数,用来避免分母为 零。

     优点:

            减少手动调节学习率

     缺点:

            由公式可以看出,仍然依赖于人工设置一个全局学习率。

            \large \alpha 设置过大的话,会对权值调节太大,可能跳出某些效果较好的局部最优解

            分母项对梯度平方进行不断的累积,分母项越来越大,最终学习率收缩到无穷小,而使得无法进行有效更新,使得训练提前结束。(这里是将每一个时刻的所有的梯度的 \large g_{t}^{2} 都相加再 开方)

 

k. Adadelta

   Adadelta 是对 AdaGrad 的扩展,最初方案依然是对学习率进行自适应约束,但是进行了计算上的简化。AdaGrad 会累加之前所有的梯度平方,而 Adadelta 只累加固定大小的项,并且也不直接存储这些项,仅仅近似计算对应的平均值。即:

               \large g_{t} = \triangledown _{\theta} J(\theta_{t})

               \large v_{t} = \lambda v_{t - 1} + (1 - \lambda) g_{t}^{2}

               \large \triangle \theta = - \frac{\alpha}{\sqrt{v_{t} + \varepsilon }} \cdot g_{t}

               \large \theta_{t + 1} = \theta_{t} + \triangle \theta_{t}

               \large \lambda:为动量因子,通常取 0.9

               \large \alpha:为学习率,通常取 0.01

               \large \varepsilon:为无穷小数,用来避免分母为 零。

   这里相当于,只是将 \large t 时刻 所有的梯度的 \large g_{t}^{2} 相加再开方。

   分母相当于梯度的均方根 (Root Mean Squared, RMS),在数据统计分析中,将所有值平方求和,求其均值,再开平方,就得到均方根值,所以可以用 RMS 简写:

                \large \triangle \theta _{t} = - \frac{\alpha}{RMS [g]_{t}} \cdot g_{t}

  此外,如果将学习率 \large \alpha 换成 \large RMS[\triangle \theta] 的话,甚至都不需要提前设定学习率了。由于 \large RMS[\triangle \theta]_{t} 是未知的,我们用 \large RMS[\triangle \theta]_{t - 1} 来代替,最终得到:

               \large \triangle \theta_{t} = - \frac{RMS[\triangle \theta]_{t - 1}}{RMS[g]_{t}} \cdot g_{t}

               \large \theta _{t + 1} = \theta _{t} + \triangle \theta_{t}

     优点:

            可以无需手动设定学习率。

            训练初中期,加速效果不错,很快

     缺点:

            训练后期,反复在局部最小值附近抖动。

 

i. RMSprop

   RMSprop 可以算作 Adadelta 的一个特例:

   使用的是指数加权平均,旨在消除梯度下降中的摆动,与 Momentum 的效果一样,某一维度的导数比较大,则指数加权平均就大,某一维度的导数比较小,则其指数加权平均就小,这样就保证了各维度导数都在一个量级,进而减少了摆动。允许使用一个更大的学习率 \large \alpha :

             \large v_{t} = 0.9 v_{t - 1} + 0.1 g_{t}^2

             \large \theta _{t + 1} = \theta_{t} - \frac{\alpha}{\sqrt{v_{t} + \varepsilon }} \cdot g_{t}

     优点:

            适合处理非常稳定的目标,对于 RNN 效果很好。

     缺点:

            RMSprop 依然依赖于全局学习率。

 

j. Adam (Adaptive Moment Estimation, Adam)

   Adam 本质上是带有动量项饿 RMSprop (即 RMSprop + Momentum),它利用梯度的一阶矩(均值) 和 二阶矩(方差) 调整每个参数的学习率。公式如下:

            \large m_{t} = \mu \cdot m_{t - 1} + (1 - \mu) g_{t}

            \large v_{t} = \lambda v_{t - 1} + (1 - \lambda) g_{t}^{2}

            \large \bar{m}_{t} = \frac{m_{t}}{1 - \mu^{t}}

            \large \bar{v}_{t} = \frac{v_{t}}{1 - \lambda^{t}}

            \large \triangle \theta_{t} = - \frac{\alpha}{\sqrt{\bar{v}_{t}} + \varepsilon } \cdot \bar{m}_{t}

            \large \theta_{t + 1} = \theta_{t} + \triangle \theta_{t}

            \large \mu:为超参,常取 0.9

            \large \mu^{t}:为 \large \mu 的 \large t 次方

            \large \lambda:为动量因子,常取 0.999

            \large \lambda^{t}:为 \large \lambda 的 \large t 次方

            \large m_{t}:为 \large t 时刻的均值

            \large v_{t}:为 \large t 时刻的方差

            \large \varepsilon:为无穷小数,用于避免分母为 零,常取 1e-8

            \large \bar{m}_{t},\; \bar{v}_{t}:为对 \large m_{t},\; v_{t} 的校正,这样可以近似为对期望的无偏估计。

     优点:

            结合了 AdaGrad 善于处理稀疏梯度和 RMSprop 善于处理稳定目标, Adam 经过偏置核校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。

            对内存需求较小,实现简单,计算高效

            为不同的参数计算不同的自适应学习率

            也适用于大多非凸优化,适用于大数据集和高维空间。

            参数的更新不受梯度的伸缩变换影响

     缺点:

            解耦权重衰减。

            修正指数移动均值。

 

k. AdaMax

   在 Adam 更新权值的 \large v_{t} 因子的规则是 将其当前的梯度与过去的梯度适用 \large L_{2} 正则进行反比例缩放:

                   \large v_{t} = \lambda v_{t -1} + (1 - \lambda) g_{t}^{2}

   当将基于 \large L{2} 范数的规则泛化到基于 \large L_{p} 范数的更新规则时,动量因子也同样进行了泛化,由 \large \lambda \rightarrow \lambda^{p}

                   \large v_{t} = \lambda^{p} v_{t - 1} + (1 - \lambda ^{p}) |g_{t}|^{p}

   虽然这样的变体会因为 \large p 的值较大而在数值上变得不稳定。然而,当 \large p \rightarrow \infty,即 \large L_{\infty } 通常表现出稳定的行为。因此,当使用 \large L_{\infty } 来计算 \large v_{t} 时会获得比较好的收敛值。使用 \large L_{\infty } 范数约束 \large v_{t},避免了陷入 Adam 的困惑:

                   \large v_{t} = \lambda^{\infty} v_{t - 1} + (1 - \lambda^{\infty}) |g_{t}|^{\infty}

                         \large = \max (\lambda \cdot v_{t - 1}, \; |g_{t}|)

   由 Adam 的一阶矩(均值)得:

                   \large m_{t} = \mu \cdot m_{t - 1} + (1 - \mu) g_{t}

                   \large \bar{m}_{t} = \frac{m_{t}}{1 - \mu^{t}}

   当使用 \large v_{t} 来代替 Adam 更新规则中的 \large \sqrt{\bar{v}_{t}},便可得到 AdaMax 的更新规则:

                   \large \theta_{t + 1} = \theta_{t} - \frac{\alpha}{v_{t} + \varepsilon } \cdot \bar{m}_{t}

                   \large \alpha:为学习率,常取 0.002

                   \large \mu:为超参,常取 0.9

                   \large \lambda:为动量因子,常取 0.999

   在 AdaMax 中,由于 \large v_{t} 是依赖于 max 操作的,并不像 Adam 中的 \large m_{t} 和 \large v_{t} 偏向于 零 所受到的影响那么大。因此,在 AdaMax 中并不需要对 \large v_{t} 计算偏差校正。其中,为了方便,可以初始化 \large v_{0} = 0

 

l. Nadam

由 Adam 可知,Adam 可以被看作是 RMSprop + Momentum 的组合:RMSprop 贡献了过去 平方梯度指数衰减的平均值 \large v_{t},而 Momentum 则刚好是过去 梯度指数衰减的平均值 \large m_{t}。而 Nesterov 加速梯度 (NAG) 被发现比香草的 Momentum (Momentum 的作者名翻译为 香草) 更好。Nadam 就是将 Adam 和 NAG 进行组合。为了将 NAG 并入 Adam,需要修改它的动量项 \large m_{t}

 Momentum 的更新规则:

               \large g_{t} = \triangledown _{\theta_{t}} J(\theta_{t})

              \large m_{t} = \lambda m_{t-1} + \alpha g_{t}

              \large \theta_{t+1} = \theta_{t} - m_{t}

              \large \theta_{t + 1} = \theta_{t} - (\lambda m_{t -1} + \alpha g_{t})

              \large \lambda:为动量因子,或称之为衰减项

              \large \alpha:为学习率

NAG 的更新规则:

              \large g_{t} = \triangledown \theta_{t} J(\theta_{t} - \lambda m_{t -1})

              \large m_{t} = \lambda m_{t - 1} + \alpha g_{t}

              \large \theta _{t + 1} = \theta_{t} - m_{t}

              \large \theta_{t + 1} = \theta_{t} - (\lambda m_{t - 1} + \alpha g_{t})

现在直接应用前瞻动量矢量来更新当前参数,效果会比 NAG 运用两次动量好:一次用来更新梯度 \large g_{t},一次用来更新参数 \large \theta_{t + 1}

               \large g_{t} = \triangledown _{\theta_{t}} J(\theta_{t})

               \large m_{t} = \lambda m_{t - 1} + \alpha g_{t}

               \large \theta_{t + 1} = \theta_{t} - (\lambda m_{t} + \alpha g_{t})

注意,上面的更新规则并不是使用 \large m_{t - 1} 进行更新,而是使用 \large m_{t} 进行更新向前传播。为了在 Adam 中加入 Nesterov 动量,可以用现在的动量向量替换之前的动量向量。

Adam 的更新规则:

                \large m_{t} = \mu m_{t - 1} + (1 - \mu) g_{t}

                \large v_{t} = \lambda v_{t - 1} + (1 - \lambda) g_{t}^{2}

                 \large \bar{m}_{t} = \frac{m_{t}}{1 - \mu^{t}}

                 \large \bar{v}_{t} = \frac{v_{t}}{1 - \lambda^{t}}

                  \large \theta _{t + 1} = \theta_{t} - \frac{\alpha}{\sqrt{\bar{v}_{t}} + \varepsilon } \cdot \bar{m}_{t}

                  \large \theta_{t + 1} = \theta_{t} - \frac{\alpha}{\sqrt{\bar{v}_{t}} + \varepsilon } \cdot (\frac{\mu m_{t - 1}}{1 - \mu^{t}} + \frac{(1 - \mu) g_{t}}{1 - \mu^{t}})

为了简单起见,可以忽略分母是 \large 1 - \mu^{t} 而不睡 \large 1 - \mu^{t - 1},这样的话,\large \frac{\mu m_{t - 1}}{1 - \mu^{t}} 就仅是对前一个时间 \large t -1 时刻的动量矢量的偏置修正值,可以用 \large \bar{m}_{t -1} 来替代:

                   \large \theta _{t + 1} = \theta_{t} - \frac{\alpha}{\sqrt{\bar{v}_{t}} + \varepsilon } \cdot (\mu m_{t - 1} + \frac{(1 - \mu) g_{t}}{1 - \mu^{t}})

这个方程看起来就和上面的动量更新规则很相似。现在,可以像之前加上 Nesterov 动量一样,只需要替换上一步动量矢量的偏差修正值 \large \bar{m}_{t - 1} 为当前的偏差修正值 \large \bar{m}_{t},即为 Nadam 的更新规则:

                  \large \theta_{t + 1} = \theta_{t} -\frac{\alpha}{\sqrt{\bar{v}_{t}} + \varepsilon } \cdot (\mu \bar{m}_{t} + \frac{(1 - \mu) g_{t}}{1 - \mu^{t}})

 

m. 优化器的选择

(a). 对于稀疏数据,尽量使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值。

(b). SGD 通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠。如果情况不好的时候,容易陷入局部极小值或鞍点。

(c). 如果在意更快的收敛,并且需要训练较深、较复杂的网络时,推荐使用学习率自适应的优化方法

(d). Adadelta、RMSprop、Adam 是比较相近的算法,在相似的情况下,表现都差不多

(e). 在想使用袋动量的 RMSprop 或 Adam 的地方,大多可以使用 Nadam,取得的效果更好

                

返回主目录

返回神经网络目录

上一章:深度篇——神经网络(四)  细说 调优神经网络

下一章:深度篇——神经网络(六)  细说 数据增强与fine-tuning

发布了42 篇原创文章 · 获赞 15 · 访问量 2766

猜你喜欢

转载自blog.csdn.net/qq_38299170/article/details/104119038
今日推荐