学习率learning_rate: 学习率表示每次参数更新的幅度
1.而参数的更新是遵照这个公式:Wn+1 = Wn - learning_rate * ▽
Wn+1:更新后的参数
Wn:当前参数
learning_rate:学习率
▽:损失函数的梯度(导数)
也就是参数的更新向着梯度下降的方向
那么下面详细看一下学习率是如何影响参数的更新的
2.定义损失函数 loss = (w + 1)² 梯度 ▽ = (α * loss) / (α * w) = 2w + 2
假设w初始化为5, 学习率为0.2 带入第一步中的学习率表达式后,则更新后的参数为
第一次 参数:5 5 - 0.2 * (2 * 5 + 2) = 2.6
第二次 参数:2.6 2.6 - 0.2 * (2 * 2.6) = 1.16
第三次 参数:1.16 1.16 - 0.2 * (2 * 1.16 + 2) = 0.296
.......
我们知道当w = -1时的loss最小,那么通过代码来实现这一过程,看一下学习率的作用。
一样的编码套路,只不过这次不需要构造数据集、定义占位符、定义前向传播过程
import tensorflow as tf #构建数据集,输入X 与 Y_标签 #定义占位符 x, y_ #定义权重,几层网络就定义几层权重W W = tf.Variable(tf.constant(5, dtype=tf.float32)) #定义前向传播过程得到输出值 y #定义损失函数得到loss值 loss = tf.square(W + 1) #通过梯度下降减小loss值 train_step = tf.train.GradientDescentOptimizer(1e-2).minimize(loss) #with结构 with tf.Session() as sess: #初始化变量 tf.global_variables_initializer().run() for i in range(500): sess.run(train_step) w_val = sess.run(W) loss_val = sess.run(loss) print("迭代第{}次的损失值是:{},更新后的权重W是:{}".format(i, loss_val, w_val))
可以看到500次迭代后的权重W已经趋近与-1。
那么再来看一下改变学习率为1时的结果:
很是不理想,由此可见固定的学习率不利于整个训练过程中最优解的寻找,偏小了会导致收敛速度慢,过大了会导致震荡不收敛。
于是提出了指数衰减的学习率这一方法,根据运行BATCH_SIZE轮数来动态减小学习率
指数衰减的学习率的计算公式如下:
lr = lr_base * lr_decay * (global_step / lr_step)
lr:学习率
lr_base:初始学习率
lr_decay:衰减率
global_step:迭代次数也就是训练次数
lr_step:多少轮更新一次学习率,一般 = 总样本数 / BATCH_SIZE
tensorflow提供了如下API来实现这一过程:
lr = tf.train.exponential_decay(
learning_rate=LR_BASE, # 初始学习率
global_step=global_step, # 当前运行到多少轮
decay_steps=LR_STEP, # 多少轮更新一次
decay_rate=LR_DECAY, # 衰减率
staircase=True # 为True时global_step / lr_step取整数,学习率呈梯形衰减。为False时学习率的呈一条平滑的曲线衰减
)
import tensorflow as tf LR_BASE = 0.1 # 最初学习率 LR_DECAY = 0.99 # 学习率衰减率 LR_STEP = 1 # 多少轮更新一次衰减率 #构建数据集,输入X 与 Y_标签 #定义指数衰减学习率 global_step = tf.Variable(0, trainable=False) # 计数器,记录当前共运行了多少轮,只用其计数,并不用来参与训练,所以trainable=False LR = tf.train.exponential_decay(learning_rate=LR_BASE, global_step=global_step, decay_steps=LR_STEP, decay_rate=LR_DECAY, staircase=True) #定义占位符 x, y_ #定义权重,几层网络就定义几层权重W W = tf.Variable(tf.constant(5, dtype=tf.float32)) #定义前向传播过程得到输出值 y #定义损失函数得到loss值 loss = tf.square(W + 1) #通过梯度下降减小loss值 train_step = tf.train.GradientDescentOptimizer(LR).minimize(loss, global_step=global_step) #with结构 with tf.Session() as sess: #初始化变量 tf.global_variables_initializer().run() for i in range(40): sess.run(train_step) w_val = sess.run(W) loss_val = sess.run(loss) lr_val = sess.run(LR) print("迭代第{}次的损失值是:{},更新后的权重W是:{},学习率是:{}".format(i, loss_val, w_val, lr_val))
代码实现: