在训练期间更改keras中的优化器

时间:2017-12-04 03:53:12

标签: keras

我正在使用nadam优化器开发模型。我想知道如果在两个时期内验证损失没有减少,是否有办法在培训期间切换到sgd

3 个答案:

答案 0 :(得分:9)

这样的事情会起作用吗?

model.compile( optimizer='Adam', ...) 
model.fit( X, y, epochs=100, callback=[EarlyStoppingCallback] ) 
# now switch to SGD and finish training
model.compile( optimizer='SGD', ...) 
model.fit( X, y, epochs=10 ) 

或者第二次调用编译覆盖所有变量(即执行类似tf.initialize_all_variables()

的操作

(它实际上是一个后续问题 - 但我写这个作为答案 - 因为stackoverflow不允许在评论中使用代码)

答案 1 :(得分:7)

您可以创建一个停止训练的EarlyStopping回调,在此回调中,您可以创建一个更改优化器并再次适合的函数。

以下回调将监控验证丢失(val_loss)并在两个时期(patience)之后停止训练,但改进不超过min_delta

min_delta = 0.000000000001

stopper = EarlyStopping(monitor='val_loss',min_delta=min_delta,patience=2) 

但是为了在培训结束后添加额外的操作,我们可以扩展此回调并更改on_train_end方法:

class OptimizerChanger(EarlyStopping):

    def __init__(self, on_train_end, **kwargs):

        self.do_on_train_end = on_train_end
        super(OptimizerChanger,self).__init__(**kwargs)

    def on_train_end(self, logs=None):
        super(OptimizerChanger,self).on_train_end(self,logs)
        self.do_on_train_end()

对于模型结束训练时要调用的自定义函数:

def do_after_training():

    #warining, this creates a new optimizer and,
    #at the beginning, it might give you a worse training performance than before
    model.compile(optimizer = 'SGD', loss=...., metrics = ...)
    model.fit(.....)

现在让我们使用回调:

changer = OptimizerChanger(on_train_end= do_after_training, 
                           monitor='val_loss',
                           min_delta=min_delta,
                           patience=2)

model.fit(..., ..., callbacks = [changer])

答案 2 :(得分:1)

我做到了,而且奏效了

class myCallback(tf.keras.callbacks.Callback):

    def on_epoch_end(self, epoch, logs):
    
        self.model.optimizer = new_model_optimizer
        self.model.loss = new_model_loss