Keras的回调函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Einstellung/article/details/83010342

训练模型时,很多事情一开始无法预测。尤其是你不知道需要多少轮次才能得到最佳验证损失。通常简单的办法是:训练足够多的轮次,这时模型已经开始过拟合了,根据第一次运行来确定训练所需要的正确轮次,然后使用这个最佳轮数从头开始启动一个新的训练。当然,这种方法很浪费。更好的办法是使用回调函数

ModelCheckpoing和EarlyStopping回调函数

如果监控的目标在设定轮数内不再改善,可以用EarlyStopping回调函数来中断训练。这个回调函数通常与ModelCheckpoint结合使用,后者可以在训练过程中持续的不断保存模型(你也可以选择只保存目前的最佳模型,即一轮结束后具有最佳性能的模型)

import keras 


# 通过fit的callbacks参数将回调函数传入模型中,这个参数接收一个回调函数列表,你可以传入任意个回调函数
callback_lists = [
    keras.callbacks.EarlyStopping(monitor = 'acc',  # 监控模型的验证精度
                                  patience = 1,),   # 如果精度在多于一轮的时间(即两轮)内不再改善,就中断训练
    
    # ModelCheckpoint用于在每轮过后保存当前权重
    keras.callbacks.ModelCheckpoint(filepath = 'my_model.h5', # 目标文件的保存路径
                                    
                                    # 这两个参数的意思是,如果val_loss没有改善,那么不需要覆盖模型文件,
                                    # 这就可以始终保存在训练过程中见到的最佳模型
                                    monitor = 'val_loss', save_best_only = True,)    
                 ]

model.compile(optimizer = 'rmsprop', loss = 'binary_crossentropy', metrics = ['acc'])


# 由于回调函数要监控验证损失和验证精度,所以在调用fit时需要传入validation_data(验证数据)
model.fit(x, y, epochs = 10,
         batch_size = 32,
         callbacks = callbacks_list,
         validation_data = (x_val, y_val))

ReduceLROnPlateau回调函数

如果验证损失不再改善,你可以使用这个回调函数来降低学习率。在训练过程中如果出现了损失平台(loss plateau),那么增大或减小学习率都是跳出局部最小值的有效策略。这里可以用到ReduceLROnPlateau回调函数。

callback_list = [
    keras.callbacks.ReduceLROnPlateau(monitor = 'val_loss',  # 监控模型的验证损失
                                      factor = 0.1,  # 触发时将学习率除以10
                                      patience = 10) # 如果验证损失在10轮内都没有改善,那么就触发这个回调函数
]

# 由于回调函数要监控验证损失和验证精度,所以在调用fit时需要传入validation_data(验证数据)
model.fit(x, y, epochs = 10,
         batch_size = 32,
         callbacks = callbacks_list,
         validation_data = (x_val, y_val))

编写自己的回调函数

如果你需要在训练过程中采取特定行动,而这项行动又没有包含在内置的回调函数中,那么可以编写自己的回调函数。这种回调函数的实现形式是创建keras.callbacks.Callback类的子类。然后你可以实现下面这些方法,它们分别在训练过程中的不同时间被调用。

on_epoch_begin  # 在每轮开始时被调用
on_epoch_end    # 在每轮结束时被调用

on_batch_begin  # 在处理每个批量之前被调用
on_batch_end    # 在处理每个批量之后被调用

on_train_begin  # 在训练开始时被调用
on_train_end    # 在训练结束时被调用

这些方法被调用时都有一个logs参数,这个参数是一个字典,里面包好前一个批量、前一个轮次或前一次训练的信息(训练的指标和验证指标等)。此外,回调函数还可以访问下列属性:

  • self.model:调用回调函数的模型实例
  • self.validation_data:传入fit作为验证数据的值

下面是一个回调函数的简单示例,它可以在每轮结束后将模型每层激活保存到硬盘(格式为Numpy数组),这个激活是对验证集的第一个样本计算得到的。

import keras
import numpy as np

class ActivationLogger(keras.callbacks.Callback):
    def set_model(self, model):
        self.model = model  # 在训练之前由父模型调用,告诉回调函数是哪个模型在调用它
        layer_outputs = [layer.output for layer in model.layers]
        self.activations_model = keras.models.Model(model.input,
                                                  layer_outputs) # 模型实例,返回每层的激活
        
    def on_epoch_end(self, epoch, logs = None):
        if self.validation_data is None:
            raise RuntimeError('Requires validation_data')
        validation_sample = self.validation_data[0][0:1]  # 获取验证数据的第一个输入样本
        activation = self.activations_model.predict(validation_sample)
        f = open('activation_at_epoch_' + str(epoch) + '.npz', 'w')  # 将数据保存到硬盘
        np.savez(f, activations)
        f.close()

猜你喜欢

转载自blog.csdn.net/Einstellung/article/details/83010342