Keras深度学习:入门、实战与进阶
上QQ阅读APP看书,第一时间看更新

3.3.2 使用回调函数寻找最优模型

应用回调函数时,应在每次训练中查看改进时输出模型的权重。可以将callback_model_checkpoint()函数设置成当验证数据集的分类精度提高时保存网络权重(monitor="val_acc"和mode="max"),并将权重保存在一个包含评价的文件中(“weights.{epoch:02d}-val_loss-{val_loss:.2f}-val_acc-{val_accuracy:.2f}.hdf5)。下面的示例创建了一个小型神经网络,以解决Pima印第安人发生糖尿病的二元分类问题。

> library(keras)
> # 导入数据集
> dataset <- read.csv('../data/pima-indians-diabetes.csv',skip = 9,header = F)
> X = as.matrix(dataset[,1:8])
> y = dataset[,9]
> # 创建回调函数
> checkpoint_dir <- "checkpoints"
> dir.create(checkpoint_dir, showWarnings = FALSE)
> filepath <- file.path(checkpoint_dir,
+            "weights.{epoch:02d}-val_loss-{val_loss:.2f}-val_acc-{val_accuracy:.2f}.hdf5")
> cp_callback <- callback_model_checkpoint(
+   filepath = filepath,
+   save_weights_only = TRUE,
+   monitor = 'val_acc',
+   mode = 'max',
+   verbose = 1
+ )
> # 定义及编译模型
> model <- keras_model_sequential()
>
> model %>%
+   layer_dense(units = 12,input_shape = c(8),kernel_initializer = 'uniform', activation = 'relu') %>%
+   layer_dense(units = 8,kernel_initializer = 'uniform',activation = 'relu') %>%
+   layer_dense(units = 1,kernel_initializer = 'uniform',activation = 'sigmoid') %>%
+   compile(loss='binary_crossentropy',optimizer = 'adam',metrics = c('accuracy'))
> # 训练模型
> model %>% fit(
+   X, y,
+   batch_size = 10,
+   epochs = 10,
+   verbose = 1,
+   callbacks = list(cp_callback),
+   validation_split = 0.33
+ )

我们将在checkpoints目录中看到包含10个HDF5格式的网络权重文件。

> # 查看网络权重文件
> list.files('checkpoints')
 [1] "weights.01-val_loss-0.66-val_acc-0.67.hdf5"
 [2] "weights.02-val_loss-0.65-val_acc-0.67.hdf5"
 [3] "weights.03-val_loss-0.65-val_acc-0.68.hdf5"
 [4] "weights.04-val_loss-0.64-val_acc-0.68.hdf5"
 [5] "weights.05-val_loss-0.64-val_acc-0.70.hdf5"
 [6] "weights.06-val_loss-0.63-val_acc-0.65.hdf5"
 [7] "weights.07-val_loss-0.62-val_acc-0.67.hdf5"
 [8] "weights.08-val_loss-0.62-val_acc-0.68.hdf5"
 [9] "weights.09-val_loss-0.61-val_acc-0.69.hdf5"
[10] "weights.10-val_loss-0.60-val_acc-0.68.hdf5"

这是一个非常简单的checkpoint策略。如果验证精度在训练周期上下波动,则可能会创建大量不必要的checkpoint文件。一个更简单的checkpoint策略是当验证精度提高后才将模型权重保存到相同的文件中,此时只需将callback_model_checkpoint()函数中的参数save_best_only设置为TRUE,则当验证数据集上模型的分类精度提高到目前为止最好的时候,才会将模型权重写入文件。下面的代码结合了callback_early_stopping()函数,若经过3个训练周期后训练集的准确率没有提升,则终止训练,并将最优的模型保存到checkpoints目录中。

> #仅保存最优模型
> checkpoint_list =list(callback_model_checkpoint('checkpoints/model.best.hdf5',
+                      monitor='val_loss',
+                      save_best_only = TRUE),
+                 callback_early_stopping(monitor = 'accuracy',patience = 3))
> model %>% fit(
+   X,y,batch_size = 10,epochs = 200,
+   verbose = 0,validation_split = 0.33,
+   callbacks = checkpoint_list)

在checkpoints目录中找到最优的模型文件:

> list.files('checkpoints',pattern = "best")
[1] "model.best.hdf5"

这是一个在训练中需要经常用到且方便的checkpoint策略。它将确保你的最佳模型被保存,同时避免输入代码来手动跟踪,并在训练时序列化最佳模型。

最后,将保存的模型文件导入R中,并评价模型性能。

> # 将模型文件导入R中
> new_model <- load_model_hdf5('checkpoints/model.best.hdf5')
> # 对导入模型进行性能评估
> new_model %>% evaluate(X,y,verbose = 0)
$loss
[1] 0.5979516

$accuracy
[1] 0.6510417