Keras中poly学习策略的实现

前言:

             在各种论文中,我见到过最多的优化器就是SGD,虽然Adam,Nadam很潮,优点很多,但是我也不知道为啥,那些很优秀的论文总是喜欢用SGD,或许是因为SGD的学习率和和decay可‘手动’调节的缘故吧,SGD的学习率衰减策略有很多,接下来就讲解一个各个衰减策略,以及poly衰减策略的实现,另一方面是网上基本上是没有Keras上实现poly的代码,经过我一个下午的摸索,终于实现了。


SGD优化策略:

随机梯度下降法,支持动量参数,支持学习衰减率,支持Nesterov动量。

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)

参数:

  • lr:大于0的浮点数,学习率
  • momentum:大于0的浮点数,动量参数
  • decay:大于0的浮点数,每次更新后的学习率衰减值
  • nesterov:布尔值,确定是否使用Nesterov动量

其中这个decay是很值得玩味的

默认decay设置

Keras 已经内置了一个基于时间的学习速率调整表,并通过上述参数中的 decay 来实现,学习速率的调整公式如下:

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

当我们初始化参数为:

LearningRate = 0.1
decay = 0.001

100 个 iteration后学习速率将变为 0 ,其变化曲线如下: 

上面这个decay是在SGD函数里面的decay参数里直接设置就可以使用的,但是直接设置的只有这一种,如果你想得到其他种类的学习率下降模式,你要自己写 LearningRateScheduler 这个回调函数的接口,具体如下

Drop-Based Learning Rate Schedule

这个学习率下降方式是在训练过程中,以台阶的方式下降的:

通常,通过将学习速率降低每个固定数量的epoch的一半来实现该方法。 例如,我们具有0.1的初始学习率并且每10个epoch将其降低0.5。 前10个训练时期将使用0.1的值,在接下来的10个时期中将使用0.05的学习率,依此类推。

根据这个曲线,学习率函数可以这样定义:

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

 具体函数如下:

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

应用这个学习率函数: 

sgd = SGD(lr=0.0, momentum=0.9, decay=0.0, nesterov=False)
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)

请注意:LearningRateScheduler()这个回调函数接收的是一个以epoch为入口参数,返回的是一个float型的学习率的函数

 Poly Learning Rate Policy

学习率下降公式:

LearningRate = InitialLearningRate*(1 - iter/max_iter) ^ (power) 

曲线如下:

 LearningRateScheduler()回调函数接口:

def poly_decay(epoch):
    # initialize the maximum number of epochs, base learning rate,
    # and power of the polynomial
    maxEpochs = Epochs
    step_each_epoch=400#根据自己的情况设置
    baseLR = 0.01
    power = 0.9
    ite = K.get_value(model.optimizer.iterations)
   
    # compute the new learning rate based on polynomial decay
    alpha = baseLR*((1 - (ite / float(maxEpochs*step_each_epoch)))**power)
    
    # return the new learning rate
    return alpha

应用:

sgd = SGD(lr=0.01, momentum=0.9, decay=0.0, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
# learning schedule callback
lrate = LearningRateScheduler(poly_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)

猜你喜欢

转载自blog.csdn.net/mieleizhi0522/article/details/83113824