Keras中如何利用回调函数Callback设置训练前先验证一遍验证集数据

【时间】2019.12.06

【题目】Keras中如何利用回调函数Callback设置训练前先验证一遍验证集数据

背景:

Keras中能够利用keras.callbacks.ModelCheckpoint()回调函数设置保存最佳权重的点,如:

  checkpoint = ModelCheckpoint(filepath=best_filepath,monitor="val_acc", verbose=1,
                              save_best_only=True,mode="max",save_weights_only=True) 

但是在第一个epoch时,监视指标为-np.inf (以val_acc为例),这样如果你加载已有weights后进行训练的第一个epoch一定会保存,这不符合初衷。一个解决办法是:训练前先验证一遍验证集数据。但是查看了keras,好像没有实现这个功能的函数。

最后查看keras.callbacks.ModelCheckpoint()的源代码,发现是通过监控checkpoint.best来决定是否保存,这样就可以这样实现:

1、使用Callback的自定义函数在第训练之前先对验证集验证一遍,获得监控指标,如val_acc

2、将监控指标赋值给checkpoint.best。

一、实现方法

使用Callback的自定义回调函数在第训练之前先对验证集验证一遍,获得监控指标,并赋值给checkpoint.best

自定义回调函数代码:

##EvaluateBeforeTrain
class EvaluateBeforeTrain(keras.callbacks.Callback):
    def __init__(self,checkpoint):
      super(Callback,self).__init__()
      self.checkpoint=checkpoint

    def on_epoch_begin(self,epoch,logs={}):
      #evaluate validation data
      if epoch==0:
        X=self.validation_data[0]
        Y=self.validation_data[1]
        result=self.model.evaluate(X,Y)
        loss=result[0]
        acc=result[1]
        self.checkpoint.best=acc
        print('first_val_acc is:',acc)

分析:

1.在自定义Callback回调函数时,使用self.validation_data可获得模型在fit()中传入的validation_data,使用self.model能够获得对应模型实例。

2、定义on_epoch_begin()函数可以让函数在每个epoch之前执行

PS:不使用on_train_begin()函数的原因是此函数获取不了self.validation_data。(不知原因)

3、传入的参数self.checkpoint=checkpoint是ModelCheckPoint的实例,目的是为了给checkpoint.best赋值

二、测试代码

from sklearn.preprocessing import LabelBinarizer
from keras.optimizers import  SGD
from keras.datasets import cifar10
from keras.layers import Dense
from keras.models import Sequential
from keras.callbacks import ModelCheckpoint,Callback

best_filepath=''
((trainX, trainY), (testX, testY)) = cifar10.load_data()
trainX = trainX.astype("float") / 255.0
testX = testX.astype("float") / 255.0
trainX = trainX.reshape((trainX.shape[0], 3072))
testX = testX.reshape((testX.shape[0], 3072))

# convert the labels from integers to vectors
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.fit_transform(testY)
##DNN
model = Sequential()
model.add(Dense(1024, input_shape=(3072,), activation="relu"))
model.add(Dense(512, activation="relu"))
model.add(Dense(10, activation="softmax"))

if os.path.exists(best_filepath):
    model.load_weights(best_filepath)
    print("have load weight")

checkpoint = ModelCheckpoint(filepath=best_filepath,monitor="val_acc", verbose=1,
                              save_best_only=True,mode="max",save_weights_only=True) 
evaluateBeforeTrain=EvaluateBeforeTrain(checkpoint)
callbacks_list = [checkpoint,evaluateBeforeTrain]
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
  H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=100, batch_size=64,callbacks=callbacks_list,verbose=1)#callbacks=callbacks_list,
  model.save_weights(final_save_path)

运行结果:

你可能感兴趣的:(Keras入门笔记,keras,callback,训练前验证)