新闻动态

深度学习之6——网络优化

seo靠我 2024-02-25 00:40:33

当前神经网络模型的难点:

优化问题:神经网络模型是一个非凸函数,再加上在深度网络中的梯度消失问题,很难进行优化;另外深层神经网络一般参数比较多,训练数据也比较大,会导致训练的效率比较低泛化问题:因为神经网络的拟合能力强,反而容易在训练集上产生过拟合,因此在训练深层神经网络时,同时也需要通过一定的正则化方法来改善网络的泛化能力。

那么为了得到一个好的网络模型,需要从优化和正则化两个方面来考虑。

网络优化

深层神经网络是一个高度非线性的模型,其风险函数是一个非凸函数,因此风险最小化是一个非凸优化问题,会存在很多局部最优点。

网络优化的难点

网络结构的多样性:现如今的神经网络结构中,比如卷积网络、循环网络等,其结构也是不相同,有些结构比较深,有些又比较宽。不同参数在网络中的作用也有很大的差异,如连接权重和偏置的不同,以及循环网络中循环连接上的权重和其他权重不同。所以很难找到一种通用的优化方法,不同的优化方法在不同网络结构的差异也比较大。另外网络的超参数也比较多,给化带来很大的挑战。

高维度变量的非凸优化:低维空间的非凸优化问题主要存在一些局部最优点。基于梯度下降的优化方法会陷入局部最优点。因此低维空间非凸优化的主要难点是如何选择初始化参数以及逃离局部最优点。深层神经网络的参数非常多,其参数学习是在非常高维空间中的非凸优化问题,其挑战和在低维空间的非凸优化问题有所不同。

鞍点:高维空间中,非凸优化的难点并不在于如何逃离局部最优点,而是如何逃离鞍点(Saddle Point)。鞍点的梯度为0,但是在一些维度上是最高点,在另一些维度上是最低点。

如图在x轴方向是最高点,在y轴方向是最低点

但是高维空间中,局部最优点要求在每一维度上都是最低点,这样的概率是非常低的。假设网络有10000维参数,一个点在某一维度是局部最低点的概率为p,那么在整个参数空间中,局部最优点的概率为 p10000p^{10000} ,可能性非常小。换句话说,高维空间,大部分梯度为0的点都是鞍点,基于梯度下降的优化方法会在鞍点附近停滞,同样也很难从鞍点中逃离。

平坦底部:深层神经网络的参数非常多,并且有一定的冗余性,这使得每个参数对最终损失的影响都比较小,这导致了损失函数在局部最优点附近是一个平坦的区域,称为平坦最小值。在非常大的神经网络中,大部分局部最小值是相等的。虽然神经网络有一定概率收敛于比较差的局部最小值,但随着网络规模增加,网络陷入局部最小值的概率将大大降低。

优化算法

深层网络的参数学习主要通过梯度下降方法来寻找一组最小化结构风险的参数,一般可以分为:批量梯度下降、随机梯度下降以及小批量梯度下降三种形式。根据收敛效果和效率上的差异,这三种方法都存在一些共同的问题:(1)如何初始化参数;(2)预处理数据;(3)如何选择合适的学习率,避免陷入局部最优点。

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

TT 为整个训练集,为了使得损失函数能够达到全局最优值,对权值的更新公式为:

ℑT(θ)=−1m∑i=1m∂Γ(y(m)−f(x(m),θ))∂θ\Im_T(\theta)=-\frac{1}{m}\sum_{i=1}^{m}{\frac{\partial \Gamma(y^{(m)}-f(x^{(m)},\theta))}{\partial \theta}}

ℑ(·)\Im(·) 为可微分的损失函数,m为训练集样本总个数。

θt=θt−αℑm(θ)\theta_{t}=\theta_t-\alpha\Im_m (\theta)

它得到的会是一个全局最优解,但是每个Iteration,都要用到训练集所有的数据,如果训练集规模很大的话,计算资源占用会很大,计算效率会变慢。

随机梯度下降(Stochastic Gradient Descent,SGD)[1]

批量梯度下降每次更新参数都需要用到所有的样本,随机梯度下降的区别在于每更新一次参数所用到的样本数只有1个,且是随机选取的。

