由于数据集很大,我在循环中迭代使用Keras模型拟合。我的目标是将数据集分成100个部分,每次读取一个部分并应用fit()方法。
我的问题:在每次迭代中,fit()方法是从我设置的初始学习率(lr=0.1)开始的,还是它会记住最后更新的学习率并直接应用到新的fit()方法调用中?
我的代码样例如下:
# 定义模型my_model()# 设置优化器sgd = SGD(lr=0.1, decay=1e-08, momentum=0.9, nesterov=False)# 编译模型model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])# 拟合模型并训练for j in range(100): print('从大矩阵中提取数据 ...') X_train = HDF5Matrix(path_train, 'X', start=st, end=ed) Y_train = HDF5Matrix(path_train, 'y', start=st, end=ed) print('拟合模型 ...') model.fit(X_train, Y_train, batch_size=100, shuffle='batch', nb_epoch=1, validation_data=(X_test, Y_test))
回答:
更新后的学习率被保存在优化器对象model.optimizer
中,在你的例子中就是sgd
变量。
在像LearningRateScheduler
这样的回调函数中,学习率变量model.optimizer.lr
会被更新(为了清晰起见,移除了一些行)。
def on_epoch_begin(self, epoch, logs=None): lr = self.schedule(epoch) K.set_value(self.model.optimizer.lr, lr)
然而,当使用decay
(如你的例子中)时,学习率变量不会被直接更新,而是model.optimizer.iterations
变量会被更新。这个变量记录了模型拟合中使用过的批次数量,带衰减的学习率在SGD.get_updates()
中通过以下方式计算:
lr = self.lrif self.initial_decay > 0: lr *= (1. / (1. + self.decay * K.cast(self.iterations, K.dtype(self.decay))))
所以在任何情况下,只要模型没有重新编译,它会在新的fit()
调用中使用更新后的学习率。