保存和序列化模型
本教程是R翻译的这个页面可以在官方的TensorFlow文档中找到。
本指南的第一部分涵盖了顺序模型和使用Functional API构建的模型的保存和序列化。对于这两种模型,保存和序列化api是完全相同的。
保存模型的自定义子类在“保存子类模型”一节中介绍。这种情况下的api与顺序模型或函数模型略有不同。
概述
对于顺序模型和使用Functional API构建的模型:
save_model_hdf5 ()
/load_model_hdf5 ()
将整个模型保存到磁盘,包括优化器
状态。您还可以使用save_model_tf
/load_model_tf
以将整个模型保存为SavedModel格式。get_config ()
/from_config ()
只将模型架构加载到R对象中。model_to_json ()
/model_from_json ()
只将模型的体系结构保存到单个字符串中—用于将体系结构保存到磁盘。您还可以使用model_to_yaml ()
/model_from_yaml ()
为了保存架构。save_model_weights_hdf5 ()
/load_model_weights_hdf5 ()
如果您只想将模型权重保存到磁盘中hdf5
格式。您还可以使用save_model_weights_tf ()
/load_model_weights_tf ()
以SavedModel格式保存权重。
请注意你可以结合使用model_to_json ()
而且save_model_weights_hdf5 ()
既节省了结构又节省了重量。在这种情况下,优化器状态不会被保存。
对于自定义模型使用:
save_model_weights_tf ()
或save_model_weights_hdf5 ()
保存模型权重。通常对于定制模型,必须使用代码重新创建体系结构。
设置
图书馆(keras)
保存顺序模型或功能模型
输入< -layer_input(形状=784,name =“数字”)输出< -输入% > %layer_dense(单位=64,激活=“relu”,name =“dense_1”)% > %layer_dense(单位=64,激活=“relu”,name =“dense_2”)% > %layer_dense(单位=10,激活=“softmax”,name =“预测”)模型< -keras_model(输入、输出)总结(模型)
可选地,让我们训练这个模型,这样它就有权重值要保存,以及优化器状态。当然,您也可以保存您从未训练过的模型,但显然这没有那么有趣。
c(c(x_train y_train),c(x_test y_test))% < - %dataset_mnist()x_train < -x_train% > %array_reshape(昏暗的=c(60000,784))/255x_test < -x_test% > %array_reshape(昏暗的=c(10000,784))/255模型% > %编译(损失=“sparse_categorical_crossentropy”,优化器=optimizer_rmsprop())< -历史模型% > %适合(y_train x_trainbatch_size =64,时代=1)
#保存预测以备将来检查预测< -预测(x_test模型)
完整的模型保存
您可以将使用Functional API构建的模型保存到单个文件中。您可以稍后从这个文件中重新创建相同的模型,即使您不再能够访问创建模型的代码。
这个文件包括:
- 模型的体系结构
- 模型的权值(训练中学习到的)
- 模型的训练配置(传递给编译的内容),如果有的话
- 优化器及其状态(如果有的话)(这使您能够在停止的地方重新启动训练)
保存模型save_model_hdf5(模型中,“model.h5”)从文件中重新创建完全相同的模型new_model < -load_model_hdf5(“model.h5”)
注意,优化器的状态也被保留了下来,因此您可以在停止的地方继续训练。
出口到SavedModel
你也可以将整个模型导出为TensorFlow SavedModel格式。SavedModel是Tensorflow对象的独立序列化格式,被Tensorflow服务以及Python以外的Tensorflow实现所支持。卡塔尔世界杯欧洲预选赛赛程表请注意,save_model_tf
仅适用于大于1.14的TensorFlow版本。
#导出模型到SavedModelsave_model_tf(模型中,“模型/”)#重建完全相同的模型new_model < -load_model_tf(“模型/”)#检查状态是否保留new_predictions < -预测(new_model x_test)all.equal(new_predictions预测)
注意,优化器的状态也被保留了下来,因此您可以在停止的地方继续训练。
的SavedModel
创建的文件包含:
- 包含模型权重的TensorFlow检查点。
- 一个SavedModel原型,包含底层的Tensorflow图。保存单独的图用于预测(服务)、训练和评估。如果之前没有编译模型,那么只导出推断图。
- 模型的架构配置(如果可用的话)。
你也可以使用export_savedmodel
函数导出模型,但这些模型不能再次加载为Keras模型。模型导出的使用exported_savedmodels
可以用于预测。
export_savedmodel(模型中,“savedmodel /”)new_predictions < -tfdeploy::predict_savedmodel(x_test“savedmodel /”)
请注意出口与export_savedmodel
将学习阶段设置为0,因此您需要重新启动R并在进行额外训练之前重新构建模型。
建筑只保存
有时,您只对模型的体系结构感兴趣,而不需要保存权值或优化器。在这种情况下,您可以通过get_config()方法检索模型的“配置”。该配置是一个命名列表,使您能够重新创建相同的模型—从头开始初始化,而不需要以前在培训期间学到的任何信息。
配置< -get_config(模型)reinitialized_model < -from_config(配置)
您可以选择使用model_to_json ()
而且model_from_json ()
,它使用JSON字符串来存储配置,而不是命名列表。这对于将配置保存到磁盘非常有用。
json_config < -model_to_json(模型)reinitialized_model < -model_from_json(json_config)
Weights-only储蓄
有时,您只对模型的状态(它的权值)感兴趣,而对体系结构不感兴趣。在这种情况下,可以通过作为数组列表检索权重值get_weights ()
,并设置模型的状态set_weights
:
重量< -get_weights(模型)set_weights(reinitialized_model权重)new_predictions < -预测(reinitialized_model x_test)all.equal(new_predictions预测)
您可以组合get_config ()
/from_config ()
而且get_weights ()
/set_weights ()
在相同的状态下重新创建模型。但是,与save_model_hdf5
,这将不包括培训配置和优化器。你得打电话编译()
在使用模型进行训练之前。
配置< -get_config(模型)重量< -get_weights(模型)new_model < -from_config(配置)set_weights(new_model权重)#检查状态是否保留new_predictions < -预测(new_model x_test)all.equal(new_predictions预测)
注意,优化器没有被保留,所以模型应该在训练之前重新编译(优化器将从空白状态开始)。
的保存到磁盘的替代方案get_weights ()
而且set_weights(权重)
是save_weights (fpath)
而且load_weights (fpath)
.
#保存JSON配置到磁盘json_config < -model_to_json(模型)writeline(json_config“model_config.json”)#保存权重到磁盘save_model_weights_hdf5(模型中,“model_weights.h5”)从我们保存的2个文件中重新加载模型json_config < -readline(“model_config.json”)new_model < -model_from_json(json_config)load_model_weights_hdf5(new_model“model_weights.h5”)#检查状态是否保留new_predictions < -预测(new_model x_test)all.equal(new_predictions预测)
注意,优化器没有被保留。但请记住,最简单、推荐的方法是:
save_model_hdf5(模型中,“model.h5”)new_model < -load_model_hdf5(“model.h5”)
仅以SavedModel格式保存权重
注意save_weights可以创建Keras HDF5格式的文件,或TensorFlow SavedModel格式的文件。
save_model_weights_tf(模型中,“model_weights”)
储蓄细分类模型
顺序模型和功能模型是表示层的DAG的数据结构。因此,可以安全地对它们进行序列化和反序列化。
子类模型的不同之处在于它不是一个数据结构,而是一段代码。模型的体系结构是通过调用方法的主体定义的。这意味着模型的体系结构不能被安全地序列化。要加载一个模型,您需要访问创建它的代码(模型子类的代码)。或者,你也可以将此代码序列化为字节码(例如通过pickle),但这是不安全的,通常不可移植。
有关这些差异的更多信息,请参阅本文“TensorFlow 2.0中的符号和命令式api是什么?”.
让我们考虑下面的子类模型,它的结构与第一节的模型相同:
keras_model_simple_mlp < -函数(num_classesuse_bn =假,use_dp =假,name =零){#定义并返回一个定制模型keras_model_custom(name =的名字,函数(自我){#创建调用所需的图层(代码执行一次)自我$dense1 < -layer_dense(单位=32,激活=“relu”)自我$dense2 < -layer_dense(单位=num_classes,激活=“softmax”)如果(use_dp)自我$dp < -layer_dropout(率=0.5)如果(use_bn)自我$bn < -layer_batch_normalization(轴=-1)#执行调用(此代码在训练和推断期间执行)函数(输入,掩码=零){x < -自我$dense1(输入)如果(use_dp)x < -自我$dp(x)如果(use_bn)x < -自我$bn(x)自我$dense2(x)}})}模型< -keras_model_simple_mlp(num_classes =10)
首先,从未使用过的子类模型无法保存。
这是因为子类模型需要调用一些数据来创建它的权重。
在模型被调用之前,它不知道形状
而且dtype
它应该期望的输入数据,因此不能创建它的权重变量。你们可能还记得,在第一部分的函数模型中形状
而且dtype
其中的输入是预先指定的(通过layer_input
) -这就是为什么函数模型一实例化就有一个状态。
让我们训练模型,给它一个状态:
模型% > %编译(损失=“sparse_categorical_crossentropy”,优化器=optimizer_rmsprop())< -历史模型% > %适合(y_train x_trainbatch_size =64,时代=1)
保存子类模型的推荐方法是使用save_model_weights_tf
创建一个TensorFlow SavedModel检查点,它将包含与模型相关的所有变量的值:-层的权重-优化器的状态-任何与有状态模型指标相关的变量(如果有)。
save_model_weights_tf(模型中,“my_weights”)
#保存预测以备将来检查预测< -预测(x_test模型)#也保存第一批的损失#之后断言优化器状态被保留first_batch_loss < -train_on_batch(模型、x_train [1:64y_train], [1:64])
要恢复模型,您需要访问创建模型对象的代码。
注意,为了恢复优化器状态和任何有状态度量的状态,你应该编译模型(与之前完全相同的参数),并在调用load_weights之前对一些数据调用它:
new_model < -keras_model_simple_mlp(num_classes =10)new_model% > %编译(损失=“sparse_categorical_crossentropy”,优化器=optimizer_rmsprop())#初始化优化器使用的变量,#以及任何有状态度量变量train_on_batch(new_model x_train [1:5y_train], [1:5])加载旧模型的状态load_model_weights_tf(new_model“my_weights”)#检查模型状态是否被保留new_predictions < -预测(new_model x_test)all.equal(new_predictions预测)#优化器状态也被保留,#这样你就可以重新开始训练了new_first_batch_loss < -train_on_batch(new_model x_train [1:64y_train], [1:64])first_batch_loss= =new_first_batch_loss
这篇指南已经讲完了!这涵盖了在TensorFlow 2.0中使用Keras保存和序列化模型所需知道的一切。