ℑl(θ)=∂Γ(y(l),f(xl,θ))∂θ\Im_{l}(\theta)=\frac{\partial \Gamma(y^{(l)},f(x^{l},\theta))}{\partial \theta}ll 为样本数以内的随机数。

θt=θt−1−αℑl(θ)\theta_{t}=\theta_{t-1}-\alpha\Im_l (\theta)

假如训练集有十万个样本,对比于批量梯度下降,每次迭代都需要十万个样本,随机梯度下降有可能只需要其中5万个样本就可以达到最优解。但是SGD伴随的一个问题是对噪音数据比较敏感,遇到噪音数据时,随机梯度下降的方向有可能就不是朝着最优解方向,因此优化过程比较“曲折”。另外,因为每次只用到一个样本进行参数优化的缘故,因此得到最优解之前可能需要经历成千上万次的迭代,这也影响了计算的效率。

小批量梯度下降(Mini-Batch Stochastic Gradient Decsent,MBSGD)

目前在训练深层网络时,由于数据规模比较大,在梯度下降时,每次迭代都要计算整个训练数据上的梯度需要占用很大的计算资源,大规模训练集中的数据通常是非常冗余的,没必要在整个训练集计算梯度,在训练深层网络时,经常会用到小批量梯度下降法。

f(x,θ)f(x,\theta) 表示一个深层神经网络, θ\theta 为网络参数,在使用小批量梯度下降进行优化时,每次随机选取K个样本 T={(x(k),y(k))}k=1KT=\{(x^{(k)},y^{(k)})\}^K_{k=1} ,第t次迭代(iteration)时损失函数关于参数 θ\theta 的偏导数为:

ℑT(θ)=1K∑(x(k),y(k))∈T∂Γ(y(k),f(x(k),θ))∂θ\Im_T(\theta)=\frac{1}{K}\sum_{(x^{(k)},y^{(k)})\in T}^{}{\frac{\partial \Gamma(y^{(k)},f(x^{(k)},\theta))}{\partial \theta}} (这里忽略了正则化项)

K为批量大小(Batch Size)。

第t次更新的梯度 gtg_t 定义为: gt⇐gt(θt−1)g_t\Leftarrow g_t(\theta_{t-1})

使用梯度下降来更新参数, θt←θt−1−αgt\theta_t\leftarrow \theta_{t-1}-\alpha g_tα\alpha 为学习率)

每次迭代时参数更新的差值 Δθt⇐θt−θt−1\Delta \theta_t\Leftarrow \theta_t-\theta_{t-1}

Δθt\Delta \theta_t 和梯度 gtg_t 并不需要完全一致, Δθt \Delta\theta_t 为每次迭代时参数的实际更新方向,即 θt=θt−1+Δθt\theta_t=\theta_{t-1}+\Delta\theta_t ,在标准小批量梯度下降中, Δθt=−αgt\Delta\theta_t=-\alpha g_t

在MNIST数据集上,批量大小对损失下降的影响:

一般批量较小时,需要设置较小的学习率,否则模型容易不收敛。每次迭代选取的批量样本数越多,下降效果越明显,下降曲线越平滑。每次选取一个样本时(随机梯度下降),损失整体是下降趋势,但局部看来会有震荡,如果按照整个数据集上的迭代次数(epoch)来看损失变化情况,则是批量样本数越小,下降效果越明显。(epoch和Iteration(单次更新)的关系为1个epoch等于 训练样本总数批量大小训练样本总数N批量大小K\frac{训练样本总数N}{批量大小K} 次Iterations)。

梯度下降速度优化:学习率衰减

在标准的小批量梯度下降基础上,做一些速度优化的改进,主要是从学习率衰减和梯度方向优化两个角度去考虑

梯度下降过程中,学习率α的值很重要,如果过大容易错过最优导致不会收敛,如果过小则收敛速度太慢。从经验上看,学习率一开始要保持大些来保证收敛速度,在收敛到最优点附近时要小些以避免来回震荡。

假设初始学习率为 α0\alpha_0 ,在第t次迭代时的学习率 αt\alpha_t ,常用的衰减方式为可以设置为按迭代次数进行衰减,比如

逆时衰减(inverse time decay): αt=α011+β×t\alpha_t=\alpha_0\frac{1}{1+\beta \times t}

