def exponential_decay_with_warmup(warmup_step,learning_rate_base,global_step,learning_rate_step,learning_rate_decay,staircase=False):
''' 如果learning_rate_base=0.01或者0.1,网络可能训练失败,0.001又太小了,这时候可以考虑前10个epoch线性增长到0.1
这样网络不会像一开始就0.1那样训练崩掉
warmup有助于网络的收敛,在某些情况下如果没有warmup可能导致网络无法收敛
至于理论上的解释,还没有得到充分证明,只管上来讲就是初期网络参数是随机数,对参数优化(包括BN层的方差,均值还不稳定)取决于当前这组,
有可能网络因此对该组数据过拟合,进入某个局部最优解,后面要多花很多组才能调回来
前期使用小学习率,网络对数据分布大致有个了解,这时候使用大学习率就不容易跑偏
当然训练到几十个epoch之后模型的分布就已经比较固定了,或者说能学到的新东西就比较少了。如果还沿用较大的学习率
就会破坏这种稳定性,用我们通常的话说,就是已经接近loss的local optimal了,为了靠近这个point,我们就要慢慢来,所以后期进行
指数衰减的学习率(或者其他的衰减形式)
warmup_step:warmup线性增长的step数
learning_rate_base学习率最大值
global_step一个全局的计数器,注意设置trainable=False,并在优化器的minimize里面填写global_step=global_step
[ global_step: tf.Variable(0,trainable=False) ]
learning_rate_step 每隔 step衰减一次
learning_rate_decat 衰减率
参数设置个人建议最终训练完学习率大致为learning_rate_base的1/50,learning_rate_decay在0.95到0.995之间
'''
with tf.name_scope("exponential_decay_with_warmup"):
linear_increase=learning_rate_base*tf.cast(global_step/warmup_step,tf.float32)
exponential_decay=tf.train.exponential_decay(learning_rate_base,
global_step-warmup_step,
learning_rate_step,
learning_rate_decay,
staircase=staircase)
learning_rate=tf.cond(global_step<=warmup_step,
lambda:linear_increase,
lambda:exponential_decay)
return learning_rate
学习率变化曲线图:
先缓慢线性增长,到达最大值后进行指数衰减