我在Keras中(使用Tensorflow后端)初始化了一个Adadelta优化器,并将其分配给一个模型:
my_adadelta = keras.optimizers.Adadelta(learning_rate=0.01, rho=0.95)my_model.compile(optimizer=my_adadelta, loss="binary_crossentropy")
在训练过程中,我使用回调函数在每个epoch后打印学习率:
class LRPrintCallback(Callback): def on_epoch_end(self, epoch, logs=None): lr = self.model.optimizer.lr print(K.eval(lr))
然而,这在每个epoch后打印的都是相同的(初始)学习率。如果我像这样初始化优化器,情况也是如此:
my_adadelta = keras.optimizers.Adadelta(learning_rate=0.01, decay=0.95)
我在初始化时做错了什么吗?学习率可能在变化,但我在打印错误的东西吗?
回答:
如相关Github讨论中所述,衰减不影响lr
变量本身,该变量仅用于存储学习率的初始值。为了打印衰减后的值,您需要自己显式计算并将其存储在一个单独的变量lr_with_decay
中;您可以使用以下回调函数来实现:
class MyCallback(Callback): def on_epoch_end(self, epoch, logs=None): lr = self.model.optimizer.lr decay = self.model.optimizer.decay iterations = self.model.optimizer.iterations lr_with_decay = lr / (1. + decay * K.cast(iterations, K.dtype(decay))) print(K.eval(lr_with_decay))
lr = self.lrif self.initial_decay > 0: lr *= (1. / (1. + self.decay * K.cast(self.iterations, K.dtype(self.decay))))
直接来自Keras的Adadelta源代码。
从所链接的源代码的检查中可以清楚地看出,这里用于衰减学习率的关键参数是decay
,而不是rho
;尽管在文档中也使用术语“decay”来描述rho
,但它是一种不同的衰减,与学习率无关:
rho:浮点数 >= 0。Adadelta衰减因子,对应于每个时间步保留的梯度比例。