我正在使用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)
这里的问题是我不知道如何为学习率设置更新规则或者为此设置衰减值。
我如何在这里使用自适应学习率?
答案 0 :(得分:182)
首先,tf.train.GradientDescentOptimizer
旨在对所有步骤中的所有变量使用恒定学习率。 TensorFlow还提供开箱即用的自适应优化器,包括tf.train.AdagradOptimizer
和tf.train.AdamOptimizer
,这些可用作插入式替换。
但是,如果你想用其他 - 香草梯度下降来控制学习率,你可以利用tf.train.GradientDescentOptimizer
constructor的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})
或者,您可以创建一个保持学习率的标量tf.Variable
,并在每次想要更改学习率时分配它。
答案 1 :(得分:87)
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'参数。
答案 2 :(得分:80)
梯度下降算法使用您可以在during the initialization中提供的恒定学习率。您可以通过Mrry表现的方式传递各种学习率。
但您可以使用more advanced optimizers代替它,它具有更快的收敛速度并适应这种情况。
根据我的理解,这是一个简短的解释:
Adam 或自适应动量是一种类似于AdaDelta的算法。但除了存储每个参数的学习率之外,它还分别存储每个参数的动量变化
答案 3 :(得分:6)
来自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))
答案 4 :(得分:0)
如果您要为0 < a < b < c < ...
之类的时间间隔设置特定的学习率。然后,您可以将学习率定义为一个条件张量,以全局步长为条件,并将其正常输入优化器。
您可以使用一堆嵌套的tf.cond
语句来实现这一点,但是更容易以递归方式构建张量:
def make_learning_rate_tensor(reduction_steps, learning_rates, global_step):
assert len(reduction_steps) + 1 == len(learning_rates)
if len(reduction_steps) == 1:
return tf.cond(
global_step < reduction_steps[0],
lambda: learning_rates[0],
lambda: learning_rates[1]
)
else:
return tf.cond(
global_step < reduction_steps[0],
lambda: learning_rates[0],
lambda: make_learning_rate_tensor(
reduction_steps[1:],
learning_rates[1:],
global_step,)
)
然后要使用它,您需要知道单个纪元中有多少个训练步骤,以便我们可以使用全局步骤在正确的时间切换,并最终定义所需的纪元和学习率。因此,如果我想分别在[0.1, 0.01, 0.001, 0.0001]
的纪元间隔内学习[0, 19], [20, 59], [60, 99], [100, \infty]
,我会这样做:
global_step = tf.train.get_or_create_global_step()
learning_rates = [0.1, 0.01, 0.001, 0.0001]
steps_per_epoch = 225
epochs_to_switch_at = [20, 60, 100]
epochs_to_switch_at = [x*steps_per_epoch for x in epochs_to_switch_at ]
learning_rate = make_learning_rate_tensor(epochs_to_switch_at , learning_rates, global_step)