您的位置:首页 > 职场人生

深度学习之参数优化方法

2018-01-03 20:37 183 查看
优化问题:给定目标函数f(x),我们需要找到一组参数x,使得f(x)的值最小

1.Vanilla update

tensorflow实现

optimizer = tf.train.GradientDescentOptimizer(learning_rate=self.learning_rate)

直接进行优化

train_op
= optimizer.minimize(loss)


x += - learning_rate * dx

对于训练数据集,我们首先将其分成n个batch,每个batch包含m个样本。我们每次更新都利用一个batch的数据,而非整个训练集。即:



好处在于:

当训练数据太多时,利用整个数据集更新往往时间上不显示。batch的方法可以减少机器的压力,并且可以更快地收敛

当训练集有很多冗余时(类似的样本出现多次),batch方法收敛更快。以一个极端情况为例,若训练集前一半和后一半梯度相同。那么如果前一半作为一个batch,后一半作为另一个batch,那么在一次遍历训练集时,batch的方法向最优解前进两个step,而整体的方法只前进一个step



2.Momentum update动量更新

tensorflow实现

optimizer = tf.train.MomentumOptimizer(lr,
0.9)

直接进行优化

train_op
= optimizer.minimize(loss)


v = mu * v - learning_rate * dx # integrate velocity

x += v # integrate position

SGD方法的一个缺点是,其更新方向完全依赖于当前的batch,因而其更新十分不稳定。解决这一问题的一个简单的做法便是引入momentum。

momentum即动量,它模拟的是物体运动时的惯性,即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力: 





其中一般的,v初始为0,mu是优化参数,一般初始化参数为0.9,当使用交叉验证的时候,参数mu一般设置成[0.5,0.9,0.95,0.99],在开始训练的时候,梯度下降较快,可以设置mu为0.5,在一段时间后逐渐变慢了,mu可以设置为0.9、0.99。也正是因为有了“惯性”,这个比SGD会稳定一些。



3.Nesterov Momentum

x_ahead = x + mu * v 
v = mu * v - learning_rate * dx_ahead
x += v



这是Momentum update的改进版,之前我们采用
v
= mu * v - learning_rate * dx
的方法计算增量,其中的dx还是当前的x,但是我们已经知道了,下一刻的惯性将会带我们去的位置,所以现在我们要用加了mu*v之后的x,来更新位置(在更新后的位置而不是在原点求解梯度),下面的图很形象: 





4.Adagrad

tensorflow实现

optimizer = tf.train.AdagradientOptimizer(learning_rate=self.learning_rate)

直接进行优化

train_op
= optimizer.minimize(loss)


cache
+= dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

上面提到的方法对于所有参数都使用了同一个更新速率。但是同一个更新速率不一定适合所有参数。比如有的参数可能已经到了仅需要微调的阶段,但又有些参数由于对应样本少等原因,还需要较大幅度的调动。Adagrad就是针对这一问题提出的,自适应地为各个参数分配不同学习率的算法。



其中gt 同样是当前的梯度,连加和开根号都是元素级别的运算。eta是初始学习率,由于之后会自动调整学习率,所以初始值就没有之前的算法那样重要了。eps是一个平滑的过程,取值通常在(10^-4~10^-8
之间)
其含义是,对于每个参数,随着其更新的总距离增多,其学习速率也随之变慢。

Adagrad中chche累加的原因是在后期作为惩罚项,这样的话学习率越来越小,符合在最后接近收敛的时候,步长越来越小的要求。

前期gt较小的时候,chche累加 regularizer较大,能够放大梯度

后期gt较大的时候,chche累加regularizer较小,能够约束梯度

适合处理稀疏梯度


 

5.RMSprop

tensorflow实现

optimizer = tf.train.RMSPropOptimizer(0.001, 0.9)
直接进行优化
train_op
= optimizer.minimize(loss)


cache=
decay_rate*cache+
(1-
decay_rate)* dx**2
x+=-
learning_rate* dx/
(np.sqrt(cache)+
eps)
decay_rate是一个超参数,常用的值是[0.9,0.99,0.999]。其中x+=和Adagrad中是一样的,但是cache变量是不同的。
因此,RMSProp仍然是基于梯度的大小来对每个权重的学习率进行修改,这同样效果不错。
但是和Adagrad不同,其更新不会让学习率单调变小。



6.Adam

tensorflow函数:

class tf.train.AdamOptimizer


__init__(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, use_locking=False, name='Adam')


直接进行优化


train_op = optimizer.minimize(loss)




m = beta1*m + (1-beta1)dx

v = beta2*v + (1-beta2)
v = beta2*v
+ (1-beta2)(dx**2)
x += - learning_rate
* m / (np.sqrt(v) + eps)
有点像RMSProp+momentum



参考来自:
http://blog.csdn.net/bea_tree/article/details/51523733#411-vanilla-update http://blog.csdn.net/luo123n/article/details/48239963
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息