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

我正在使用TensorFlow来训练一个neural network。 这是我如何初始化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) 

这里的事情是我不知道如何设置学习率或衰减值的更新规则。

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

首先, tf.train.GradientDescentOptimizer被devise为对所有步骤中的所有variables使用不变的学习率。 TensorFlow还提供了开箱即用的自适应优化器,包括tf.train.AdagradOptimizertf.train.AdamOptimizer ,这些可以用作插入replace。

但是,如果要用其他的香草渐变下降控制学习率,则可以利用tf.train.GradientDescentOptimizer构造函数的learning_rate参数可以是Tensor对象的事实。 这允许您在每个步骤中为学习速率计算不同的值,例如:

 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}) 

或者,您可以创build一个标量tf.Variable来保存学习率,并在每次要更改学习率时分配它。

Tensorflow提供了一个自动将指数衰减应用于学习速率张量: tf.train.exponential_decay 。 有关使用的示例,请参阅MNIST卷积模型示例中的这一行 。 然后使用上面的@ mrry的build议将这个variables作为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) 

请注意global_step=batch参数以最小化。 这就告诉优化器在每次训练时都会帮助你增加“批量”参数。

梯度下降algorithm使用初始化期间可以提供的恒定学习速率。 你可以通过Mrry的方式传递各种学习费用。

但是,也可以使用更先进的优化器 ,它具有更快的收敛速度和适应情况。

基于我的理解,下面是一个简单的解释:

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

    几个可视化 : 在这里输入图像说明 在这里输入图像说明

从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))