如何为GradientDescentOptimizer设置自适应学习速率?

dis*_*ame 96 python tensorflow

我正在使用TensorFlow来训练神经网络.这是我初始化的方式GradientDescentOptimizer:

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

mse        = tf.reduce_mean(tf.square(out - out_))
train_step = tf.train.GradientDescentOptimizer(0.3).minimize(mse)
Run Code Online (Sandbox Code Playgroud)

这里的问题是我不知道如何为学习率或衰减值设置更新规则.

我如何在这里使用自适应学习率?

mrr*_*rry 190

首先,tf.train.GradientDescentOptimizer旨在对所有步骤中的所有变量使用恒定学习率.TensorFlow还提供开箱即用的自适应优化器,包括tf.train.AdagradOptimizertf.train.AdamOptimizer,以及这些可用作插入式替换.

但是,如果要使用其他方法控制学习速率,可以利用构造函数learning_rate参数可以作为对象这一事实.这允许您为每个步骤中的学习率计算不同的值,例如:tf.train.GradientDescentOptimizerTensor

learning_rate = tf.placeholder(tf.float32, shape=[])
# ...
train_step = tf.train.GradientDescentOptimizer(
    learning_rate=learning_rate).minimize(mse)

sess = tf.Session()

# Feed different values for learning rate to each training step.
sess.run(train_step, feed_dict={learning_rate: 0.1})
sess.run(train_step, feed_dict={learning_rate: 0.1})
sess.run(train_step, feed_dict={learning_rate: 0.01})
sess.run(train_step, feed_dict={learning_rate: 0.01})
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建一个tf.Variable保持学习速率的标量,并在每次想要更改学习速率时分配它.


dga*_*dga 88

Tensorflow提供了一个自动将指数衰减应用于学习速率张量的操作:tf.train.exponential_decay.有关它的使用示例,请参阅MNIST卷积模型示例中的此行.然后使用上面的@mrry建议将此变量作为learning_rate参数提供给您选择的优化器.

要看的关键摘录是:

# Optimizer: set up a variable that's incremented once per batch and
# controls the learning rate decay.
batch = tf.Variable(0)

learning_rate = tf.train.exponential_decay(
  0.01,                # Base learning rate.
  batch * BATCH_SIZE,  # Current index into the dataset.
  train_size,          # Decay step.
  0.95,                # Decay rate.
  staircase=True)
# Use simple momentum for the optimization.
optimizer = tf.train.MomentumOptimizer(learning_rate,
                                     0.9).minimize(loss,
                                                   global_step=batch)
Run Code Online (Sandbox Code Playgroud)

请注意global_step=batch要最小化的参数.这告诉优化器每次训练时都会为你帮助增加'batch'参数.

  • 通常,你称之为`batch`的变量称为`global_step`,并且有几个便利函数,一个用于创建它`tf.train.create_global_step()`(它只是创建一个整数`tf.Variable`并将其添加到`tf.GraphKeys.GLOBAL_STEP` collection)和`tf.train.get_global_step()`. (3认同)

Sal*_*ali 82

梯度下降算法使用您在初始化期间可以提供的恒定学习速率.您可以通过Mrry表现的方式传递各种学习率.

但除此之外,您还可以使用更高级的优化器,它们具有更快的收敛速度并适应这种情况.

以下是基于我的理解的简要说明:

  • 动量 有助于 SGD沿着相关方向导航并减轻无关紧要的振荡.它只是将前一步骤的一部分方向添加到当前步骤.这实现了在正确的方向上放大速度并且在错误的方向上软化振荡.该分数通常在(0,1)范围内.使用自适应动量也是有意义的.在学习开始时,一个巨大的动力只会阻碍你的进步,所以使用像0.01这样的东西很有意义,一旦所有的高梯度消失,你就可以使用更大的时刻.动量存在一个问题:当我们非常接近目标时,我们在大多数情况下的势头非常高,并且不知道它应该减速.这可能导致它在最小值周围错过或振荡
  • nesterov加速梯度通过开始减速来克服这个问题.在动量中,我们首先计算梯度,然后在那个方向上跳跃,放大我们之前的动量.NAG做了同样的事情,但是按照另一种顺序:首先我们根据存储的信息进行大跳,然后我们计算渐变并进行小的修正.这种看似无关紧要的变化带来了显着的实际加速.
  • AdaGrad或自适应梯度允许学习速率基于参数进行调整.它为不频繁的参数执行更大的更新,为频繁的参数执行更小的更新.因此,它非常适合稀疏数据(NLP或图像识别).另一个优点是它基本上不需要调整学习速率.每个参数都有自己的学习速率,并且由于算法的特殊性,学习速率是单调递减的.这导致了最大的问题:在某些时间点,学习速度很小,系统停止学习
  • AdaDelta解决了AdaGrad单调降低学习率的问题.在AdaGrad中,学习率大致计算为1除以平方根的总和.在每个阶段,您将另一个平方根添加到总和,这会导致分母不断减少.在AdaDelta中,它不是对所有过去的平方根求和,而是使用滑动窗口,允许总和减少.RMSprop与AdaDelta非常相似
  • Adam或自适应动量是一种类似于AdaDelta的算法.但除了存储每个参数的学习率之外,它还分别存储每个参数的动量变化

    一个几可视化: 在此输入图像描述 在此输入图像描述

  • 很棒的动画! (8认同)
  • 为了比较TensorFlow中的不同优化器,请查看以下ipython笔记本:https://github.com/vsmolyakov/experiments_with_python/blob/master/chp03/tensorflow_optimizers.ipynb for (2认同)

Pra*_*lli 7

来自tensorflow官方文档

global_step = tf.Variable(0, trainable=False)
starter_learning_rate = 0.1
learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step,
                                       100000, 0.96, staircase=True)

# Passing global_step to minimize() will increment it at each step.
learning_step = (
tf.train.GradientDescentOptimizer(learning_rate)
.minimize(...my loss..., global_step=global_step))
Run Code Online (Sandbox Code Playgroud)