利用学习率衰减找到最优结果

2019-11-11 23:41:03 浏览数 (2)

学习一时爽,一直学习一直爽

Hello,大家好,我是 もうり,一个从无到有的技术 语言小白。

学习率是深度学习中的一个重要的超参,如何调整学习率是训练出好模型的关键要素之一。

关于学习率的大小

在训练过程中,一般根据训练轮数设置动态变化的学习率。

  • 刚开始训练时:学习率以 0.01 ~ 0.001 为宜。
  • 一定轮数过后:逐渐减缓。
  • 接近训练结束:学习速率的衰减应该在 100 倍以上。
  • 两种学习率衰减模式,一种为线性衰减,一种为指数衰减。 如果学习率过小,梯度下降很慢,如果学习率过大,如 Andrew Ng 的 Stanford 公开课程所说梯度下降的步子过大可能会跨过最优值。不同的学习率对 loss 的影响如下图所示:

常见学习率衰减方式

https://www.jianshu.com/p/125fe2ab085b

线性衰减

momentum 动量法

网络权值时,存在一些不确定因素,并不能保证每一次初始化操作都能使得网络的初始权值处在一个合适的状态。不恰当的初始权值可能使得网络的损失函数在训练过程中陷入局部最小值,达不到全局最优的状态。

momentum 动量能够在一定程度上解决这个问题。momentum 动量是依据物理学的势能与动能之间能量转换原理提出来的。

当 momentum 动量越大时,其转换为势能的能量也就越大,就越有可能摆脱局部凹域的束缚,进入全局凹域。momentum 动量主要用在权重更新的时候。

一般,神经网络在更新权值时,采用如下公式:

w = w - learning_rate * dw

引入 momentum 后,采用如下公式:

v = mu * v - learning_rate * dw

w = w v

其中,v 初始化为 0,mu 是设定的一个超变量,最常见的设定值是 0.9。

先看源码,其实主要改几个参数就可以

基于 Iris 数据集

代码语言:javascript复制
'''@authot: 毛利'''from sklearn import datasetsimport numpy as npfrom keras.models import Sequentialfrom keras.layers import Densefrom keras.optimizers import SGDfrom keras.wrappers.scikit_learn import KerasClassifierdataset = datasets.load_iris()x = dataset.dataY = dataset.targetseed = 4np.random.seed(seed)def create_model():    model = Sequential()    model.add(Dense(units=4, activation='relu', input_dim=4))    model.add(Dense(units=6, activation='relu'))    model.add(Dense(units=3, activation='softmax' ))    # 定义优化器    learningRate = 0.1    momentum = 0.9      # 动量参数    decay_rate = 0.005  # 学习率衰减    sgd = SGD(lr=learningRate, momentum=momentum, decay=decay_rate, nesterov=False)    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])    return modelmodel = KerasClassifier(build_fn=create_model, epochs=200, batch_size=5, verbose=1)model.fit(x,Y)

线性衰减的最终的结果为:loss: 0.4630 - acc: 0.6467

因此指数衰减相对于线性衰减效果会更好

通过固定的 epoch 周期将学习速率降低 50% 来实现的。例如,初始学习率设定为 0.1,每 10 个 epochs 降低 50%。前 10 个 epochs 使用 0.1 的学习率,接下来的 10 个 epochs 使用 0.05 的学习率,学习率以指数级进行衰减。

代码语言:javascript复制
lrate = init_lrate * pow(drop, floor(1   epoch) / epochs_drop)

需要导入 from keras.callbacks import LearningRateScheduler用于动态设置学习率

代码语言:javascript复制
'''@author:毛利'''from sklearn import datasetsimport numpy as npfrom keras.models import Sequentialfrom keras.layers import Densefrom keras.optimizers import SGDfrom keras.wrappers.scikit_learn import KerasClassifierfrom keras.callbacks import LearningRateSchedulerfrom math import pow, floordataset = datasets.load_iris()x = dataset.dataY = dataset.targetseed = 4np.random.seed(seed)# 计算学习率def step_decay(epoch):    init_lrate = 0.01    drop = 0.05    epochs_drop = 10    lrate = init_lrate * pow(drop, floor(1 epoch) / epochs_drop)    return lratedef create_model(init='glorot_uniform'):    model = Sequential()    model.add(Dense(units=4, activation='relu', input_dim=4, kernel_initializer=init))    model.add(Dense(units=6, activation='relu', kernel_initializer=init))    model.add(Dense(units=3, activation='softmax', kernel_initializer=init))    # 定义优化器    learningRate = 0.01    momentum = 0.9      # 动量参数    decay_rate = 0.0    # 学习率衰减    sgd = SGD(lr=learningRate, momentum=momentum, decay=decay_rate, nesterov=False)    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])    return model"""keras.callbacks.LearningRateScheduler(schedule) 该回调函数是用于动态设置学习率 参数: ● schedule:函数,该函数以epoch号为参数(从0算起的整数),返回一个新学习率(浮点数)"""lrate = LearningRateScheduler(step_decay)model = KerasClassifier(build_fn=create_model, epochs=200, batch_size=5, verbose=1, callbacks=[lrate])model.fit(x, Y)

指数衰减的最终结果为 loss: 0.3393 - acc: 0.9000

0 人点赞