首页 文章

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

提问于
浏览
86

我正在使用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)

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

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

4 回答

  • 77

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

    但是,如果您想用其他方式控制学习率,那么您可以利用tf.train.GradientDescentOptimizer constructorlearning_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})
    

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

  • 181

    Tensorflow提供了一种操作,可自动将指数衰减应用于学习速率张量:tf.train.exponential_decay . 有关它的使用示例,请参阅this line in the MNIST convolutional model example . 然后使用上面的@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)
    

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

  • 85

    梯度下降算法使用您可以在during the initialization中提供的常量学习率 . 您可以通过Mrry表现的方式传递各种学习率 .

    但是你可以使用more advanced optimizers而不是它,它具有更快的收敛速度并适应这种情况 .

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

    • momentum helps SGD沿相关方向导航并软化无关紧要的振荡 . 它只是将前一步骤的一部分方向添加到当前步骤 . 这实现了在正确的方向上放大速度并且在错误的方向上软化振荡 . 该分数通常在(0,1)范围内 . 使用自适应动量也是有意义的 . 在学习开始时,一个巨大的动力只会阻碍你的进步,所以使用像0.01这样的东西很有意义,一旦所有的高梯度消失,你就可以使用更大的时刻 . 动量存在一个问题:当我们非常接近目标时,我们在大多数情况下的势头非常高,并且不知道它应该减速 . 这可能导致它在最小值周围错过或振荡

    • nesterov accelerated gradient 通过开始减速来克服这个问题 . 在动量中,我们首先计算梯度,然后在那个方向上跳跃,放大我们之前的动量 . NAG做了同样的事情,但是按照另一种顺序:首先我们根据存储的信息进行大跳,然后我们计算渐变并进行小的修正 . 这种看似无关紧要的变化带来了显着的实际加速 .

    • AdaGrad 或自适应梯度允许学习速率基于参数进行调整 . 它为不频繁的参数执行更大的更新,为频繁的参数执行更小的更新 . 因此,它非常适合稀疏数据(NLP或图像识别) . 另一个优点是它基本上不需要调整学习速率 . 每个参数都有自己的学习速率,并且由于算法的特殊性,学习速率是单调递减的 . 这导致了最大的问题:在某些时间点,学习速度很小,系统停止学习

    • AdaDelta 解决了AdaGrad单调降低学习率的问题 . 在AdaGrad中,学习率大致计算为1除以平方根的总和 . 在每个阶段,您将另一个平方根添加到总和,这会导致分母不断减少 . 在AdaDelta中,它不是对所有过去的平方根求和,而是使用滑动窗口,允许总和减少 . RMSprop 与AdaDelta非常相似

    • Adam 或自适应动量是一种类似于AdaDelta的算法 . 但除了存储每个参数的学习率之外,它还分别存储每个参数的动量变化

    A few visualizations
    enter image description here

    enter image description here

  • 5

    来自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))
    

相关问题