神经网络训练过程中,根据每batch训练数据前向传播的结果,计算损失函数,再由损失函数根据梯度下降法更新每一个网络参数,在参数更新过程中使用到一个学习率(learning rate),用来定义每次参数更新的幅度

过小的学习率会降低网络优化的速度,增加训练时间,过大的学习率可能导致网络参数在最终的极优值两侧来回摆动,导致网络不能收敛。实践中证明有效的方法是设置一个根据迭代次数衰减的学习率,可以兼顾训练效率和后期的稳定性。

分段常数衰减

分段常数衰减是在事先定义好的训练次数区间上,设置不同的学习率常数。刚开始学习率大一些,之后越来越小,区间的设置需要根据样本量调整,一般样本量越大区间间隔应该越小。

tf中定义了tf.train.piecewise_constant 函数,实现了学习率的分段常数衰减功能。

tf.train.piecewise_constant(
x,
boundaries,
values,
name=None
)
  1. x: 标量,指代训练次数
  2. boundaries: 学习率参数应用区间列表
  3. values: 学习率列表,values的长度比boundaries的长度多一个
  4. name: 操作的名称

# coding:utf-8

import matplotlib.pyplot as plt
import tensorflow as tf num_epoch = 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 num_epoch in range(N):
learing_rate = tf.train.piecewise_constant(num_epoch, boundaries=boundaries, values=learing_rates)
lr = sess.run([learing_rate])
y.append(lr) x = range(N)
plt.plot(x, y, 'r-', linewidth=2)
plt.title('piecewise_constant')
plt.show()


分段常数衰减可以让调试人员针对不同任务设置不同的学习率,进行精细调参,要求调试人员对模型和数据集有深刻认识,要求较高。

指数衰减

指数衰减是比较常用的衰减方法,学习率是跟当前的训练轮次指数相关的。

tf中实现指数衰减的函数是 tf.train.exponential_decay()。

tf.train.exponential_decay(
learning_rate,
global_step,
decay_steps,
decay_rate,
staircase=False,
name=None
)

  1. learning_rate: 初始学习率
  2. global_step: 当前训练轮次,epoch
  3. decay_step: 定义衰减周期,跟参数staircase配合,可以在decay_step个训练轮次内保持学习率不变
  4. decay_rate,衰减率系数
  5. staircase: 定义是否是阶梯型衰减,还是连续衰减,默认是False,即连续衰减(标准的指数型衰减)
  6. name: 操作名称

函数返回学习率数值,计算公式是:

decayed_learning_rate = learning_rate *
decay_rate ^ (global_step / decay_steps)

# coding:utf-8
import matplotlib.pyplot as plt
import tensorflow as tf num_epoch = tf.Variable(0, name='global_step', trainable=False) y = []
z = []
N = 200 with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for num_epoch in range(N):
# 阶梯型衰减
learing_rate1 = tf.train.exponential_decay(
learning_rate=0.5, global_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=True)
# 标准指数型衰减
learing_rate2 = tf.train.exponential_decay(
learning_rate=0.5, global_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=False)
lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
y.append(lr1)
z.append(lr2) 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()


红色的是阶梯型指数衰减,在一定轮次内学习率保持一致,绿色的是标准的指数衰减,即连续型指数衰减。

自然指数衰减

自然指数衰减是指数衰减的一种特殊情况,学习率也是跟当前的训练轮次指数相关,只不过以 e 为底数。

tf中实现自然指数衰减的函数是 tf.train.natural_exp_decay()

tf.train.natural_exp_decay(
learning_rate,
global_step,
decay_steps,
decay_rate,
staircase=False,
name=None
)

  1. learning_rate: 初始学习率
  2. global_step: 当前训练轮次,epoch
  3. decay_step: 定义衰减周期,跟参数staircase配合,可以在decay_step个训练轮次内保持学习率不变
  4. decay_rate,衰减率系数
  5. staircase: 定义是否是阶梯型衰减,还是连续衰减,默认是False,即连续衰减(标准的指数型衰减)
  6. name: 操作名称

自然指数衰减的计算公式是:

decayed_learning_rate = learning_rate * exp(-decay_rate * global_step)
# coding:utf-8

