一、学习率
使用TensorFlow训练一个模型时,我们需要通过优化函数来使得我们训练的模型损失值达到最小,常用的优化算法有随机梯度下降、批量梯度下降,而在使用优化算法的时候,我们都需要设置一个学习率(learning rate),而学习率的设置在训练模型的时候也是非常重要的,因为学习率控制了每次更新参数的幅度。如果学习率太大就会导致更新的幅度太大,就有可能会跨过损失值的极小值(不说最小值的原因,是因为有可能是局部的最小值),最后可能参数的极优值会在参数的极优值之间徘徊,而取不到参数的极优值。如果学习率设置的太小,就会导致的更新速度太慢,从而需要消耗更多的资源来保证获取到参数的极优值。下面通过一个简单的表格和解析来说明学习率究竟是如何影响参数的更新的。
通过观察上表可以发现,设置了三个不同的学习率来更新参数的值,如果参数的极优值是1,如果将学习率设置为1,可以发现无论迭代多少次参数的值都在5和-5之间变化,永远也不可能达到1。很显然,学习率设置为0.1还是比较合适的,更新速度相对于学习率设置为0.001而言更新速度不会太慢,而且迭代的次数也会少不少,最后的结果可能相差并不大。通过上表可以看出学习率的设置还是非常重要的。其实,对于学习率的设置上面,我们可能会想着刚开始更新的时候,学习率尽可能的大,当参数快接近极优值的时候,学习率要变小,从而保证参数最后能够达到极优值而且保证迭代的次数足够小,减少资源的消耗,加快训练的速度。
二、指数衰减学习率
TensorFlow提供了一种非常灵活的学习率设置方法,指数衰减法。通过这种方式可以很好的解决上面的问题,先用一个较大的学习率来快速得到一个比较优的参数值,然后通过迭代次数的增加逐渐减少学习率,使得保证参数极优的同时迭代次数也少。TensorFlow提供了一个exponential_decay函数会指数极的逐渐减少学习率,函数的功能有下面的公式可以表示:
decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
公式中的参数,其中decayed_learning_rate表示每轮迭代所使用的学习率,learning_rate为初始化学习率,decay_rate为衰减系数,随着迭代次数的增加,学习率会逐步降低。
tf.train.exponential_decay(learning_rate,global_step,decay_step,staircase=False,name=None)
learning_rate:一个标量类型为float32或floate64、张量或一个python数字,代表初始化的学习率
global_step:一个标量类型为int32或int64,张量或一个python数字,用于衰减计算中,不能是负数。
decay_steps:一个标量类型为int32或int64,张量或一个python数字,必须是正数,用于衰减计算中。
decay_rate:一个标量类型为float32或floate64,张量或一个python数字,表示衰减的比率。
staircase:Boolean类型,默认是False表示衰减的学习率是连续的,如果是True代表衰减的学习率是一个离散的间隔。
返回值:一个标量类型的学习率。
import tensorflow as tf
from numpy.random import RandomState
if __name__ == "__main__":
#设置每次跌打数据的大小
batch_size = 8
#定义输入节点
x = tf.placeholder(tf.float32,shape=(None,1),name="x_input")
#定义预测值的输出节点
y_ = tf.placeholder(tf.float32,shape=(None,1),name="y_output")
#定义参数变量
w = tf.Variable(50.,trainable=True)
# 定义神经网络的传播过程
y = x * w
#定义损失函数
loss = tf.reduce_sum(tf.square(y-y_))
#定义global_step
global_step = tf.Variable(0,trainable=False)
#通过指数衰减函数来生成学习率
learing_rate = tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=False)
#使用梯度下降算法来最优化损失值
learing_step = tf.train.GradientDescentOptimizer(learing_rate).minimize(loss,global_step)
#随机产生一个数据集
rdm = RandomState(1)
#设置数据集的大小
dataset_size = 200
#产生输入数据
X = rdm.rand(dataset_size,1)
#定义真实的输出数据Y,
Y = [x1 + rdm.rand()/5.0 - 0.05 for x1 in X]
#训练模型
with tf.Session() as sess:
#初始化所有的参数
all_init = tf.initialize_all_variables()
sess.run(all_init)
#设置迭代次数
STEPS = 5000
for i in range(STEPS):
start = (i * batch_size) % batch_size
end = min(start+batch_size,dataset_size)
#训练模型
sess.run(fetches=learing_step,feed_dict={x:X[start:end],y_:Y[start:end]})
#没迭代100次输出一次参数值
if i % 100 == 0:
print("w:%f,learing_rate:%f"%(w.eval(session=sess),learing_rate.eval(session=sess)))
tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=False),设置初始学习率为0.1,staircase=False表示是一个联系变化的衰减曲线,若为True则是一个阶梯型,每训练100轮学习率乘以0.96,可以通过运行上面的代码进行验证。一般来说初始学习率、衰减系数以及衰减速度都是根据经验设置的,而且损失函数下降的速度与迭代结束之后的中损失没有必然的联系。