参考链接: Python中的numpy.float_power
学习率衰减(learning rate decay) 在训练神经网络时,使用学习率控制参数的更新速度.学习率较小时,会大大降低参数的更新速度;学习率较大时,会使搜索过程中发生震荡,导致参数在极优值附近徘徊. 为此,在训练过程中引入学习率衰减,使学习率随着训练的进行逐渐衰减.
TensorFlow中实现的学习率衰减方法:
tf.train.piecewise_constant 分段常数衰减tf.train.inverse_time_decay 反时限衰减tf.train.polynomial_decay 多项式衰减tf.train.exponential_decay 指数衰减tf.train.natural_exp_decay 自然指数衰减tf.train.cosine_decay 余弦衰减tf.train.linear_cosine_decay 线性余弦衰减tf.train.noisy_linear_cosine_decay 噪声线性余弦衰减
函数返回衰减的学习率.
先讲单个函数的使用效果,最后演示如何将其用在实际模型中。
首先是使用效果:
分段常数衰减:tf.train.piecewise_constant() 指定间隔的分段常数. 参数:
x:0-D标量Tensor.boundaries:边界,tensor或list.values:指定定义区间的值.name:操作的名称,默认为PiecewiseConstant.
分段常数衰减就是在定义好的区间上,分别设置不同的常数值,作为学习率的初始值和后续衰减的取值.
#!/usr/bin/python
# coding:utf-8
# piecewise_constant 阶梯式下降法
import matplotlib.pyplot as plt
import tensorflow as tf
global_step = tf.Variable(0, name='global_step', trainable=False)
boundaries = [10, 20, 30]
learing_rates = [0.1, 0.07, 0.025, 0.0125]
y = []
N = 40
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for global_step in range(N):
learing_rate = tf.train.piecewise_constant(global_step, boundaries=boundaries, values=learing_rates)
lr = sess.run([learing_rate])
y.append(lr[0])
x = range(N)
plt.plot(x, y, 'r-', linewidth=2)
plt.title('piecewise_constant')
plt.show()
指数衰减:tf.train.exponential_decay() 应用指数衰减的学习率. 指数衰减是最常用的衰减方法. 参数:
learning_rate:初始学习率.global_step:用于衰减计算的全局步数,非负.用于逐步计算衰减指数.decay_steps:衰减步数,必须是正值.决定衰减周期.decay_rate:衰减率.staircase:若为True,则以不连续的间隔衰减学习速率即阶梯型衰减(就是在一段时间内或相同的eproch内保持相同的学习率);若为False,则是标准指数型衰减.name:操作的名称,默认为ExponentialDecay.(可选项)
指数衰减的学习速率计算公式为:
decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps) 优点:简单直接,收敛速度快.
直观解释:假设给定初始学习率learning_rate为0.1,学习率衰减率为0.1,decay_steps为10000。 则随着迭代次数从1到10000,当前的学习率decayed_learning_rate慢慢的从0.1降低为0.1*0.1=0.01, 当迭代次数到20000,当前的学习率慢慢的从0.01降低为0.1*0.1^2=0.001,以此类推。 也就是说每10000次迭代,学习率衰减为前10000次的十分之一,该衰减是连续的,这是在staircase为False的情况下。
如果staircase为True,则global_step / decay_steps始终取整数,也就是说衰减是突变的,每decay_steps次变化一次,变化曲线是阶梯状。
示例,阶梯型衰减与指数型衰减对比:
#!/usr/bin/python
# coding:utf-8
import matplotlib.pyplot as plt
import tensorflow as tf
global_step = tf.Variable(0, name='global_step', trainable=False)
y = []
z = []
N = 200
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for global_step in range(N):
# 阶梯型衰减
learing_rate1 = tf.train.exponential_decay(
learning_rate=0.5, global_step=global_step, decay_steps=10, decay_rate=0.9, staircase=True)
# 标准指数型衰减
learing_rate2 = tf.train.exponential_decay(
learning_rate=0.5, global_step=global_step, decay_steps=10, decay_rate=0.9, staircase=False)
lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
y.append(lr1[0])
z.append(lr2[0])
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim([0, 0.55])
plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, z, 'g-', linewidth=2)
plt.title('exponential_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.show()
如图,红色:阶梯型;绿色:指数型:
自然指数衰减:tf.train.natural_exp_decay() 应用自然指数衰减的学习率. 参数:
learning_rate:初始学习率.global_step:用于衰减计算的全局步数,非负.decay_steps:衰减步数.decay_rate:衰减率.staircase:若为True,则是离散的阶梯型衰减(就是在一段时间内或相同的eproch内保持相同的学习率);若为False,则是标准型衰减.name: 操作的名称,默认为ExponentialTimeDecay.
natural_exp_decay 和 exponential_decay 形式近似,natural_exp_decay的底数是e.自然指数衰减比指数衰减要快的多,一般用于较快收敛,容易训练的网络. 自然指数衰减的学习率计算公式为:
decayed_learning_rate = learning_rate * exp(-decay_rate * global_step) 示例,指数衰减与自然指数衰减的阶梯型与指数型:
#!/usr/bin/python
# coding:utf-8
import matplotlib.pyplot as plt
import tensorflow as tf
global_step = tf.Variable(0, name='global_step', trainable=False)
y = []
z = []
w = []
N = 200
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for global_step in range(N):
# 阶梯型衰减
learing_rate1 = tf.train.natural_exp_decay(
learning_rate=0.5, global_step=global_step, decay_steps=10, decay_rate=0.9, staircase=True)
# 标准指数型衰减
learing_rate2 = tf.train.natural_exp_decay(
learning_rate=0.5, global_step=global_step, decay_steps=10, decay_rate=0.9, staircase=False)
# 指数衰减
learing_rate3 = tf.train.exponential_decay(
learning_rate=0.5, global_step=global_step, decay_steps=10, decay_rate=0.9, staircase=False)
lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
lr3 = sess.run([learing_rate3])
y.append(lr1[0])
z.append(lr2[0])
w.append(lr3[0])
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim([0, 0.55])
plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, z, 'g-', linewidth=2)
plt.plot(x, w, 'b-', linewidth=2)
plt.title('natural_exp_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.show()
如图,红色:阶梯型;绿色:指数型;蓝色指数型衰减:
多项式衰减:tf.train.polynomial_decay() 应用多项式衰减的学习率. 参数:
learning_rate:初始学习率.global_step:用于衰减计算的全局步数,非负.decay_steps:衰减步数,必须是正值.end_learning_rate:最低的最终学习率.power:多项式的幂,默认为1.0(线性).cycle:学习率下降后是否重新上升.name:操作的名称,默认为PolynomialDecay。
函数使用多项式衰减,以给定的decay_steps将初始学习率(learning_rate)衰减至指定的学习率(end_learning_rate).
多项式衰减的学习率计算公式为:
global_step = min(global_step,decay_steps) decayed_learning_rate = (learning_rate-end_learning_rate)*(1-global_step/decay_steps)^ (power)+end_learning_rate
参数cycle决定学习率是否在下降后重新上升.若cycle为True,则学习率下降后重新上升;使用decay_steps的倍数,取第一个大于global_steps的结果.
decay_steps = decay_steps*ceil(global_step/decay_steps) decayed_learning_rate = (learning_rate-end_learning_rate)*(1-global_step/decay_steps)^ (power)+end_learning_rate
参数cycle目的:防止神经网络训练后期学习率过小导致网络一直在某个局部最小值中振荡;这样,通过增大学习率可以跳出局部极小值.
示例,学习率下降后是否重新上升对比:
#!/usr/bin/python
# coding:utf-8
# 学习率下降后是否重新上升
import matplotlib.pyplot as plt
import tensorflow as tf
y = []
z = []
N = 200
global_step = tf.Variable(0, name='global_step', trainable=False)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for global_step in range(N):
# cycle=False
learing_rate1 = tf.train.polynomial_decay(
learning_rate=0.1, global_step=global_step, decay_steps=50,
end_learning_rate=0.01, power=0.5, cycle=False)
# cycle=True
learing_rate2 = tf.train.polynomial_decay(
learning_rate=0.1, global_step=global_step, decay_steps=50,
end_learning_rate=0.01, power=0.5, cycle=True)
lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
y.append(lr1[0])
z.append(lr2[0])
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, z, 'g-', linewidth=2)
plt.plot(x, y, 'r--', linewidth=2)
plt.title('polynomial_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.show()
如图,红色:下降后不再上升;绿色:下降后重新上升:
余弦衰减:tf.train.cosine_decay() 将余弦衰减应用于学习率 参数:
learning_rate:标初始学习率.global_step:用于衰减计算的全局步数.decay_steps:衰减步数.alpha:最小学习率(learning_rate的部分)。name:操作的名称,默认为CosineDecay.
根据论文SGDR: Stochastic Gradient Descent with Warm Restarts提出.
余弦衰减的学习率计算公式为:
global_step = min(global_step, decay_steps) cosine_decay = 0.5 * (1 + cos(pi * global_step / decay_steps)) decayed = (1 - alpha) * cosine_decay + alpha decayed_learning_rate = learning_rate * decayed
线性余弦衰减:tf.train.linear_cosine_decay() 将线性余弦衰减应用于学习率. 参数:
learning_rate:标初始学习率.global_step:用于衰减计算的全局步数.decay_steps:衰减步数。num_periods:衰减余弦部分的周期数.alpha:见计算.beta:见计算.name:操作的名称,默认为LinearCosineDecay。
根据论文Neural Optimizer Search with Reinforcement Learning提出.
线性余弦衰减的学习率计算公式为:
global_step=min(global_step,decay_steps) linear_decay=(decay_steps-global_step)/decay_steps) cosine_decay = 0.5*(1+cos(pi*2*num_periods*global_step/decay_steps)) decayed=(alpha+linear_decay)*cosine_decay+beta decayed_learning_rate=learning_rate*decayed
噪声线性余弦衰减:tf.train.noisy_linear_cosine_decay() 将噪声线性余弦衰减应用于学习率. 参数:
learning_rate:标初始学习率.global_step:用于衰减计算的全局步数.decay_steps:衰减步数.initial_variance:噪声的初始方差.variance_decay:衰减噪声的方差.num_periods:衰减余弦部分的周期数.alpha:见计算.beta:见计算.name:操作的名称,默认为NoisyLinearCosineDecay.
根据论文Neural Optimizer Search with Reinforcement Learning提出.在衰减过程中加入了噪声,一定程度上增加了线性余弦衰减的随机性和可能性.
噪声线性余弦衰减的学习率计算公式为:
global_step=min(global_step,decay_steps) linear_decay=(decay_steps-global_step)/decay_steps) cosine_decay=0.5*(1+cos(pi*2*num_periods*global_step/decay_steps)) decayed=(alpha+linear_decay+eps_t)*cosine_decay+beta decayed_learning_rate =learning_rate*decayed 示例,线性余弦衰减与噪声线性余弦衰减:
#!/usr/bin/python
# coding:utf-8
import matplotlib.pyplot as plt
import tensorflow as tf
y = []
z = []
w = []
N = 200
global_step = tf.Variable(0, name='global_step', trainable=False)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for global_step in range(N):
# 余弦衰减
learing_rate1 = tf.train.cosine_decay(
learning_rate=0.1, global_step=global_step, decay_steps=50,
alpha=0.5)
# 线性余弦衰减
learing_rate2 = tf.train.linear_cosine_decay(
learning_rate=0.1, global_step=global_step, decay_steps=50,
num_periods=0.2, alpha=0.5, beta=0.2)
# 噪声线性余弦衰减
learing_rate3 = tf.train.noisy_linear_cosine_decay(
learning_rate=0.1, global_step=global_step, decay_steps=50,
initial_variance=0.01, variance_decay=0.1, num_periods=0.2, alpha=0.5, beta=0.2)
lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
lr3 = sess.run([learing_rate3])
y.append(lr1[0])
z.append(lr2[0])
w.append(lr3[0])
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, z, 'b-', linewidth=2)
plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, w, 'g-', linewidth=2)
plt.title('cosine_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.show()
如图,红色:余弦衰减;蓝色:线性余弦衰减;绿色:噪声线性余弦衰减;
反时限衰减:tf.train.inverse_time_decay() 将反时限衰减应用到初始学习率. 参数:
learning_rate:初始学习率.global_step:用于衰减计算的全局步数.decay_steps:衰减步数.decay_rate:衰减率.staircase:是否应用离散阶梯型衰减.(否则为连续型)name:操作的名称,默认为InverseTimeDecay.
该函数应用反向衰减函数提供初始学习速率.利用global_step来计算衰减的学习速率.计算公式为:
decayed_learning_rate =learning_rate/(1+decay_rate* global_step/decay_step) 若staircase为True时:
decayed_learning_rate =learning_rate/(1+decay_rate*floor(global_step/decay_step)) 示例,反时限衰减的阶梯型衰减与连续型对比:
#!/usr/bin/python
# coding:utf-8
import matplotlib.pyplot as plt
import tensorflow as tf
y = []
z = []
N = 200
global_step = tf.Variable(0, name='global_step', trainable=False)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for global_step in range(N):
# 阶梯型衰减
learing_rate1 = tf.train.inverse_time_decay(
learning_rate=0.1, global_step=global_step, decay_steps=20,
decay_rate=0.2, staircase=True)
# 连续型衰减
learing_rate2 = tf.train.inverse_time_decay(
learning_rate=0.1, global_step=global_step, decay_steps=20,
decay_rate=0.2, staircase=False)
lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
y.append(lr1[0])
z.append(lr2[0])
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, z, 'r-', linewidth=2)
plt.plot(x, y, 'g-', linewidth=2)
plt.title('inverse_time_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.show()
如图,蓝色:阶梯型;红色:连续型:
----------------------------------------------------------------------------------------------------------------------------------
以上是单个的使用效果,但是在实际模型中这些函数并不是这么使用的,以下使用两个方法,简述如何在模型中使用学习率衰减!
----------------------------------------------------------------------------------------------------------------------------------
首先第一个例子:
例如
tf.train.exponential_decay(initial_learning_rate, global_step=global_step, decay_steps=1000, decay_rate=0.9)表示没经过1000次的迭代,学习率变为原来的0.9。
增大批次处理样本的数量也可以起到退化学习率的作用。
下面我们写了一个例子,每迭代10次,则较小为原来的0.5,代码如下:
import tensorflow as tf
import numpy as np
global_step = tf.Variable(0, trainable=False)
initial_learning_rate = 0.1
learning_rate = tf.train.exponential_decay(initial_learning_rate,
global_step=global_step,
decay_steps=10,
decay_rate=0.5)
opt = tf.train.GradientDescentOptimizer(learning_rate)
add_global = global_step.assign_add(1)
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(learning_rate))
for i in range(50):
g, rate = sess.run([add_global, learning_rate])
print(g, rate)
在这个代码里面使用add_global = global_step.assign_add(1)来实现全局迭代步数+1的更新;
下面是程序的结果,我们发现每10次就变为原来的一半:
下面在mnist数据集上使用该方法去测试,代码如下:
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
tf.reset_default_graph()
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
w = tf.Variable(tf.random_normal([784, 10]))
b = tf.Variable(tf.zeros([10]))
pred = tf.matmul(x, w) + b
pred = tf.nn.softmax(pred)
cost = tf.reduce_mean(-tf.reduce_sum(y * tf.log(pred), reduction_indices=1))
global_step = tf.Variable(0, trainable=False)
initial_learning_rate = 0.1
learning_rate = tf.train.exponential_decay(initial_learning_rate,
global_step=global_step,
decay_steps=1000,
decay_rate=0.9)
opt = tf.train.GradientDescentOptimizer(learning_rate)
add_global = global_step.assign_add(1)
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
training_epochs = 50
batch_size = 100
display_step = 1
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples/batch_size)
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
_, c, add, rate = sess.run([optimizer, cost, add_global, learning_rate], feed_dict={x:batch_xs, y:batch_ys})
avg_cost += c / total_batch
if (epoch + 1) % display_step == 0:
print('epoch= ', epoch+1, ' cost= ', avg_cost, 'add_global=', add, 'rate=', rate)
print('finished')
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('accuracy: ', accuracy.eval({x:mnist.test.images, y:mnist.test.labels}))
其次是第二个例子:
# 下面设置学习率衰减,tf.train.inverse_time_decay是反时限衰减
global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.inverse_time_decay(LEARNING_RATE, global_step, 5000, 0.5)
Opt_D = tf.train.AdamOptimizer(learning_rate).minimize(D_loss, var_list=D.var(), global_step=global_step)
# 在上面的minimize中会实现global_step次数的加1.一次梯度下降中只需要加一次,之所以下面的就不需要再加了
Opt_G = tf.train.AdamOptimizer(learning_rate).minimize(G_loss, var_list=G.var())
# 如果不想用minimize这种方法,那么可以自己写add_global = global_step.assign_add(1)并计算更新
在sess.run中获取详细的学习率的写法举例:
[dloss, gloss, Mglobal, fakeimg, step, lr] = sess.run([D_loss, G_loss, M_global, fake_img, global_step, learning_rate], feed_dict={real_img: batch, z: z0})
相关例子的详细代码可以下载我注释相应的资源。
参考:https://blog.csdn.net/akadiao/article/details/79560731
https://www.baidu.com/link?url=wlFfuGH8nDDaDfhuElvs2jdyR5keRCHVqjQlXybBcKg5GN9CzrKOIE1Hlepjdb3BtEdlHn8htQEPzqh2BA7D584Ex-gelV5KvFByK9DWp7C&wd=&eqid=f9b7355900003134000000055eaa9aa0
https://www.cnblogs.com/baby-lily/p/10962574.html
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。