import matplotlib.pyplot as plt
import tensorflow as tf num_epoch = tf.Variable(0, name='global_step', trainable=False) y = []
z = []
w = []
m = []
N = 200 with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for num_epoch in range(N): # 阶梯型衰减
learing_rate1 = tf.train.natural_exp_decay(
learning_rate=0.5, global_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=True) # 标准指数型衰减
learing_rate2 = tf.train.natural_exp_decay(
learning_rate=0.5, global_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=False) # 阶梯型指数衰减
learing_rate3 = tf.train.exponential_decay(
learning_rate=0.5, global_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=True) # 标准指数衰减
learing_rate4 = tf.train.exponential_decay(
learning_rate=0.5, global_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=False) lr1 = sess.run([learing_rate1])
lr2 = sess.run([learing_rate2])
lr3 = sess.run([learing_rate3])
lr4 = sess.run([learing_rate4]) y.append(lr1)
z.append(lr2)
w.append(lr3)
m.append(lr4) 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, 'r-', linewidth=2)
plt.plot(x, m, 'g-', linewidth=2) plt.title('natural_exp_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.show()


左下部分的两条曲线是自然指数衰减,右上部分的两条曲线是指数衰减,可见自然指数衰减对学习率的衰减程度要远大于一般的指数衰减,一般用于可以较快收敛的网络,或者是训练数据集比较大的场合。

多项式衰减

多项式衰减是这样一种衰减机制:定义一个初始的学习率,一个最低的学习率,按照设置的衰减规则,学习率从初始学习率逐渐降低到最低的学习率,并且可以定义学习率降低到最低的学习率之后,是一直保持使用这个最低的学习率,还是到达最低的学习率之后再升高学习率到一定值,然后再降低到最低的学习率(反复这个过程)。

tf中实现多项式衰减的函数是 tf.train.polynomial_decay()

tf.train.polynomial_decay(
learning_rate,
global_step,
decay_steps,
end_learning_rate=0.0001,
power=1.0,
cycle=False,
name=None
)

  1. learning_rate: 初始学习率
  2. global_step: 当前训练轮次,epoch
  3. decay_step: 定义衰减周期
  4. end_learning_rate:最小的学习率,默认值是0.0001
  5. power: 多项式的幂,默认值是1,即线性的
  6. cycle: 定义学习率是否到达最低学习率后升高,然后再降低,默认False,保持最低学习率
  7. name: 操作名称

多项式衰减的学习率计算公式:

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为True,学习率在到达最低学习率后往复升高降低,此时学习率计算公式为:

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

# 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)
z.append(lr2) 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()


红色的学习率衰减曲线对应 cycle = False,下降后不再上升,保持不变,绿色的学习率衰减曲线对应 cycle = True,下降后往复升降。

多项式衰减中设置学习率可以往复升降的目的是为了防止神经网络后期训练的学习率过小,导致网络参数陷入某个局部最优解出不来,设置学习率升高机制,有可能使网络跳出局部最优解。

余弦衰减

余弦衰减的衰减机制跟余弦函数相关,形状也大体上是余弦形状。tf中的实现函数是:

tf.train.cosine_decay()
tf.train.cosine_decay(
learning_rate,
global_step,
decay_steps,
alpha=0.0,
name=None
)

  1. learning_rate:初始学习率
  2. global_step: 当前训练轮次,epoch
  3. decay_steps: 衰减步数,即从初始学习率衰减到最小学习率需要的训练轮次
  4. alpha=: 最小学习率
  5. name: 操作的名称

余弦衰减学习率计算公式:

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()
噪声线性余弦衰减,对应函数 tf.train.noisy_linear_cosine_decay()

# 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) # 线性余弦衰减
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)
z.append(lr2)
w.append(lr3) 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中实现倒数衰减的函数是 tf.train.inverse_time_decay()。

tf.train.inverse_time_decay(
learning_rate,
global_step,
decay_steps,
decay_rate,
staircase=False,
name=None
)

  1. learning_rate:初始学习率
  2. global_step:用于衰减计算的全局步数
  3. decay_steps:衰减步数
  4. decay_rate:衰减率
  5. staircase:是否应用离散阶梯型衰减(否则为连续型)
  6. name:操作的名称

倒数衰减的计算公式:

decayed_learning_rate =learning_rate/(1+decay_rate* global_step/decay_step)

# 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)
z.append(lr2) 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()


倒数衰减不固定最小学习率,迭代次数越多,学习率越小。