指数衰减(exponential decay): αt=α0βt\alpha_t=\alpha_0 \beta^t

自然指数衰减(natural exponential decay): αt=α0exp(−β×t)\alpha_t=\alpha_0 exp(-\beta \times t)

β\beta 为衰减率,一般取值为0.99。

自适应学习率调整

AdaGrad算法

在第t次迭代时,先计算每个参数梯度平方的累计值:

Gt=∑τ=1tgτ⊙gτG_t=\sum_{\tau=1}^{t}{g_\tau \odot g_\tau}\odot 为按元素乘积, gτ∈R|θ|g_\tau\in R^{|\theta|} 是第 τ\tau 次迭代的梯度。

Δθt=−α0Gt+ϵ⊙gt\Delta\theta_t=-\frac{\alpha_0}{\sqrt{G_t+\epsilon}}\odot g_t

ϵ\epsilon 是为了保持数值稳定性而设置的非常小的常熟,一般取值 ϵ−7\epsilon^{-7}ϵ−10\epsilon^{-10} ,此外这里的开平方、除、加法运算都是按位操作。

在Adagrad算法中,如果某个参数的偏导数累计比较大,其学习率相对较小;相反如果其偏导数累计较小,其学习率相对较大,整体是随着迭代次数的增加,学习率逐渐变小。

缺点是经过一定次数的迭代依然没有找到最优点,由于此时学习率已经非常小,很难再继续找到最优点。

RMSprop算法

可以避免Adagrad算法中学习率不断单调下降以至于过早衰减的缺点。

RMSprop算法首先计算每次迭代梯度 gtg_t 平方的指数衰减移动平均,

Gt=βGt−1+(1−β)gt⊙gtG_t=\beta G_{t-1}+(1-\beta)g_t\odot g_t

⇒(1−β)∑τ=1tβt−τgτ⊙gτ\Rightarrow (1-\beta)\sum_{\tau=1}^{t}{\beta^{t-\tau}}g_\tau\odot g_\tau

β\beta 为衰减率,一般取值为0.9。

Δθt=−α0Gt+ϵ⊙gt\Delta\theta_t=-\frac{\alpha_0}{\sqrt{G_t+\epsilon}}\odot g_t

RMSProp算法和Adagrad算法区别在于 GtG_t 的计算由累积方式变成了指数衰减移动平均,在迭代过程中,每个参数的学习率并不是呈衰减趋势,既可以变大也可以变小。

AdaDelta算法

AdaDelta算法通过梯度平方的指数衰减移动平均来调整学习率,此外AdaDelta算法还引入了每次参数更新差 Δθ\Delta\theta 的平方的指数衰减权移动平均。

第t次迭代时,每次参数更新差 Δθτ\Delta\theta_\tau1≤τ≤t−11\leq \tau\leq t-1 的指数衰减权移动平均为:

ΔXt−12=β1ΔXt−22+(1−β1)Δθt−1⊙Δθt−1\Delta X^2_{t-1}=\beta_1\Delta X^2_{t-2}+(1-\beta_1)\Delta\theta_{t-1}\odot\Delta\theta_{t-1}

其中 β1\beta_1 为衰减率,此时 Δθt\Delta\theta_t 还未知,只能计算到 ΔXt−1\Delta X_{t-1}

Δθt=−ΔXt−12+ϵGt+ϵgt\Delta\theta_t=-\frac{\sqrt{\Delta X^2_{t-1}+\epsilon}}{\sqrt{G_t+\epsilon}}g_t

GtG_t 的计算方式和RMSprop算法一样, ΔXt−12\Delta X^2_{t-1} 为参数更新差 Δθ\Delta \theta 的指数衰减权移动平均

AdaDelta算法将RMSrop算法中的初始学习率α改为动态计算的 ΔXt−12\sqrt{\Delta X^2_{t-1}} ,一定程度上抑制了学习率的波动。

梯度下降速度优化:梯度方向的优化

除了调整学习率之外,还可以通过使用最近一段时间内的平均梯度来代替当前时刻的梯度作为参数更新的方向,在小批量梯度下降中,如果每次选取样本数量较小,损失会呈现只震荡的方式下降。有效的缓解梯度下降中的震荡的方式是通过梯度的移动平均来代替每次的实际梯度,并提高优化速度,称为动量法。

