tensorflow Optimizer算法

来源:互联网 发布:手机淘宝体检中心链接 编辑:程序博客网 时间:2024/05/29 14:36

tensorflow优化器

种类如下,其中Optimizer是基类

    tf.train.Optimizer    tf.train.GradientDescentOptimizer    tf.train.AdadeltaOptimizer    tf.train.AdagradOptimizer    tf.train.AdagradDAOptimizer    tf.train.MomentumOptimizer    tf.train.AdamOptimizer    tf.train.FtrlOptimizer    tf.train.ProximalGradientDescentOptimizer    tf.train.ProximalAdagradOptimizer    tf.train.RMSPropOptimizer

tf.train.GradientDescentOptimizer

梯度下降法

设:
hθ(x)=θ1x,其参数是θ1,则其损失函数是:
J(θ1)=12mmi=1(hθ(x(i))y(i))2
θ1通过如下求得:
minimizeθ1J(θ1)

梯度下降原理

设样本集合是{(1,1), (2,2), (3,3)}.下图是θ1J(θ1)变化情况。
这里写图片描述
θj=θjαθjJ(θ0,θ1)
对参数中向量θ中的每个分量θj,迭代减去速率因子ηdJ(θ)dθj

梯度下降法

批量梯度下降法

θj=θjηθJ(θ)
如上例:
h(θ)=nj=0θjxj
J(θ)=12mmi=1(yihθ(xi))2
2.求解方法
J(θ)θj=1mmi=1(yihθ(xi))xij
θj=θj+1mmi=1(yihθ(xi))xij
全局最优,但是m很大时,计算量较大。

for i in range(nb_epochs):  params_grad = evaluate_gradient(loss_function, data, params)  params = params - learning_rate * params_grad

随机梯度下降法

对每一个样本xi根据label yi进行更新
θj=θjηθJ(θ;x(i);y(i))
如上例:
J(θ)=12mmi=1(yihθ(xi))2
梯度更新:
θj=θj+(yihθ(xi))xij,j

for i in range(nb_epochs):  np.random.shuffle(data)  for example in data:    params_grad = evaluate_gradient(loss_function, example, params)    params = params - learning_rate * params_grad

mini-batch 梯度下降法

θj=θjηθJ(θ;x(i;i+n);y(i;i+n))
如n取50的情况:

for i in range(nb_epochs):  np.random.shuffle(data)  for batch in get_batches(data, batch_size=50):    params_grad = evaluate_gradient(loss_function, batch, params)    params = params - learning_rate * params_grad

问题

1.合适的学习率,α比较难获得
α过大导致震荡无法得到最优解,过小导致学习过程漫长。
2.对所有参数学习率只有一个,如果数据是稀疏的,并且特征具有不同的频率时,更倾向于对不同频率特征使用不同的学习率,对很少发生的特征采用较大的学习率。
3.目标函数门限需要提前定义,一旦计算中小于门限就停止,数据调度训练的选择对其有影响,通常使用shuffle打断以减小这种影响。
4.高维非凸误差函数最小求解技术难度大。

tf.train.AdadeltaOptimizer

该算法不需要手动调优学习速率α,抗噪声能力强,可以选择不同的模型结构。
Adadelta是对Adagrad的扩展。Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是计算对应的平均值。
上一节的参数更新模型是:
θt+1=θtαdJ(θ)dθt
为方便,把dJ(θ)dθt记作gt,把平滑后的梯度记作E[g]t,则其平方表示如下:
E[g2]t=ρE[g2]t1+(1ρ)g2t
其中ρ是平滑/衰减因子。其均方根得到的该值如下:
RMS[g]t=E[g2]t+ϵ
其中ϵ是为了防止后续计算分母为零而引入的参数常量。
Δθ=RMS[Δθ]t1RMS[g]tgt
θt+1=θt+Δθt

ADADELTA t时刻跟新过程如下:

前提衰减因子ρ,常数ϵ,初始的θ值。

1 计算变量E[g2]0=0E[Δθ2]0=0
2: for t=1:T do %%Loop over #of updates

3: 计算梯度:gt
4: 滑动平均梯度:E[g2]t=ρE[g2]t1+(1ρ)g2t
5. 计算参数跟新Δθ=RMS[Δθ2]tRMS[g]tgt
6. 计算更新E[Δx2]t=ρE[Δθ2]t1+(1ρ)θ2
7. 更新参数θt+1=θt+Δθt

8.end for

tf.train.AdagradOptimizer

Adagrad会累加之前所有的梯度平方。
Δθt=ηtτg2τ+ϵgt
θt+1=θtηtτg2τ+ϵgt
通常上述的求和针对一个窗长w求解,以减小运算量。

tf.train.AdagradDAOptimizer

tf.train.MomentumOptimizer

动量法的原理是,如果梯度长时间保持一个方向(为正或者长时间为负),则增大参数更新幅度,反之,如果频繁发生符号翻转,则说明这是要减小参数更新幅度。可以把这一过程理解成从山顶放下一个球,会滑的越来越快。
θt=ρθt1ηdJ(θ)dθt

tf.train.AdamOptimizer

Adam(Adaptive Moment Estimation)加上了bias校正和momentum,在优化末期,梯度更稀疏时,它比RMSprop稍微好点。
mt=β1mt1+(1β1)gt
vt=β2vt1+(1β2)g2t
其中mt是梯度均值,vt是梯度偏方差。这两个值初始化时为0的张量。在训练开始时,mtvt趋向于零。可以使用如下估计方法抵消:
m^t=mt1βt1
v^t=vt1βt2
θt+1=θtηv^t+ϵm^t

tf.train.FtrlOptimizer

tf.train.ProximalGradientDescentOptimizer

tf.train.ProximalAdagradOptimizer

tf.train.RMSPropOptimizer

E[g2]t=0.9E[g2]t1+0.1g2t
θ)t+1=θtηE[g2]t+ϵgt
学习速率梯度均方根均值指数衰减。

如何选用optimizer

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

其它梯度优化方法

1.数据重拍(shuffle函数)和数据多次重复训练
2.批量归一化,防止逐级训练中的梯度消失和溢出
3.提前终止,防止过拟合,监控验证数据集在训练中的损失,合适时提前终止。
4.增加高斯分布的梯度噪声,
gt,i=gt,i+N(0,δ2)
δ2t=η(1+t)γ
这使得网络对初始化不敏感。

tensorflow中使用方法

创建优化器

# Create an optimizer with the desired parameters.opt = GradientDescentOptimizer(learning_rate=0.1)# Add Ops to the graph to minimize a cost by updating a list of variables.# "cost" is a Tensor, and the list of variables contains tf.Variable# objects.opt_op = opt.minimize(cost, var_list=<list of variables>)

在训练步骤中

# Execute opt_op to do one step of training:opt_op.run()

minimize()函数处理了梯度计算和参数更新两个操作,如果想获得梯度并单独处理,则compute_gradients()函数用于获取梯度,apply_gradients()用于更新参数。

# Create an optimizer.opt = GradientDescentOptimizer(learning_rate=0.1)# Compute the gradients for a list of variables.grads_and_vars = opt.compute_gradients(loss, <list of variables>)# grads_and_vars is a list of tuples (gradient, variable).  Do whatever you# need to the 'gradient' part, for example cap them, etc.capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]# Ask the optimizer to apply the capped gradients.opt.apply_gradients(capped_grads_and_vars)
原创粉丝点击