一、优化器介绍
tensorflow优化器
1 | tf.train.GradientDescentOptimizer |
1)GradientDescent梯度下降法
TF函数实现:
tf.train.GradientDescentOptimizer
设:
$h_W(x)=W_1x$,其参数是W_1,则其损失函数是:
$J(W_1)=\frac{1}{2m}\sum^{m}_{i=1}(h_W(x^{i})-y^{i})^2$
则W1W1通过如下求得:
$minimize\ J(W_1)$
标准梯度下降法:标准梯度下降先计算所有样本汇总误差,然后根据总误差来更新权值。
随机梯度下降法:随机梯度下降随机抽取一个样本来计算误差,然后更新权值。
批量梯度下降法:批量梯度下降算是一种折中的方案,从总样本中选取一个批次(比如一共有10000个样本,随机选取100个样本作为一个batch),然后计算这个batch的总误差,根据总误差来更新权值。
问题
1.合适的学习率,α 比较难获得
α 过大导致震荡无法得到最优解,过小导致学习过程漫长。
2.对所有参数学习率只有一个,如果数据是稀疏的,并且特征具有不同的频率时,更倾向于对不同频率特征使用不同的学习率,对很少发生的特征采用较大的学习率。
3.目标函数门限需要提前定义,一旦计算中小于门限就停止,数据调度训练的选择对其有影响,通常使用shuffle打断以减小这种影响。
4.高维非凸误差函数最小求解技术难度大。
2)Momentum
TF函数实现:
tf.train.MomentumOptimizer
动量法
ρ:动力通常设为 0.9
$W_t=ρW_{t-1}-η\nabla_W {J(W)}$
当前权值的改变会受到上一次全职改变的影响,类似小球向下滚动的时候带上了惯性。这样可以加快小球向下的速度。
3)NAG(Nesterov accelerated gradient)
TF函数实现:
tf.train.MomentumOptimizer
$W_t=ρW_{t-1}-η\nabla_W {J(W-ρW_{t-1})}$
NAG在TF中跟Momentum合并在同一个函数tf.train.MomentumOptimizer中,可以通过参数配置启用。在Momentum中小球会盲目跟从下坡的梯度,容易发生错误,所以我们需要一个更聪明的小球,这个小球提前知道它要去哪里,它还要知道走到坡底的时候速度慢下来而不是又冲上另一个坡。我们可以提前计算下一个位置的梯度,然后使用到当前位置。
4)Adagrad
TF函数实现:
tf.train.AdagradOptimizer
tf.train.AdagradDAOptimizer
Adagrad会累加之前所有的梯度平方。
$ΔW_t=-\frac η{\sqrt{\sum_{τ}^{t}g_τ^2+ϵ}}⨀g_t$
$W_{t+1}=W_t-\frac η{\sqrt{\sum_{τ}^{t}g_τ^2+ϵ}}⨀g_t$
通常上述的求和针对一个窗长w求解,以减小运算量。
它是基于SGD的一种算法,它的核心思想是对比比较常见的数据给予它比较小的学习率去调整参数,对于比较罕见的数据给予它较大的学习率去调整参数。它很适合应用于数据稀疏的数据集(比如一个图片的数据集,有10000张狗的照片,10000张猫的照片,只有100张大象的照片)。
Adagrad主要的优势在于不需要人为的调节学习率,它可以自动调节。它的缺点在于,随着迭代次数的增多,学习率也会越来越低,最终会趋向于0。
5)RMSprop
TF函数实现:
tf.train.RMSPropOptimizer
$E|g^2|_t=0.9E|g^2|_{t-1}+0.1g^2_t$
$W_{t+1}=W_t-\frac η{\sqrt {E|g2|_t+ϵ}}⨀g_t$
学习速率梯度均方根均值指数衰减。
RMSprop借鉴了一些Adagrad的思想,不过这里RMSprop只用到了前t-1次梯度平方的平均值加上当前梯度的平方的和的开平方作为学习率的分母。这样RMSprop不会出现学习率越来越低的问题,而且也能自己调节学习率,并且可以有一个比较好的效果。
6)Adadelta
TF函数实现:
tf.train.AdadeltaOptimizer
该算法不需要手动调优学习速率α,抗噪声能力强,可以选择不同的模型结构。
Adadelta是对Adagrad的扩展。Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是计算对应的平均值。
上一节的参数更新模型是:
$W_{t+1}=W_t - α\frac{dJ(W)}{dW_t}$
为方便,把$\frac{dJ(W)}{dW_t}$记作$g_t$,把平滑后的梯度记作$E|g|_t$,则其平方表示如下:
$E|g^2|_t = ρE|g^2|_{t-1}+(1-ρ)g^2_t$
其中ρ是平滑/衰减因子。其均方根得到的该值如下:
$RMS|g|_t=\sqrt {E|g^2|_t+ϵ}$
其中ϵ是为了防止后续计算分母为零而引入的参数常量。
$ΔW=-\frac{RMS|ΔW|_{t-1}}{RMS|g|_t}g_t$
$W_t+1=W_t+ΔW_t$
Adadelta t时刻跟新过程如下:
前提衰减因子ρ,常数ϵ,初始的W值。
1 计算变量E|g2|0=0E|g2|0=0,E|ΔW2|0=0E|ΔW2|0=0
2: for t=1:T do %%Loop over #of updates
3: 计算梯度:$g_t $
4: 滑动平均梯度:$E|g^2|_t = ρE|g^2|_{t-1}+(1-ρ)g^2_t$
- 计算参数跟新$ΔW=-\frac{RMS|ΔW|_{t-1}}{RMS|g|_t}g_t$
- 计算更新$E|Δx^2|_t=ρE|ΔW^2|_{t-1} + (1-ρ)W^2$
- 更新参数$W_{t+1}=W_t+ΔW_t$
8.end for
7)Adam
TF函数实现:
tf.train.AdamOptimizer
Adam(Adaptive Moment Estimation)加上了bias校正和momentum,在优化末期,梯度更稀疏时,它比RMSprop稍微好点。
$m_t=β_1m_{t-1}+(1-β_1)g_t$
$v_t=β_2v_{t-1}+(1-β_2)g^2_t$
其中$m_t$是梯度均值,$v_t$是梯度偏方差。这两个值初始化时为0的张量。在训练开始时,$m_t$和$v_t$趋向于零。可以使用如下估计方法抵消:
$\hat m_t=\frac{m_t}{1-β^t_1}$
$\hat v_t=\frac {v_t}{1-β^t_2}$
$W_{t+1}=W_t-\frac η{\sqrt{\hat v_t+ϵ}}\hat m_t$
就像Adadelta和RMSprop一样Adam会存储之前衰减的平方梯度,同时它也会保存之前衰减的梯度。经过一些处理之后再使用类似Adadelta和RMSprop的方式更新参数。
tf.train.FtrlOptimizer
tf.train.ProximalGradientDescentOptimizer
tf.train.ProximalAdagradOptimizer
其它梯度优化方法
1.数据重拍(shuffle函数)和数据多次重复训练
2.批量归一化,防止逐级训练中的梯度消失和溢出
3.提前终止,防止过拟合,监控验证数据集在训练中的损失,合适时提前终止。
4.增加高斯分布的梯度噪声,
$g_{t,i}=g_{t,i}+N(0,δ^2)$
$δ^2_t=\frac η{(1+t)^γ}$
这使得网络对初始化不敏感。
二、总结
如何选用optimizer
- 对于稀疏数据:
使用学习率可自适应的优化方法如:RMSprop,不用手动调节,而且最好采用默认值 - 追求精度:
SGD。虽然通常训练时间更长,容易陷入鞍点,但是在好的初始化和学习率调度方案的情况下,结果更可靠 - 如果在意更快的收敛,并且需要训练较深较复杂的网络时:
推荐使用学习率自适应的优化方法,如:Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。NAG收敛也比较快。