动量法

用之前累动量来代替真正的梯度,每次迭代的梯度可以看作是加速度。

在第t次迭代时,计算负梯度的“加权移动平均”作为参数的更新方向,

Δθt=ρΔθt−1−αgt\Delta\theta_t=\rho\Delta\theta_{t-1}-\alpha g_tρ\rho 为动量因子,通常设为0.9。

每个参数的实际更新差值取决于最近一段时间内梯度的加权平均值:某个参数在最近一段时间内的梯度方向不一致时,其真实的参数更新幅度变小;当在一段时间内的梯度方向都一致时,其真实的参数更新幅度变大,起到加速作用,可以更快地到达最优点。

在迭代初期,梯度方向都比较一致,动量法会起到加速作用更快到达最优点。迭代后期,梯度方向会在收敛值附近震荡,动量法会起到减速的作用增加稳定性。

Nesterov加速梯度/动量法(NAG)

在动量法中,实际的参数更新方向 Δθt\Delta\theta_t 为上一步的参数更新方向 Δθt−1\Delta\theta_{t-1} 和当前梯度 −gt-g_t 的叠加。 Δθt\Delta\theta_t 可以被拆分为两步进行,先根据 Δθt−1\Delta\theta_{t-1} 更新一次得到参数 θ~\tilde{\theta} ,再用 gtg_t 进行更新:

θ~=θt−1+ρΔθt−1\tilde{\theta}=\theta_{t-1}+\rho\Delta\theta_{t-1}θt=θ~−αgt\theta_t=\tilde{\theta}-\alpha g_t

其中 gtg_t 为点 θt−1\theta_{t-1} 上的梯度,因此在第二步更新中有些不太合理,更合理的更新方向为 θ~\tilde{\theta} 上的梯度。合并更新方向为:

Δθt=ρΔθt−1−αℑt(θt−1+ρΔθt−1)\Delta\theta_t=\rho\Delta\theta_{t-1}-\alpha \Im_t(\theta_{t-1}+\rho\Delta\theta_{t-1})

其中 ℑt(θt−1+ρΔθt−1)\Im_t(\theta_{t-1}+\rho\Delta\theta_{t-1}) 表示损失函数在点 θ~=θt−1+ρΔθt−1\tilde{\theta}=\theta_{t-1}+\rho\Delta\theta_{t-1} 上的偏导数。

AdaM算法

自适应动量估计算法可以看作动量法和RMSprop的结合,不但使用动量作为参数更新方向,可以自适应调整学习率。

AdaM算法计算梯度平方 gt2g_t^2 的指数加权平均以及 gtg_t 的指数加权平均:

Mt=β1Mt−1+(1−β1)gtM_t=\beta_1M_{t-1}+(1-\beta_1)g_t

Gt=β2Gt−1+(1−β2)gt⊙gtG_t=\beta_2G_{t-1}+(1-\beta_2)g_t\odot g_t

其中 β1\beta_1β2\beta_2 分别为两个移动平均的衰减率,通常取值为 β1=0.9,β2=0.99\beta_1=0.9,\beta_2=0.99

MtM_t 可以看作是梯度的均值, GtG_t 可以看作是梯度的未减去均值的方差(二阶矩)。

假设 M0=0,G0=0M_0=0,G_0=0 ,那么在迭代初期 Mt,GtM_t,G_t 的值会比真实均值和方差要小。特别是当 β1,β2\beta_1,\beta_2 都接近1时,偏差会很大,需要对偏差进行修正:

Mt~=Mt1−β1t\tilde{M_t}=\frac{M_t}{1-\beta_1^t}Gt~=Gt1−β2t\tilde{G_t}=\frac{G_t}{1-\beta_2^t}

Adam算法的参数更新差值:

Δθt=−αGt~+ϵMt~\Delta\theta_t=-\frac{\alpha}{\sqrt{\tilde{G_t}+\epsilon}}\tilde{M_t}

α为初始学习率,通常设定为0.001,也可以进行衰减,比如 αt=α0t\alpha_t=\frac{\alpha_0}{\sqrt{t}}

NAdaM算法

类似于带有Nesterov动量项的Adam。

gt~=gt1−∏i=1tμi\tilde{g_t}=\frac{g_t}{1-\prod_{i=1}^{t}\mu_i}

