深度学习学习率加速方法。Learning Rate scheduling优化

如何实现Power scheduling?

optimizer = tf.keras.optimizers.SGD(lr=0.01,decay=1e-4)

 

如何实现Exponential scheduling?

def exponential_decay(lr0,s):

    def exponential_decay_fn(epoch):

        return lr0*0.1**(epoch/s)

    return exponential_decay_fn

exponential_decay_fn = exponential_decay(lr0=0.01,s=20)

 

如何实现Piecewise Constat scheduling?

 

def piecewise_constant_fn(epoch):

    if epoch<5:

        return 0.01

    elif epoch<15:

        return 0.005

    else:

        return 0.001

 

什么是 1cycle scheduling?

简单来说,1cycle scheduling, 使用的是一种周期性学习率,从较小的学习率开始学习,缓慢提高至较高的学习率,然后再慢慢下降,周而复始,每个周期的长度略微缩短,在训练的最后部分,学习率比之前的最小值降得更低。这不仅可以加速训练,还有助于防止模型落入损失平面的陡峭区域,使模型更倾向于寻找更平坦部分的极小值,从而缓解过拟合现象。

1cycle 3 步

One-Cycle-Policy 大概有三个步骤:

  1. 我们逐渐将学习率从 lr_max / div_factor 提高到 lr_max,同时我们逐渐减少从 mom_max 到 mom_min 的动量(momentum)。

  2. 反向再做一次:我们逐渐将学习率从 lr_max 降低到 lr_max / div_factor,同时我们逐渐增加从 mom_min 到 mom_max 的动量。

  3. 我们进一步将学习率从 lr_max / div_factor 降低到 lr_max /(div_factor x 100),我们保持动力稳定在 mom_max。

我们来分别简单说明一下:

慢启动的想法并不新鲜:通常使用较低的值来预热训练,这正是 one-cycle 第一步实现的目标。Leslie 不建议直接切换到更高的值,而是线性提高的最大值。

他在实验过程中观察到的是,在 Cycle 中期,高学习率将作为正则化的角色,并使 NN 不会过拟合。它们将阻止模型落在损失函数的陡峭区域,而是找到更平坦的最小值。他在另一篇论文中解释了通过使用这一政策,Hessian 的近似值较低,表明 SGD 正在寻找更宽的平坦区域。

然后训练的最后一部分,学习率下降直到消失,将允许我们得到更平滑的部分内的局部最小值。在高学习率的同时,我们没有看到 loss 或 acc 的显着改善,并且验证集的 loss 有时非常高。但是当我们最终在最后降低学习率时,我们会发现这是很有好处的。

代码实现

class OneCycleScheduler(keras.callbacks.Callback):
    def __init__(self, iterations, max_rate, start_rate=None,
                 last_iterations=None, last_rate=None):
        self.iterations = iterations
        self.max_rate = max_rate
        self.start_rate = start_rate or max_rate / 10
        self.last_iterations = last_iterations or iterations // 10 + 1
        self.half_iteration = (iterations - self.last_iterations) // 2
        self.last_rate = last_rate or self.start_rate / 1000
        self.iteration = 0
    def _interpolate(self, iter1, iter2, rate1, rate2):
        return ((rate2 - rate1) * (self.iteration - iter1)
                / (iter2 - iter1) + rate1)
    def on_batch_begin(self, batch, logs):
        if self.iteration < self.half_iteration:
            rate = self._interpolate(0, self.half_iteration, self.start_rate, self.max_rate)
        elif self.iteration < 2 * self.half_iteration:
            rate = self._interpolate(self.half_iteration, 2 * self.half_iteration,
                                     self.max_rate, self.start_rate)
        else:
            rate = self._interpolate(2 * self.half_iteration, self.iterations,
                                     self.start_rate, self.last_rate)
            rate = max(rate, self.last_rate)
        self.iteration += 1
        K.set_value(self.model.optimizer.lr, rate)

你可能感兴趣的:(人工智能,Tensorflow,深度学习,深度学习,机器学习,人工智能,神经网络)