TensorFlow之优化器
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
tf.train.GradientDescentOptimizer
梯度下降法
设:
hθ(x)=θ1xhθ(x)=θ1x,其参数是θ1θ1,则其损失函数是:
J(θ1)=12m∑mi=1(hθ(x(i))−y(i))2J(θ1)=12m∑i=1m(hθ(x(i))−y(i))2
则θ1θ1通过如下求得:
minimizeθ1J(θ1)minimizeθ1J(θ1)
梯度下降原理
设样本集合是{(1,1), (2,2), (3,3)}.下图是θ1θ1和J(θ1)J(θ1)变化情况。
θj=θj−α∂∂θjJ(θ0,θ1)θj=θj−α∂∂θjJ(θ0,θ1)
对参数中向量θθ中的每个分量θjθj,迭代减去速率因子η∗dJ(θ)dθjη∗dJ(θ)dθj
梯度下降法
批量梯度下降法
θj=θj−η⋅▽θJ(θ)θj=θj−η⋅▽θJ(θ)
如上例:
h(θ)=∑nj=0θjxjh(θ)=∑j=0nθjxj
J(θ)=12m∑mi=1(yi−hθ(xi))2J(θ)=12m∑i=1m(yi−hθ(xi))2
2.求解方法
∂J(θ)∂θj=−1m∑mi=1(yi−hθ(xi))xij∂J(θ)∂θj=−1m∑i=1m(yi−hθ(xi))xji
θj=θj+1m∑mi=1(yi−hθ(xi))xijθj=θj+1m∑i=1m(yi−hθ(xi))xji
全局最优,但是m很大时,计算量较大。
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
随机梯度下降法
对每一个样本xixi根据label yiyi进行更新
θj=θj−η⋅▽θJ(θ;x(i);y(i))θj=θj−η⋅▽θJ(θ;x(i);y(i))
如上例:
J(θ)=12m∑mi=1(yi−hθ(xi))2J(θ)=12m∑i=1m(yi−hθ(xi))2
梯度更新:
θj=θj+(yi−hθ(xi))xij,对每一个j求解θj=θj+(yi−hθ(xi))xji,对每一个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
- 1
- 2
- 3
- 4
- 5
mini-batch 梯度下降法
θj=θj−η⋅▽θJ(θ;x(i;i+n);y(i;i+n))θ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
- 4
- 5
问题
1.合适的学习率,αα比较难获得
αα过大导致震荡无法得到最优解,过小导致学习过程漫长。
2.对所有参数学习率只有一个,如果数据是稀疏的,并且特征具有不同的频率时,更倾向于对不同频率特征使用不同的学习率,对很少发生的特征采用较大的学习率。
3.目标函数门限需要提前定义,一旦计算中小于门限就停止,数据调度训练的选择对其有影响,通常使用shuffle打断以减小这种影响。
4.高维非凸误差函数最小求解技术难度大。
tf.train.AdadeltaOptimizer
该算法不需要手动调优学习速率αα,抗噪声能力强,可以选择不同的模型结构。
Adadelta是对Adagrad的扩展。Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是计算对应的平均值。
上一节的参数更新模型是:
θt+1=θt−αdJ(θ)dθtθt+1=θt−αdJ(θ)dθt
为方便,把dJ(θ)dθtdJ(θ)dθt记作gtgt,把平滑后的梯度记作E[g]tE[g]t,则其平方表示如下:
E[g2]t=ρE[g2]t−1+(1−ρ)g2tE[g2]t=ρE[g2]t−1+(1−ρ)gt2
其中ρρ是平滑/衰减因子。其均方根得到的该值如下:
RMS[g]t=E[g2]t+ϵ‾‾‾‾‾‾‾‾‾‾√RMS[g]t=E[g2]t+ϵ
其中ϵϵ是为了防止后续计算分母为零而引入的参数常量。
Δθ=−RMS[Δθ]t−1RMS[g]tgtΔθ=−RMS[Δθ]t−1RMS[g]tgt
θt+1=θt+Δθtθt+1=θt+Δθt
ADADELTA t时刻跟新过程如下:
前提衰减因子ρρ,常数ϵϵ,初始的θθ值。
1 计算变量E[g2]0=0E[g2]0=0,E[Δθ2]0=0E[Δθ2]0=0
2: for t=1:T do %%Loop over #of updates
3: 计算梯度:gtgt
4: 滑动平均梯度:E[g2]t=ρE[g2]t−1+(1−ρ)g2tE[g2]t=ρE[g2]t−1+(1−ρ)gt2
5. 计算参数跟新Δθ=−RMS[Δθ2]tRMS[g]tgtΔθ=−RMS[Δθ2]tRMS[g]tgt
6. 计算更新E[Δx2]t=ρE[Δθ2]t−1+(1−ρ)θ2E[Δx2]t=ρE[Δθ2]t−1+(1−ρ)θ2
7. 更新参数θt+1=θt+Δθtθt+1=θt+Δθt
8.end for
tf.train.AdagradOptimizer
Adagrad会累加之前所有的梯度平方。
Δθt=−η∑tτg2τ+ϵ√⨀gtΔθt=−η∑τtgτ2+ϵ⨀gt
θt+1=θt−η∑tτg2τ+ϵ√⨀gtθt+1=θt−η∑τtgτ2+ϵ⨀gt
通常上述的求和针对一个窗长ww求解,以减小运算量。
tf.train.AdagradDAOptimizer
tf.train.MomentumOptimizer
动量法的原理是,如果梯度长时间保持一个方向(为正或者长时间为负),则增大参数更新幅度,反之,如果频繁发生符号翻转,则说明这是要减小参数更新幅度。可以把这一过程理解成从山顶放下一个球,会滑的越来越快。
θt=ρθt−1−ηdJ(θ)dθtθt=ρθt−1−ηdJ(θ)dθt
tf.train.AdamOptimizer
Adam(Adaptive Moment Estimation)加上了bias校正和momentum,在优化末期,梯度更稀疏时,它比RMSprop稍微好点。
mt=β1mt−1+(1−β1)gtmt=β1mt−1+(1−β1)gt
vt=β2vt−1+(1−β2)g2tvt=β2vt−1+(1−β2)gt2
其中mtmt是梯度均值,vtvt是梯度偏方差。这两个值初始化时为0的张量。在训练开始时,mtmt和vtvt趋向于零。可以使用如下估计方法抵消:
m̂ t=mt1−βt1m^t=mt1−β1t
v̂ t=vt1−βt2v^t=vt1−β2t
θt+1=θt−ηv̂ t+ϵ√m̂ tθ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]t−1+0.1g2tE[g2]t=0.9E[g2]t−1+0.1gt2
θ)t+1=θt−ηE[g2]t+ϵ√⨀gtθ)t+1=θt−ηE[g2]t+ϵ⨀gt
学习速率梯度均方根均值指数衰减。
如何选用optimizer
对于稀疏数据,使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值
SGD通常训练时间更长,容易陷入鞍点,但是在好的初始化和学习率调度方案的情况下,结果更可靠
如果在意更快的收敛,并且需要训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。
Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。
其它梯度优化方法
1.数据重拍(shuffle函数)和数据多次重复训练
2.批量归一化,防止逐级训练中的梯度消失和溢出
3.提前终止,防止过拟合,监控验证数据集在训练中的损失,合适时提前终止。
4.增加高斯分布的梯度噪声,
gt,i=gt,i+N(0,δ2)gt,i=gt,i+N(0,δ2)
δ2t=η(1+t)γδt2=η(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>)
- 1
- 2
- 3
- 4
- 5
- 6
在训练步骤中
# Execute opt_op to do one step of training:
opt_op.run()
- 1
- 2
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)