tensorflow中常用学习率更新策略的更多相关文章

  1. tensorflow中的学习率调整策略

    通常为了模型能更好的收敛,随着训练的进行,希望能够减小学习率,以使得模型能够更好地收敛,找到loss最低的那个点. tensorflow中提供了多种学习率的调整方式.在https://www.tens ...

  2. TensorFlow中设置学习率的方式

    目录 1. 指数衰减 2. 分段常数衰减 3. 自然指数衰减 4. 多项式衰减 5. 倒数衰减 6. 余弦衰减 6.1 标准余弦衰减 6.2 重启余弦衰减 6.3 线性余弦噪声 6.4 噪声余弦衰减 ...

  3. 深度学习训练过程中的学习率衰减策略及pytorch实现

    学习率是深度学习中的一个重要超参数,选择合适的学习率能够帮助模型更好地收敛. 本文主要介绍深度学习训练过程中的6种学习率衰减策略以及相应的Pytorch实现. 1. StepLR 按固定的训练epoc ...

  4. J2EE开发中常用的缓存策略

    一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之 ...

  5. tensorflow中常用激活函数和损失函数

    激活函数 各激活函数曲线对比 常用激活函数: tf.sigmoid() tf.tanh() tf.nn.relu() tf.nn.softplus() tf.nn.softmax() tf.nn.dr ...

  6. React中setState同步更新策略

    setState 同步更新 我们在上文中提及,为了提高性能React将setState设置为批次更新,即是异步操作函数,并不能以顺序控制流的方式设置某些事件,我们也不能依赖于this.state来计算 ...

  7. 深度学习---1cycle策略:实践中的学习率设定应该是先增再降

    深度学习---1cycle策略:实践中的学习率设定应该是先增再降 本文转载自机器之心Pro,以作为该段时间的学习记录 深度模型中的学习率及其相关参数是最重要也是最难控制的超参数,本文将介绍 Lesli ...

  8. 分布式系统中一些主要的副本更新策略——Dynamo/Cassandra/Riak同时采取了主从式更新的同步+异步类型,以及任意节点更新的策略。

    分布式系统中一些主要的副本更新策略. 1.同时更新 类型A:没有任何协议,可能出现多个节点执行顺序交叉导致数据不一致情况. 类型B:通过一致性协议唯一确定不同更新操作的执行顺序,从而保证数据一致性 2 ...

  9. Android开发中常用的库总结(持续更新)

    这篇文章用来收集Android开发中常用的库,都是实际使用过的.持续更新... 1.消息提示的小红点 微信,微博消息提示的小红点. 开源库地址:https://github.com/stefanjau ...

随机推荐

  1. Python的函数参数传递

    a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun(a) print a # [1]

  2. c++ 容器元素填充指定数量的元素(generate_n)

    #include <iostream> // cout #include <algorithm> // generate_n using namespace std; ; in ...

  3. 【Golang 接口自动化05】使用yml管理自动化用例

    我们在前面几篇文章中学习怎么发送数据请求,怎么处理解析接口返回的结果,接下来我们一起来学习怎么进行测试用例管理,今天我们介绍的是使用yml文件进行用例管理,所以首先我们一起来了解一下YAML和它的简单 ...

  4. AtomicLong与LongAdder的区别

    AtomicLong的原理 AtomicLong是通过依靠底层的CAS来保障原子性的更新数据,在要添加或者减少的时候,会使用死循环不断地cas到特定的值,从而达到更新数据的目的. LongAdder的 ...

  5. linux下ssh公钥验证的设置和远程登录

    1.第一步 在自己本机,通过工具生成一对公私钥对,对应id_rsa/id_rsa.pub 2.第二步 修改服务器配置     1)复制id_rsa.pub公钥内容    将文件内容追加到~/.ssh/ ...

  6. RabbitMq windows 安装

    参考官方网址: http://www.rabbitmq.com/install-windows-manual.html http://www.rabbitmq.com/install-windows. ...

  7. UVA-11882 Biggest Number (DFS+剪枝)

    题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...

  8. EBS标准的查看供应商地点

    VO数据源:oracle.apps.pos.supplier.server.SitesVO SELECT pvsa.address_style, hzl.language, pvsa.province ...

  9. SPFA单源最短路径算法

    我们用数组d记录每个结点的最短路径估计值,而且用邻接表来存储图G.我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开 ...

  10. POJ服务器不能启动问题

    问题1: 启动tomcat时出现错误:tomcat Address already in use: JVM_Bind:80 按照网上的方法,查找占用80端口的进程:netstat -ano 任务管理器 ...