保存和序列化模型

    本教程是R翻译的这个页面可以在官方的TensorFlow文档中找到。

    本指南的第一部分涵盖了顺序模型和使用Functional API构建的模型的保存和序列化。对于这两种模型,保存和序列化api是完全相同的。

    保存模型的自定义子类在“保存子类模型”一节中介绍。这种情况下的api与顺序模型或函数模型略有不同。

    概述

    对于顺序模型和使用Functional API构建的模型:

    请注意你可以结合使用model_to_json ()而且save_model_weights_hdf5 ()既节省了结构又节省了重量。在这种情况下,优化器状态不会被保存。

    对于自定义模型使用:

    设置

    图书馆(keras)

    保存顺序模型或功能模型

    输入< -layer_input形状=784name =“数字”输出< -输入% > %layer_dense单位=64激活=“relu”name =“dense_1”% > %layer_dense单位=64激活=“relu”name =“dense_2”% > %layer_dense单位=10激活=“softmax”name =“预测”模型< -keras_model(输入、输出)总结(模型)

    可选地,让我们训练这个模型,这样它就有权重值要保存,以及优化器状态。当然,您也可以保存您从未训练过的模型,但显然这没有那么有趣。

    cc(x_train y_train),c(x_test y_test))% < - %dataset_mnist()x_train < -x_train% > %array_reshape昏暗的=c60000784))/255x_test < -x_test% > %array_reshape昏暗的=c10000784))/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”
    #检查状态是否保留new_predictions < -预测(new_model x_test)all.equal(new_predictions预测)

    注意,优化器的状态也被保留了下来,因此您可以在停止的地方继续训练。

    出口到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(配置)
    #注意模型状态是不保留的!我们只保存了建筑。new_predictions < -预测(reinitialized_model x_test)all.equal(new_predictions预测)

    您可以选择使用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_customname =的名字,函数(自我){#创建调用所需的图层(代码执行一次)自我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_mlpnum_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 [164y_train], [164])

    要恢复模型,您需要访问创建模型对象的代码。

    注意,为了恢复优化器状态和任何有状态度量的状态,你应该编译模型(与之前完全相同的参数),并在调用load_weights之前对一些数据调用它:

    new_model < -keras_model_simple_mlpnum_classes =10new_model% > %编译损失=“sparse_categorical_crossentropy”优化器=optimizer_rmsprop())#初始化优化器使用的变量,#以及任何有状态度量变量train_on_batch(new_model x_train [15y_train], [15])加载旧模型的状态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 [164y_train], [164])first_batch_loss= =new_first_batch_loss

    这篇指南已经讲完了!这涵盖了在TensorFlow 2.0中使用Keras保存和序列化模型所需知道的一切。