mt=μt∗mt−1+(1−μt)∗gtm_t=\mu_t*m_{t-1}+(1-\mu_t)*g_t

mt~=mt1−∏i=1t+1μi\tilde{m_t}=\frac{m_t}{1-\prod_{i=1}^{t+1}\mu_i}

nt=v∗nt−1+(1−v)∗gt2n_t=v*n_{t-1}+(1-v)*g_t^2

nt~=nt1−vtmt~=(1−μt)∗gt~+μt+1∗mt~\tilde{n_t}=\frac{n_t}{1-v^t}\tilde{m_t}=(1-\mu_t)*\tilde{g_t}+\mu_{t+1}*\tilde{m_t}

Δθt=−η∗mt~nt~+ϵ\Delta\theta_t=-\eta*\frac{\tilde{m_t}}{\sqrt{\tilde{n_t}}+\epsilon}

Nadam对学习率有更强的约束,同时对梯度的更新也有更直接的影响,一般而言,想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

优化方法小结

几种优化方式总结比较

SGD

现在的SGD一般指的都是mini-batch gradient descent,SGD就是每一次迭代计算mini-batch的梯度,然后对参数进行更新,是最常见的优化方法:gtg_t 完全依赖于batch。

缺点

选择合适的Ir比较困难,对所有参数更新同样的lr,对于稀疏数据或者特征,有时可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD不满足要求。SGD容易收敛到局部最优,并且在某些情况下可能被困在鞍点,。

Momentum

Δθt=μΔθt−1−αgt\Delta \theta_t=\mu\Delta\theta_{t-1}-\alpha g_tθt=θt−1+Δθt\theta_t=\theta_{t-1}+\Delta\theta_t , μ\mu 是动量因子

特点:

下降初期,使用上一次参数更新,下降方向一致,乘上较大的 μ\mu 可以更好地加速。下降中后期,在局部最小值来回震荡的时候, gradient→0gradient \rightarrow 0 , μ\mu 使得更新幅度增大,跳出陷阱。在梯度方向改变的时候, μ\mu 能够减少更新,momentum项能够在相关方向加速SGD,抑制震荡,加快收敛。

Nesterov

nesterov项在梯度更新时做一个校正,避免前进太快,同时提高灵敏度。将上式展开得:

θ~=θt−1+ρΔθt−1\tilde{\theta}=\theta_{t-1}+\rho\Delta\theta_{t-1} , θt=θ~−αgt\theta_t=\tilde{\theta}-\alpha g_t

momentum和nesterov都是为了使梯度更新更加灵活,对不同情况有针对性,但是人工设置一些学习率总是不太好,因此以下为自适应学习率方法

Adagrad

特点:

前期 gtg_t 较小的时候,regularizer较大,能够放大梯度。后期 gtg_t 较大的时候,regularizer较小,能够约束梯度。适合处理稀疏梯度。

缺点:

仍依赖于人工设置一个全局学习率η\eta 设置过大的话,会使regularizer过于敏感,对梯度调节太大。中后期,分母上梯度平方的累加将会越来越大,使 gradient→0gradient\rightarrow 0 ,使得训练提前停止。

Adadelta

Adagrad会累加之前所有梯度平方,而Adadelta只累加固定大小得项,并且也不直接存储这些项,仅仅是近似计算对应平均值(滑动平均值)

特点:

训练初中期,加速效果不错,很快。训练后期,反复在局部最小值附近抖动。

RMSprop

特点:

RMSprop依赖于全局学习率RMSprop算是Adagrad的一种发展,是Adadelta的变体,效果趋于二者之间适合处理非平稳目标,对于RNN效果好。

Adam

本质上是带有动量项的RMSprop,利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定的范围,使得参数比较平稳。

特点

结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点对内存需求较小为不同的参数计算不同的自适应学习率也适用于大多非凸优化 - 适用于大数据集和高维空间

经验之谈

对于稀疏数据,尽量使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠如果在意更快的收敛,并且需要训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果

参考书籍:《神经网络与深度学习》—邱锡鹏

参考博客:

ycszen:深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)2779 赞同 · 106 评论文章

参考

^随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比 https://blog.csdn.net/lilyth_lilyth/article/details/8973972
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2