精华内容
下载资源
问答
  • Keras中那些学习率衰减策略

    千次阅读 多人点赞 2020-07-26 13:30:44
    神经网路的训练绕不开的调参,调参中学习率至为重要。下面聊聊Keras中提供的学习率策略。 四种学习率衰减策略 指数衰减

    神经网路的训练绕不开的调参,调参中学习率至为重要。下面聊聊Keras中提供的学习率策略。

    从optimizer的SGD说起

    最常见的就是SGD和Adam。这里以SGD为例,看看在模型训练过程中,学习率是如何改变的。
    参考官方文档,SGD的定义如下:

    tf.keras.optimizers.SGD(
        learning_rate=0.01, momentum=0.0, nesterov=False, name='SGD', **kwargs
    )
    

    梯度下降算法中,一般情况下权重 θ t \theta_{t} θt的更新方法如下式,其中 g t g_{t} gt表示求得的梯度。
    θ t = θ t − 1 − l e a r n i n g _ r a t e ∗ g t \theta_{t}=\theta_{t-1}- learning\_rate * g_{t} θt=θt1learning_rategt
    当考虑momentum优化方法时,更新方式变为如下:
    v t = m o m e n t u m ∗ v t − 1 − l e a r n i n g r a t e ∗ g t v_{t}= momentum * v_{t-1}- learning rate * g_{t} vt=momentumvt1learningrategt
    θ t = θ t − 1 + v t \theta_{t}=\theta_{t-1}+v_{t} θt=θt1+vt

    (1)自定义 time-Based Learning Rate Schedule(基于时间的学习率计划)

    具体计算如下:

    LearningRate = LearningRate * 1/(1 + decay * epoch)
    

    在上述的SGD定义中,**kwargs中有decay这个参数,默认值为0时,学习率不会衰减。
    当初始learning_rate=0.1,decay=0.001时,

    Epoch	Learning Rate
    1	0.1
    2	0.0999000999
    3	0.0997006985
    4	0.09940249103
    5	0.09900646517
    
    from  tf.keras.optimizers import SGD
    #...
    # Compile model
    epochs = 50
    learning_rate = 0.1
    decay_rate = learning_rate / epochs
    momentum = 0.8
    sgd = SGD(lr=learning_rate, momentum=momentum, decay=decay_rate, nesterov=False)
    model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
    # Fit the model
    model.fit(X, Y, validation_split=0.33, epochs=epochs, batch_size=28, verbose=2)
    

    (2) 四种Keras提供的学习率衰减策略

    四种衰减策略分别是ExponentialDecay(指数衰减), PiecewiseConstantDecay(分段常数衰减) , PolynomialDecay(多项式衰减)
    InverseTimeDecay(逆时间衰减)。
    直接使用方法:
    假如当拟合Keras模型时,每100000步衰减一次,基数为0.96

    lr_schedule = keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate=1e-2,
        decay_steps=10000,
        decay_rate=0.96)
    optimizer = keras.optimizers.SGD(learning_rate=lr_schedule)
    

    a.指数衰减

    定义:

    tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate, decay_steps, decay_rate, staircase=False, name=None
    )
    

    具体的计算实现:

       def decayed_learning_rate(step):
          return initial_learning_rate * decay_rate ^ (step / decay_steps)
    

    由此我们可以知道,随着训练step的增加,学习率不断地被更新。
    这里的一个step指的是一个batch。

    b.分段常数衰减

    例如:对于前100001步,学习率为1.0,对于接下来的10000步,学习率为0.5,对于任何其他步骤,学习率为0.1

    step = tf.Variable(0, trainable=False)
    boundaries = [100000, 110000]
    values = [1.0, 0.5, 0.1]
    learning_rate_fn = keras.optimizers.schedules.PiecewiseConstantDecay(
        boundaries, values)
    
    # Later, whenever we perform an optimization step, we pass in the step.
    learning_rate = learning_rate_fn(step)
    

    c.多项式衰减

    给定一个初始学习率和一个结束学习率,优化过程中使用指定多项式形式从初始学习率降到一个结束学习率,比如用2次、3次多项式。
    计算过程如下:

    def decayed_learning_rate(step):
      step = min(step, decay_steps)
      return ((initial_learning_rate - end_learning_rate) *
              (1 - step / decay_steps) ^ (power)
             ) + end_learning_rate
    

    比如:拟合一个模型,在10000步中从0.1衰减到0.01,使用开根式( power=0.5):

    starter_learning_rate = 0.1
    end_learning_rate = 0.01
    decay_steps = 10000
    learning_rate_fn = tf.keras.optimizers.schedules.PolynomialDecay(
        starter_learning_rate,
        decay_steps,
        end_learning_rate,
        power=0.5)
    
    model.compile(optimizer=tf.keras.optimizers.SGD(
                      learning_rate=learning_rate_fn),
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    
    model.fit(data, labels, epochs=5)
    

    d.逆时间衰减

    def decayed_learning_rate(step):
      return initial_learning_rate / (1 + decay_rate * step / decay_step)
    

    以0.5衰减率,decay_step=1拟合模型:

    initial_learning_rate = 0.1
    decay_steps = 1.0
    decay_rate = 0.5
    learning_rate_fn = keras.optimizers.schedules.InverseTimeDecay(
      initial_learning_rate, decay_steps, decay_rate)
    
    model.compile(optimizer=tf.keras.optimizers.SGD(
                      learning_rate=learning_rate_fn),
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    

    2. 使用callbacks来实现动态、自定义学习率衰减策略

    由于optimizer无法访问 validation metrics,因此使用这些调度对象无法实现动态学习率调度(例如,在验证集中loss不再改善时降低学习率)。然而,callbacks可以访问所有指标,包括 validation metrics。因此,您可以通过使用一个callback来修改优化器上的当前学习率来实现动态修改学习率。实际上,这甚至是内置的ReduceLROnPlateau回调。
    当我们使用calllback定义的学习率衰减策略时,optimizer中的学习率衰减策略就会被忽视。

    (1)自定义 time-Based Learning Rate Schedule

    tf.keras.callbacks.LearningRateScheduler(
        schedule, verbose=0
    )
    

    1
    例如:前10个epochs学习率保持不变,后面学习率呈指数衰减

    # This function keeps the learning rate at 0.001 for the first ten epochs
    # and decreases it exponentially after that.
    def scheduler(epoch):
      if epoch < 10:
        return 0.001
      else:
        return 0.001 * tf.math.exp(0.1 * (10 - epoch))
    
    callback = tf.keras.callbacks.LearningRateScheduler(scheduler)
    model.fit(data, labels, epochs=100, callbacks=[callback],
              validation_data=(val_data, val_labels))
    

    (2)Drop-Based Learning Rate Schedule

    LearningRateScheduler的callback允许我们定义一个函数来调用epoch number 作为参数并返回随机梯度下降中使用的学习速率。可以定义一个半衰减的学习策略,如下计算公式,DropRate=0.5, floor(Epoch / EpochDrop)计算什么时候更新学习率,当EpochDrop=10时表示每经过10epochs,学习率变为原来的一半。

    LearningRate = InitialLearningRate * DropRate^floor(Epoch / EpochDrop)
    

    具体实现和使用:

    # Drop-Based Learning Rate Decay
    import math
    from  tf.keras.optimizers import SGD
    from  tf.keras.callbacks import LearningRateScheduler
    
    # learning rate schedule
    def step_decay(epoch):
    	initial_lrate = 0.1
    	drop = 0.5
    	epochs_drop = 10.0
    	lrate = initial_lrate * math.pow(drop, math.floor((1+epoch)/epochs_drop))
    	return lrate
    # ...
    # Compile model
    sgd = SGD(lr=0.0, momentum=0.9)
    model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
    # learning schedule callback
    lrate = LearningRateScheduler(step_decay)
    callbacks_list = [lrate]
    # Fit the model
    model.fit(X, Y, validation_split=0.33, epochs=50, batch_size=28, callbacks=callbacks_list, verbose=2)
    

    (3)使用ReduceLROnPlateau动态修改学习率

    当验证集上的loss几乎不在改变时,修改学习率为原来的2-10倍通常能获得更好的结果。使用ReduceLROnPlateau就能做到。
    其定义如下:

    tf.keras.callbacks.ReduceLROnPlateau(
        monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto',
        min_delta=0.0001, cooldown=0, min_lr=0, **kwargs
    )
    

    22
    例如当训练集连续5个epochs的改变小于min_delta(默认为0.0001)时,修改学习率为原来的五分之一(new_lr = lr * factor)。

    reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,
                                  patience=5, min_lr=0.001)
    model.fit(X_train, Y_train, callbacks=[reduce_lr])
    

    Using Learning Rate Schedules for Deep Learning Models in Python with Keras
    Keras官方文档

    展开全文
  • 关于余弦退火学习率衰减策略的详细介绍可以参考文章:学习率衰减之余弦退火(CosineAnnealing)。 代码实现 在 Tensorflow2.0 中自定义学习率衰减策略其实很简单,可以参考文章:Tensorflow2.0学习率衰减详细汇总。 ...

    项目说明

    余弦退火学习率衰减的学习率曲线如下图所示:
    在这里插入图片描述
    除了在训练过程中进行学习率衰减以防止求得的最优解不断震荡之外,余弦退火衰减策略规定,学习率每次衰减到0之后,会迅速回升至初始值,这样可以避免陷入局部最优解。关于余弦退火学习率衰减策略的详细介绍可以参考文章:学习率衰减之余弦退火(CosineAnnealing)

    代码实现

    在 Tensorflow2.0 中自定义学习率衰减策略其实很简单,可以参考文章:Tensorflow2.0学习率衰减详细汇总

    import tensorflow as tf
    
    展开全文
  • 深度学习中的固定学习率衰减策略总结 深层神经网络的参数学习主要是通过梯度下降方法来寻找一组可以最小化结构风险的参数。 在梯度下降中学习率的取值非常关键,如果过大可能不会收敛,过小则收敛速度太慢。 通常的...

    深度学习中的固定学习率衰减策略总结
    深层神经网络的参数学习主要是通过梯度下降方法来寻找一组可以最小化结构风险的参数。 在梯度下降中学习率的取值非常关键,如果过大可能不会收敛,过小则收敛速度太慢。

    通常的策略的在一开始采用大的学习率保证收敛,在收敛到最优点附近时要小些以避免来回震荡。因此,比较简单直接的学习率 调整可以通过学习率衰减(Learning Rate Decay)的方式来实现。

    学习率衰减策略可以分为两种:固定策略的学习率衰减和自适应学习率衰减,其中固定学习率衰减包括分段衰减、逆时衰减、指数衰减等,自适应学习率衰减包括AdaGrad、 RMSprop、 AdaDelta等。一般情况,两种策略会结合使用。

    本文主要基于tensorflow,对一些常见的固定策略衰减策略进行总结,包括基本的衰减策略、循环学习率衰减和单循环学习率衰减。

    基本学习率衰减
    piecewise decay
    分段常数衰减, 在训练过程中不同阶段设置不同的学习率,便于更精细的调参。在目标检测任务如Faster RCNN 和 SSD 的训练中都采用分段常数衰减策略,调整学习率。

    方法接口
    tf.train.piecewise_constant_decay
    boundaries:学习率衰减边界;values:不同阶段对应学习率。

    注意由于boundaries忽略了初始边界0,因此values的长度会比boundaries多1。

    验证代码

    import os
    import tensorflow as tf
    
    summary_path = './summary'
    method = 'piecewise_decay'
    
    max_step = 20000
    base_learning_rate = 0.01
    decay_boundaries = [5000, 8000]
    learning_rate_value = [base_learning_rate, base_learning_rate/10., base_learning_rate/100.]
    summary_step = 10
    
    def main():
    
        global_step_op = tf.train.get_or_create_global_step()
    
        # x = tf.get_variable(shape=[1], initializer=tf.random_normal_initializer(), name="x")
        learning_rate =  tf.train.piecewise_constant_decay(global_step_op,
                                                           boundaries=decay_boundaries,
                                                           values=learning_rate_value)
        tf.summary.scalar("learning_rate", learning_rate)
        summary_op = tf.summary.merge_all()
    
        init_op = tf.group(tf.global_variables_initializer(),
                           tf.local_variables_initializer())
    
        with tf.Session() as sess:
            sess.run(init_op)
    
            summary_write = tf.summary.FileWriter(os.path.join(summary_path, method))
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess, coord)
            try:
                if not coord.should_stop():
                    for step in range(max_step):
                        if step % summary_step == 0:
                            summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
                            summary_write.add_summary(summary, global_step=global_step)
                            summary_write.flush()
    
                        summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
    
            except Exception as e:
                # Report exceptions to the coordinator.
                coord.request_stop(e)
            finally:
                coord.request_stop()
                coord.join(threads)
                print('all threads are asked to stop!')
    
    if __name__ == "__main__":
        main()
    

    在这里插入图片描述
    exponential decay
    指数衰减:学习率以指数的形式进行衰减,其中指数函数的底为decay_rate, 指数为 global_step / decay_steps

    函数接口
    tf.train.exponential_decay
    learning_rate: 基学习率;decay_rate: 衰减率;decay_steps: 衰减步数(周期)

    staircase: 是否以离散的时间间隔衰减学习率

    验证代码

    import os
    import tensorflow as tf
    
    summary_path = './summary'
    method = 'exponential_decay'
    
    max_step = 20000
    base_learning_rate = 0.01
    decay_rate = 0.98
    decay_steps = 2000
    summary_step = 10
    
    def main():
    
        global_step_op = tf.train.get_or_create_global_step()
        #  decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
        learning_rate_no_stair =  tf.train.exponential_decay(learning_rate=base_learning_rate,
                                                    decay_rate=decay_rate,
                                                    decay_steps=decay_steps,
                                                    staircase=False,
                                                    global_step=global_step_op,
                                                    name="exponential_decay_no_stair")
        tf.summary.scalar("exponential_decay_no_stair", learning_rate_no_stair)
        learning_rate_no_stair = tf.train.exponential_decay(learning_rate=base_learning_rate,
                                                            decay_rate=decay_rate,
                                                            decay_steps=decay_steps,
                                                            staircase=True,
                                                            global_step=global_step_op,
                                                            name="exponential_decay_use_stair")
        tf.summary.scalar("exponential_decay_use_stair", learning_rate_no_stair)
        summary_op = tf.summary.merge_all()
    
        init_op = tf.group(tf.global_variables_initializer(),
                           tf.local_variables_initializer())
    
        with tf.Session() as sess:
            sess.run(init_op)
    
            summary_write = tf.summary.FileWriter(os.path.join(summary_path, method))
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess, coord)
            try:
                if not coord.should_stop():
                    for step in range(max_step):
                        if step % summary_step == 0:
                            summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
                            summary_write.add_summary(summary, global_step=global_step)
                            summary_write.flush()
    
                        summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
    
            except Exception as e:
                # Report exceptions to the coordinator.
                coord.request_stop(e)
            finally:
                coord.request_stop()
                coord.join(threads)
                print('all threads are asked to stop!')
    
    if __name__ == "__main__":
        main()
    

    在这里插入图片描述
    在这里插入图片描述
    natural exponential decay
    自然指数衰减:学习率以自然指数进行衰减,其中指数函数底为自然常数e, 指数为-decay_rate * global_step / decay_step, 相比指数衰减具有更快的衰减速度。

    方法接口
    tf.train.natural_exp_decay
    learning_rate: 基学习率;decay_rate: 衰减率;decay_steps: 衰减步数/周期;staircase: 是否以离散的时间间隔衰减学习率

    验证代码

    import os
    import tensorflow as tf
    
    summary_path = './summary'
    method = 'natural_exp_decay'
    
    max_step = 20000
    base_learning_rate = 0.01
    decay_rate = 0.98
    decay_steps = 2000
    summary_step = 10
    
    def main():
    
        global_step_op = tf.train.get_or_create_global_step()
    
        # decayed_learning_rate = learning_rate * exp(-decay_rate * global_step / decay_step)
        learning_rate_no_stair =  tf.train.natural_exp_decay(learning_rate=base_learning_rate,
                                                            decay_rate=decay_rate,
                                                            decay_steps=decay_steps,
                                                            staircase=False,
                                                            global_step=global_step_op,
                                                            name="natural_exp_decay_no_stair")
        tf.summary.scalar("natural_exp_decay_no_stair", learning_rate_no_stair)
        learning_rate_no_stair = tf.train.natural_exp_decay(learning_rate=base_learning_rate,
                                                            decay_rate=decay_rate,
                                                            decay_steps=decay_steps,
                                                            staircase=True,
                                                            global_step=global_step_op,
                                                            name="natural_exp_decay_use_stair")
        tf.summary.scalar("natural_exp_decay_use_stair", learning_rate_no_stair)
        summary_op = tf.summary.merge_all()
    
        init_op = tf.group(tf.global_variables_initializer(),
                           tf.local_variables_initializer())
    
        with tf.Session() as sess:
            sess.run(init_op)
    
            summary_write = tf.summary.FileWriter(os.path.join(summary_path, method))
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess, coord)
            try:
                if not coord.should_stop():
                    for step in range(max_step):
                        if step % summary_step == 0:
                            summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
                            summary_write.add_summary(summary, global_step=global_step)
                            summary_write.flush()
    
                        summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
    
            except Exception as e:
                # Report exceptions to the coordinator.
                coord.request_stop(e)
            finally:
                coord.request_stop()
                coord.join(threads)
                print('all threads are asked to stop!')
    
    if __name__ == "__main__":
        main()
    

    在这里插入图片描述
    在这里插入图片描述
    polynomial decay
    多项式衰减:调整学习率的衰减轨迹以多项式对应的轨迹进行。其中(1 - global_step / decay_steps) 为幂函数的底; power为指数,控制衰减的轨迹。

    方法接口
    tf.train.polynomial_decay
    learning_rate: 基学习率;decay_steps: 衰减率衰减步数;power: 多项式的幂;end_learning_rate:最小学习率

    验证代码

    import os
    import tensorflow as tf
    
    summary_path = './summary'
    method = 'polynomial_decay'
    
    max_step = 20000
    base_learning_rate = 0.01
    decay_steps = 10000
    end_learning_rate = 0.00001
    summary_step = 10
    
    def main():
    
        global_step_op = tf.train.get_or_create_global_step()
    
        # global_step = min(global_step, decay_steps)
        # decayed_learning_rate = (learning_rate - end_learning_rate) *
        #                           (1 - global_step / decay_steps) ^ (power) + end_learning_rate
        learning_rate_power_1 =  tf.train.polynomial_decay(learning_rate=base_learning_rate,
                                                            decay_steps=decay_steps,
                                                            end_learning_rate = end_learning_rate,
                                                            power=1.,
                                                            global_step=global_step_op,
                                                            name="polynomial_decay_power_1")
        tf.summary.scalar("polynomial_decay_power_1", learning_rate_power_1)
        learning_rate_power_05 = tf.train.polynomial_decay(learning_rate=base_learning_rate,
                                                          decay_steps=decay_steps,
                                                          end_learning_rate=end_learning_rate,
                                                          power=0.5,
                                                          global_step=global_step_op,
                                                          name="polynomial_decay_power_05")
        tf.summary.scalar("polynomial_decay_power_05", learning_rate_power_05)
        learning_rate_power_2 = tf.train.polynomial_decay(learning_rate=base_learning_rate,
                                                           decay_steps=decay_steps,
                                                           end_learning_rate=end_learning_rate,
                                                           power=2,
                                                           global_step=global_step_op,
                                                           name="polynomial_decay_power_2")
        tf.summary.scalar("polynomial_decay_power_2", learning_rate_power_2)
        summary_op = tf.summary.merge_all()
    
        init_op = tf.group(tf.global_variables_initializer(),
                           tf.local_variables_initializer())
    
        with tf.Session() as sess:
            sess.run(init_op)
    
            summary_write = tf.summary.FileWriter(os.path.join(summary_path, method))
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess, coord)
            try:
                if not coord.should_stop():
                    for step in range(max_step):
                        if step % summary_step == 0:
                            summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
                            summary_write.add_summary(summary, global_step=global_step)
                            summary_write.flush()
    
                        summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
    
            except Exception as e:
                # Report exceptions to the coordinator.
                coord.request_stop(e)
            finally:
                coord.request_stop()
                coord.join(threads)
                print('all threads are asked to stop!')
    
    if __name__ == "__main__":
        main()
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    cosine decay
    余弦衰减:学习率以cosine 函数曲线进行进行衰减, 其中余弦函数的周期为
    [公式]
    , 自变量为
    在这里插入图片描述

    函数接口
    tf.train.cosine_decay
    learning_rate: 基学习率;decay_steps: 衰减率衰减步数;alpha: 最小学习率

    代码验证

    import os
    import tensorflow as tf
    
    summary_path = './summary'
    method = 'cosine_decay'
    
    max_step = 20000
    base_learning_rate = 0.01
    decay_steps = 10000
    alpha = 0.001
    summary_step = 10
    
    def main():
    
        global_step_op = tf.train.get_or_create_global_step()
    
        # 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
        # update learning rate(decayed learning rate) just according to decayed parameter and learning no change
        learning_rate =  tf.train.cosine_decay(learning_rate=base_learning_rate,
                                               decay_steps=decay_steps,
                                               alpha=alpha,
                                               global_step=global_step_op,
                                               name="cosine_decay")
        tf.summary.scalar("learning_rate", learning_rate)
        summary_op = tf.summary.merge_all()
    
        init_op = tf.group(tf.global_variables_initializer(),
                           tf.local_variables_initializer())
    
        with tf.Session() as sess:
            sess.run(init_op)
    
            summary_write = tf.summary.FileWriter(os.path.join(summary_path, method))
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess, coord)
            try:
                if not coord.should_stop():
                    for step in range(max_step):
                        if step % summary_step == 0:
                            summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
                            summary_write.add_summary(summary, global_step=global_step)
                            summary_write.flush()
    
                        summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
    
            except Exception as e:
                # Report exceptions to the coordinator.
                coord.request_stop(e)
            finally:
                coord.request_stop()
                coord.join(threads)
                print('all threads are asked to stop!')
    
    if __name__ == "__main__":
        main()
    

    在这里插入图片描述
    linear cosine decay
    线性余弦衰减:动机式在开始的几个周期,执行warm up 操作,线性余弦衰减比余弦衰减更具aggressive,通常可以使用更大的初始学习速率。其中余弦函数的周期 为
    在这里插入图片描述
    函数接口
    tf.train.linear_cosine_decay
    learning_rate: 基学习率;decay_steps: 衰减率衰减步数;alpha: 调节学习率衰减系数;
    beta: 最小学习率;num_periods:余弦衰减部分周期数

    代码验证

    import os
    import tensorflow as tf
    
    summary_path = './summary'
    method = 'linear_cosine_decay'
    
    max_step = 20000
    base_learning_rate = 0.01
    decay_steps = 10000
    num_periods_05= 0.5
    num_periods_4 = 4
    alpha = 0.001
    beta = 0.001
    summary_step = 10
    
    def main():
    
        global_step_op = tf.train.get_or_create_global_step()
    
        # 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
        linear_cosine_decay_05 = tf.train.linear_cosine_decay(learning_rate=base_learning_rate,
                                                             decay_steps=decay_steps,
                                                             num_periods=num_periods_05,
                                                             alpha=alpha,
                                                             beta=beta,
                                                             global_step=global_step_op,
                                                             name="linear_cosine_decay_05")
        tf.summary.scalar("linear_cosine_decay_05", linear_cosine_decay_05)
        linear_cosine_decay_4 =  tf.train.linear_cosine_decay(learning_rate=base_learning_rate,
                                                       decay_steps=decay_steps,
                                                       num_periods=num_periods_4,
                                                       alpha=alpha,
                                                       beta = beta,
                                                       global_step=global_step_op,
                                                       name="linear_cosine_decay_4")
        tf.summary.scalar("linear_cosine_decay_4", linear_cosine_decay_4)
        summary_op = tf.summary.merge_all()
    
        init_op = tf.group(tf.global_variables_initializer(),
                           tf.local_variables_initializer())
    
        with tf.Session() as sess:
            sess.run(init_op)
    
            summary_write = tf.summary.FileWriter(os.path.join(summary_path, method))
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess, coord)
            try:
                if not coord.should_stop():
                    for step in range(max_step):
                        if step % summary_step == 0:
                            summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
                            summary_write.add_summary(summary, global_step=global_step)
                            summary_write.flush()
    
                        summary, global_step = sess.run([summary_op, global_step_op], feed_dict={global_step_op:step})
    
            except Exception as e:
                # Report exceptions to the coordinator.
                coord.request_stop(e)
            finally:
                coord.request_stop()
                coord.join(threads)
                print('all threads are asked to stop!')
    
    if __name__ == "__main__":
        main()
    

    在这里插入图片描述
    在这里插入图片描述
    参考资料

    https://github.com/tensorflow/models/blob/v1.13.0/official/resnet/resnet_run_loop.py#L225
    https://github.com/tensorflow/models/blob/master/research/object_detection/utils/learning_schedules.py
    https://www.zhihu.com/question/338066667/answer/771252708

    展开全文
  • Dl4j学习率衰减策略,机器学习应用程序由两个部分组成。一个部分负责加载数据并对其进行预加工,以供网络学习。我们将这一部分称为ETL(提取、转换、加载)流程。 我们建立了名为DataVec 的库来简化这一流程。另一个...
  • 原文:pytorch必须掌握的的4种学习率衰减策略1.指数衰减2. 固定步长衰减3. 多步长衰减4. 余弦退火衰减5. 上述4种学习率动态更新策略的说明 梯度下降算法需要我们指定一个学习率作为权重更新步幅的控制因子,常用的...

    在这里插入图片描述
    原文:

    梯度下降算法需要我们指定一个学习率作为权重更新步幅的控制因子,常用的学习率有0.01、0.001以及0.0001等,学习率越大则权重更新。一般来说,我们希望在训练初期学习率大一些,使得网络收敛迅速,在训练后期学习率小一些,使得网络更好的收敛到最优解。下图展示了随着迭代的进行动态调整学习率的4种策略曲线:

    在这里插入图片描述
    上述4种策略为自己根据资料整理得到的衰减类型:指数衰减、固定步长的衰减、多步长衰、余弦退火衰减。下面逐一介绍其性质,及pytorch对应的使用方式,需要注意学习率衰减策略很大程度上是依赖于经验与具体问题的,不能照搬参数。

    1.指数衰减

    学习率按照指数的形式衰减是比较常用的策略,我们首先需要确定需要针对哪个优化器执行学习率动态调整策略,也就是首先定义一个优化器:

    optimizer_ExpLR = torch.optim.SGD(net.parameters(), lr=0.1)
    

    定义好优化器以后,就可以给这个优化器绑定一个指数衰减学习率控制器:

    ExpLR = torch.optim.lr_scheduler.ExponentialLR(optimizer_ExpLR, gamma=0.98)
    

    其中参数gamma表示衰减的底数,选择不同的gamma值可以获得幅度不同的衰减曲线,如下:
    在这里插入图片描述

    2. 固定步长衰减

    有时我们希望学习率每隔一定步数(或者epoch)就减少为原来的gamma分之一,使用固定步长衰减依旧先定义优化器,再给优化器绑定StepLR对象:

    optimizer_StepLR = torch.optim.SGD(net.parameters(), lr=0.1)
    StepLR = torch.optim.lr_scheduler.StepLR(optimizer_StepLR, step_size=step_size, gamma=0.65)
    

    其中gamma参数表示衰减的程度,step_size参数表示每隔多少个step进行一次学习率调整,下面对比了不同gamma值下的学习率变化情况:
    在这里插入图片描述

    Example:
            >>> # Assuming optimizer uses lr = 0.05 for all groups
            >>> # lr = 0.05     if epoch < 30
            >>> # lr = 0.005    if 30 <= epoch < 60
            >>> # lr = 0.0005   if 60 <= epoch < 90
            >>> # ...
            >>> scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
            >>> for epoch in range(100):
            >>>     train(...)
            >>>     validate(...)
            >>>     scheduler.step()
    

    3. 多步长衰减

    上述固定步长的衰减的虽然能够按照固定的区间长度进行学习率更新,但是有时我们希望不同的区间采用不同的更新频率,或者是有的区间更新学习率,有的区间不更新学习率,这就需要使用MultiStepLR来实现动态区间长度控制:

    optimizer_MultiStepLR = torch.optim.SGD(net.parameters(), lr=0.1)
    torch.optim.lr_scheduler.MultiStepLR(optimizer_MultiStepLR,
                        milestones=[200, 300, 320, 340, 200], gamma=0.8)
    

    其中milestones参数为表示学习率更新的起止区间,在区间[0. 200]内学习率不更新,而在[200, 300]、[300, 320]…[340, 400]的右侧值都进行一次更新;gamma参数表示学习率衰减为上次的gamma分之一。其图示如下:

    在这里插入图片描述
    从图中可以看出,学习率在区间[200, 400]内快速的下降,这就是milestones参数所控制的,在milestones以外的区间学习率始终保持不变。

    Example:
            >>> # Assuming optimizer uses lr = 0.05 for all groups
            >>> # lr = 0.05     if epoch < 30
            >>> # lr = 0.005    if 30 <= epoch < 80
            >>> # lr = 0.0005   if epoch >= 80
            >>> scheduler = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)
            >>> for epoch in range(100):
            >>>     train(...)
            >>>     validate(...)
            >>>     scheduler.step()
    

    4. 余弦退火衰减

    严格的说,余弦退火策略不应该算是学习率衰减策略,因为它使得学习率按照周期变化,其定义方式如下:

    optimizer_CosineLR = torch.optim.SGD(net.parameters(), lr=0.1)
    CosineLR = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer_CosineLR, T_max=150, eta_min=0)
    

    其包含的参数和余弦知识一致,参数T_max表示余弦函数周期;eta_min表示学习率的最小值,默认它是0表示学习率至少为正值。确定一个余弦函数需要知道最值和周期,其中周期就是T_max,最值是初试学习率。下图展示了不同周期下的余弦学习率更新曲线:
    在这里插入图片描述

    5. 上述4种学习率动态更新策略的说明

    4个负责学习率调整的类:StepLR、ExponentialLR、MultiStepLR和CosineAnnealingLR,其完整对学习率的更新都是在其step()函数被调用以后完成的,这个step表达的含义可以是一次迭代,当然更多情况下应该是一个epoch以后进行一次scheduler.step(),这根据具体问题来确定。此外,根据pytorch官网上给出的说明,scheduler.step()函数的调用应该在训练代码以后:

    >>> scheduler = ...
    >>> for epoch in range(100):
    >>>     train(...)
    >>>     validate(...)
    >>>     scheduler.step()
    
    展开全文
  • Dl4j学习率衰减策略

    2018-01-03 14:37:00
    Dl4j学习率衰减策略package org.deeplearning4j.nn.conf;/** * Learning Rate Policy * * How to decay learning rate during training. * * <p><b>None</b> = do not apply decay policy aka fixed in Caffe ...
  • 几种学习率衰减策略

    千次阅读 2019-12-04 14:19:36
    常用的学习率调整方法包括学习率衰减率、学习率预热、周期学习率以及一些自适应地调整学习率的方法,比如AdaGrad、RMSprop、AdaDelta等。自适应学习率方法可以针对每个参数设置不同的学习率。 周期性学习率调整 ...
  • 下图展示了随着四种常用的学习率衰减策略曲线: 1、指数衰减 学习率按照指数的形式衰减是比较常用的策略,我们首先需要确定需要针对哪个优化器执行学习率动态调整策略,也就是首先定义一个优化器: ...
  • import tensorflow as tf import math import matplotlib.pyplot as plt class CosineWarmup(tf.keras.optimizers.schedules.LearningRateSchedule): def __init__(self, warmup_slope, warmup_steps, cosine_...
  • 学习率(learning rate,lr)是在神经网络的训练过程中一个很重要的超参数,对神经网络的训练效果与训练时间成本有很大影响。 学习率对训练效果的影响(主要体现在对网络的有效容量/参数搜索空间的影响上): 学....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,467
精华内容 4,186
关键字:

学习率衰减策略