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官方文档

  • 23
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 学习率衰减是指在训练神经网络时,随着训练的进行,逐渐降低学习率的过程。这样做的目的是为了让模型在训练初期快速收敛,而在训练后期避免过拟合。在TensorFlow 2.0,可以通过使用tf.keras.optimizers的learning_rate_scheduler来实现学习率衰减。常见的学习率衰减方法有Step Decay、Exponential Decay、Cosine Decay等。 ### 回答2: 学习率衰减是指在训练神经网络时,随着训练的进行,逐渐减小学习率的过程。在本文,我们将介绍TensorFlow 2.0学习率衰减的方法和实现。 TensorFlow 2.0学习率衰减有三种实现方式:时间衰减、余弦退火和指数衰减。其,指数衰减是最常用的方法,因为它非常简单且易于调整,同时也有良好的效果。 指数衰减通过指数函数逐渐减小学习率,可以实现快速收敛和防止过拟合。具体实现方式为: ```python initial_learning_rate = 0.1 # 初始化学习率 decay_steps = 10000 # 衰减步数 decay_rate = 0.96 # 衰减率 step = tf.Variable(0, trainable=False) # 定义指数衰减函数 learning_rate = tf.compat.v1.train.exponential_decay(initial_learning_rate, step, decay_steps, decay_rate, staircase=True) # 定义优化器 optimizer = tf.keras.optimizers.SGD(learning_rate) ``` 在上述代码,我们首先定义了初始学习率衰减步数和衰减率,然后通过指数衰减函数逐步减小学习率。最后,我们使用SGD优化器来训练模型。 除了指数衰减,TensorFlow 2.0还支持余弦退火和时间衰减。其,余弦退火在训练初期较快地减小学习率,在接近最优解时较慢地减小学习率,从而有效地避免了局部最优解;时间衰减则类似于指数衰减,只是减小学习率的速度不同。 总之,在训练神经网络时使用学习率衰减可以加速收敛、防止过拟合和提高模型的泛化能力。TensorFlow 2.0提供了三种学习率衰减的实现方式,其指数衰减是最常用的方法,也是最简单易用的方法。 ### 回答3: 学习率衰减是一种优化算法,它可以帮助更好地训练深度神经网络,并且可以提高模型的准确性和泛化能力。Tensorflow2.0提供了许多学习率衰减函数,可以在训练模型时轻松地应用它们。 学习率衰减可以理解为一种策略,它会随着训练的进行,逐渐减小模型参数的更新量。这是因为在初始训练阶段,学习率越大,模型参数更新越大,但随着训练的进行,参数更新越来越小,这样会使模型达到一个比较稳定的状态。如果学习率不改变,则可能会导致模型过拟合,并且训练时间可能会更长。 Tensorflow2.0提供了三种不同的学习率衰减方式:指数衰减、多项式衰减和余弦衰减。其指数衰减方式是最常用的方法,它会通过一个指数函数来不断减小学习率,每次减小的程度也可以进行设置。多项式衰减方式会通过一个多项式函数来不断减小学习率,而余弦衰减则会根据余弦函数不断减小学习率学习率衰减不仅可以提高模型的准确性和泛化能力,还可以在遇到局部极小值时,帮助模型跳出局部极小值,更快地找到全局最优解。在使用学习率衰减时,需要注意一些常见的问题,例如衰减率、衰减周期、起始学习率等等。这些参数需要根据具体情况进行设置,以获得更好的训练效果。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值