在训练神经网络时,需要设置学习率(leaming rate)来控制参数更新的速度,学习率决定了参数每次更新的幅度,如果幅度过大,那么可能导致参数在极优值的两侧来回移动,如果幅度过小,虽然能保证收敛性,但是这会大大降低优化速度。
为了解决设定学习率的问题,TensorFlow 提供了一种更加灵活的学习率设置方法——指数衰减法,通过指数衰减的学习率既可以让模型在训练的前期快速接近较优解,又可以保证模型在训练后期不会有太大的波动,从而更加接近局部最优。
在 TensorFlow 中,tf.train.exponential_decay
函数实现了指数衰减学习率,通过这个函数,可以先使用较大的学习率来快速得到一个比较优的解,然后随着迭代的继续逐步减小学习率,使得模型在训练后期更加稳定。
tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase, name)
函数会指数级地减小学习率,它实现了以下代码的功能:
# tf.train.exponential_decay 函数可以通过设置 staircase 参数选择不同的学习率衰减方式
# staircase 参数为 False(默认)时,选择连续衰减学习率:
decayed_learning_rate = learning_rate * math.pow(decay_rate, global_step / decay_steps)
# staircase 参数为 True 时,选择阶梯状衰减学习率:
decayed_learning_rate = learning_rate * math.pow(decay_rate, global_step // decay_steps)
-
decayed_leaming_rate
:每一轮优化时使用的学习率; -
leaming_rate
:事先设定的初始学习率; -
decay_rate
:衰减系数; -
global_step
:当前训练的轮数; -
decay_steps
:衰减速度,通常代表了完整的使用一遍训练数据所需要的迭代轮数,这个迭代轮数也就是总训练样本数除以每一个 batch 中的训练样本数,比如训练数据集的大小为 128,每一个 batch 中样例的个数为 8,那么decay_steps
就为 16; -
staircase
:- 当
staircase
参数设置为True
,使用阶梯状衰减学习率时,代码的含义是每完整地过完一遍训练数据即每训练decay_steps
轮,学习率就减小一次,这可以使得训练数据集中的所有数据对模型训练有相等的作用; - 当
staircase
参数设置为False
,使用连续的衰减学习率时,不同的训练数据有不同的学习率,而当学习率减小时,对应的训练数据对模型训练结果的影响也就小了。
- 当
接下来看一看 tf.train.exponential_decay
函数应用的两种形态(省略部分代码):
- 第一种形态,
global_step
作为变量被优化,在这种形态下,global_step
是变量,在minimize
函数中传入global_step
将自动更新global_step
参数(global_step
每轮迭代自动加一),从而使得学习率也得到相应更新:import tensorflow as tf . . . #设置学习率 global_step = tf.Variable(tf.constant(0)) learning_rate = tf.train.exponential_decay(0.01, global_step, 16, 0.96, staircase=True) #定义反向传播算法的优化方法 train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy, global_step=global_step) . . . #创建会话 with tf.Session() as sess: . . . for i in range(STEPS): . . . #通过选取的样本训练神经网络并更新参数 sess.run(train_step, feed_dict={x:X[start:end], y_:Y[start:end]}) . . .
- 第二种形态,
global_step
作为占位被 feed,在这种形态下,global_step
是占位,在调用sess.run(train_step)
时使用当前迭代的轮数 i 进行 feed:import tensorflow as tf . . . #设置学习率 global_step = tf.placeholder(tf.float32, shape=()) learning_rate = tf.train.exponential_decay(0.01, global_step, 16, 0.96, staircase=True) #定义反向传播算法的优化方法 train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy) . . . #创建会话 with tf.Session() as sess: . . . for i in range(STEPS): . . . #通过选取的样本训练神经网络并更新参数 sess.run(train_step, feed_dict={x:X[start:end], y_:Y[start:end], global_step:i}) . . .