〔TensorFlow〕保存与恢复模型
前面章节中我们使用《初学者的 TensorFlow 2.0 教程》已经训练了一个图像分类模型,但并没有保存模型。
这篇教程我会保持持续更新,随着学习的深入,将模型保存和恢复相关功能都整理出来。
说明
模型信息包括:
- 结构
- 权重
- 配置
- 优化器状态
保存模型的结构
使用 model.to_json()搭配 tf.keras.models.model_from_json()对模型的结构进行保存与恢复
- 保存
import json
# 生成json文件
model_json = model.to_json()
# 写入json文件
with open(r'model_json.json', 'w') as f:
json.dump(model_json, f)
print('模型的结构json文件保存完成!')
结果
{
"module": "keras",
"class_name": "Sequential",
"config": {
"name": "sequential",
"trainable": true,
"dtype": "float32",
"layers": [
{
"module": "keras.layers",
"class_name": "InputLayer",
"config": { "batch_shape": [null, 28, 28], "dtype": "float32", "sparse": false, "name": "input_layer" },
"registered_name": null
},
{
"module": "keras.layers",
"class_name": "Flatten",
"config": { "name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last" },
"registered_name": null,
"build_config": { "input_shape": [null, 28, 28] }
},
{
"module": "keras.layers",
"class_name": "Dense",
"config": {
"name": "dense",
"trainable": true,
"dtype": "float32",
"units": 128,
"activation": "relu",
"use_bias": true,
"kernel_initializer": {
"module": "keras.initializers",
"class_name": "GlorotUniform",
"config": { "seed": null },
"registered_name": null
},
"bias_initializer": { "module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null },
"kernel_regularizer": null,
"bias_regularizer": null,
"kernel_constraint": null,
"bias_constraint": null
},
"registered_name": null,
"build_config": { "input_shape": [null, 784] }
},
{
"module": "keras.layers",
"class_name": "Dropout",
"config": { "name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "seed": null, "noise_shape": null },
"registered_name": null
},
{
"module": "keras.layers",
"class_name": "Dense",
"config": {
"name": "dense_1",
"trainable": true,
"dtype": "float32",
"units": 10,
"activation": "linear",
"use_bias": true,
"kernel_initializer": {
"module": "keras.initializers",
"class_name": "GlorotUniform",
"config": { "seed": null },
"registered_name": null
},
"bias_initializer": { "module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null },
"kernel_regularizer": null,
"bias_regularizer": null,
"kernel_constraint": null,
"bias_constraint": null
},
"registered_name": null,
"build_config": { "input_shape": [null, 128] }
}
],
"build_input_shape": [null, 28, 28]
},
"registered_name": null,
"build_config": { "input_shape": [null, 28, 28] },
"compile_config": {
"optimizer": "adam",
"loss": {
"module": "keras.losses",
"class_name": "SparseCategoricalCrossentropy",
"config": { "name": "sparse_categorical_crossentropy", "reduction": "sum_over_batch_size", "from_logits": true, "ignore_class": null },
"registered_name": null
},
"loss_weights": null,
"metrics": ["accuracy"],
"weighted_metrics": null,
"run_eagerly": false,
"steps_per_execution": 1,
"jit_compile": false
}
}
- 恢复
# 从磁盘读取json文件
with open('model_json.json') as json_file:
json_config = json_file.read()
new_model = keras.models.model_from_json(json_config)
保存模型的权重
#将权重写入磁盘,文件后缀要求是.weights.h5
model.save_weights('model_weights.weights.h5')
#从磁盘读取权重文件
model.load_weights('model_weights.weights.h5')
保存模型
保存网络结构、权重、配置、优化器状态。
# 保存模型,可以是.h5或.keras格式
model.save('model.h5')
# 加载模型,同时加载了模型的结构、权重等信息
new_model = keras.models.load_model('model.h5')
checkpoints 模式
提示
在网络上搜索 checkpoints 模式会发现多个不同的代码实现,可能是不同版本的 TensorFlow 接口不同。这里我使用的是的 keras 版本 3.1.1。
checkpoint 模式是最常见的一种保存方式,尽可能多地保存模型能帮助我们不错过效果最好的模型,但是实际操作也要考虑内存大小和运行效率。工程师的通用做法是每训练多少步后就在验证集上计算一次准确率,如果本次结果比上次好则保存新的模型。最常见的做法是直接每训练多少步就直接保存一次模型,实际上 TensorFlow 的 API 也提供了在模型文件名提供添加训练 step 后缀的方式。
保存模型
from keras.callbacks import ModelCheckpoint
#在开始训练之前,使用 Keras Model.compile 配置和编译模型。将 optimizer 类设置为 adam,将 loss 设置为您之前定义的 loss_fn 函数,并通过将 metrics 参数设置为 accuracy 来指定要为模型评估的指标。
model.compile(optimizer='adam',
loss=loss_fn,
metrics=['accuracy'])
#checkpoints检查点
filepath = "checkpoint_{epoch:02d}.keras"
#monitor='val_accuracy'与model.compile方法中的metrics相关联
checkpoint = ModelCheckpoint(filepath, monitor='val_accuracy', verbose=0)
#训练并评估模型
#使用 Model.fit 方法调整您的模型参数并最小化损失:
model.fit(x_train, y_train, epochs=10, callbacks=[checkpoint])
在上面的代码中,重点是 ModelCheckpoint 类,“回调以保存某个频率下的 Keras 模型或模型权重。”
。ModelCheckpoint
中 callback 与使用model.fit()
的训练结合使用,以在某个时间间隔保存模型或权重(在检查点文件中),因此可以稍后加载模型或权重,以从保存的状态继续训练。简单点理解就是在训练模型的过程中保存检查点位置的模型信息。
ModelCheckpoint 类构造方法如下:
#你需要比对一下跟你的keras版本中代码是否相同
def __init__(
self,
filepath,
monitor="val_loss",
verbose=0,
save_best_only=False,
save_weights_only=False,
mode="auto",
save_freq="epoch",
initial_value_threshold=None,
)
- filepath
字符串或格式类字符串,保存模型文件的路径,filepath
可以包含命名格式选项,这些选项将填充epoch
的值和logs中的键
(传入on_ech_end
)。当save_weights_only=True
时,filepath
名称需要以“.weights.h5”
结尾,或者当检查点保存整个模型时,应以“.keras”
结尾(默认值)。例如:如果filepath
是“{epoch:02d}-{val_loss:.2f}.keras”
,则模型检查点将与 epoch 编号和验证丢失一起保存在文件名中。文件路径的目录不应被任何其他回调重用,以避免冲突。
- monitor
要监视的度量值名称。通常,度量是通过“Model.compile”方法设置的。例如上面代码中 val_accuracy。
- verbose
详细模式,0 或 1。模式 0 是静默的,模式 1 在回调执行操作时显示消息。
- save_best_only
如果“save_best_only=True”,则仅当模型被视为“最佳”时进行保存,并且根据监测的数量,最新的最佳模型不会被覆盖。如果“filepath”不包含像“{epoch}”这样的格式化选项,那么“文件路径”将被每个新的更好的模型覆盖。
- save_weights_only
如果为“True”,则只保存模型的权重(model.save_weights(filepath)
),否则保存整个模型(model.seave(filepath)
)。
- mode
{auto
、min
、max
}之一。如果“save_best_only=True”,则覆盖当前保存文件的决定是基于监控数量的最大化或最小化。对于val_acc
,它应该是max
,对于val_loss
,它应是min
等。在auto
模式中,如果监测的量是acc
或以fmeasure
开始,则模式设置为max
,其余量设置为min
。
- save_freq
epoch
或整数。当使用“epoch”时,回调会在每个 epoch 之后保存模型。当使用 integer 时,回调会在这么多批处理结束时保存模型。如果“模型”是用“steps_per_execution=N”编译的,则每 N 批都会检查保存条件。请注意,如果保存与历元不一致,则监控的度量可能不太可靠(它可能只反映一个批次,因为每个历元都会重置度量)。默认为“epoch”。
- initial_value_threshold
要监视的度量的浮点初始“最佳”值。仅当“save_best_value=True”时适用。仅当当前模型的性能优于此值时,才会覆盖已保存的模型权重。
加载模型
未完待续