# 保存模型详解 Tensorflow2.x三种模型保存文件分别为Checkpoint、HDF5、SavedModel。 ## Checkpoint ```bash checkpoint ├── checkpoint ├── ckpt.data-00000-of-00001 ├── ckpt.index └── ckpt.meta ``` checkpoint文件:记录最新的检查点路径映射,用以其他函数 ckpt.data文件:保存模型所有变量值、超参数值和权重值 ckpt.index文件:保存模型所有变量名、超参数名和权重索引 ckpt.meta文件:保存模型计算图 ```python # tf.__version__ = 1.x saver = tf.train.Saver(max_to_keep) saver.saver(sess, './checkpoint', global_step=epoch) saver_reload = tf.train.import_meta_graph('./checkpoint/ckpt.meta') saver_reload.restore(sess, tf.train.latest_checkpoint('./checkpoint')) # tf.__version__ = 2.x tf.keras.callbacks.ModelCheckpoint( filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', save_freq='epoch', options=None ) model = tf.keras.Model(...) ckpt = tf.train.Checkpoint(model) ckpt.save('./checkpoint') ckpt = tf.train.Checkpoint() ckpt.restore('./checkpoint').assert_consumed() ``` ## HDF5 HDF5 格式的文件,可以将保存的模型视为单个二进制 blob,里面同时保存了模型权重、模型结构和优化器配置。 ```python model = tf.keras.Sequential() # 保存完整模型 model.save('model.h5') # 仅保存模型权重 model.save_weights('model_weights.h5') # 重载完整模型 model = tf.keras.models.load_model('model.h5') # 重载模型权重 model = tf.keras.Sequential() model.load_weights('model_weights.h5') ``` ## SavedModel ```bash saved_model ├── assets ├── saved_model.pb └── variables ├── variables.data-00000-of-00001 └── variables.index ``` saved_model.pb文件:计算图 variables目录:ckpt文件集合 variables.data文件:保存模型所有变量值、超参数值和权重值 variables.index文件:保存模型所有变量名、超参数名和权重索引 ```python # tf.__version__ = 1.x builder = tf.saved_model.builder.SavedModelBuilder(path) builder.add_meta_graph_and_variables(sess, ['cpu_server_1']) with tf.Session(graph=tf.Graph()) as sess:   tf.saved_model.loader.load(sess, ['cpu_server_1'], './saved_model/saved_model.pb') # tf.__version__ = 2.x tf.keras.models.save_model(model, './saved_model') loaded_model = tf.keras.models.load_model('./saved_model') ``` # 模型保存和重载 方法一:只保存模型权重(model.save_weights)。 方法二:保存HDF5文件(model.save)。 方法三:保存pb文件(tf.saved_model)。 注意:saved_model格式的模型可以直接用来预测,但是saved_model没有保存优化器配置。 ## 使用tf.keras.Sequencial构建的模型 **只保留模型的参数:这个有2种方法** ```python # 保存 model.save_weights("model_name.h5") # 重载 model.load_weights("model_name.h5") ``` ```python # 保存 model.save_weights("./checkpoints/") # 重载 model.load_weights("./checkpoints/") ``` 注意:这种方法只保留了参数,而并没有保留整个模型,所以说在加载的时候需要使用model.load_weights。这个函数只会保留模型的权重,它不包含模型的结构,所以当我们加载权重文件时候,需要先输入网络结构。 **保存为HDF5文件,保存整个模型。** 这种方法已经保存了模型的结构和权重,以及损失函数和优化器。 ```python # 保存 model.save("hdf5_model.h5") # 重载 new_model = tf.keras.model.load_model("hdf5_model.h5") ``` 注意:这种方法只可以使用在keras的顺序模型和函数式模型中,不能使用在子类模型和自定义模型中,否则会报错。 **保存为pb文件,保存整个模型。**(方法一) ```python # 保存 model.save("saved_model", save_format="tf") # 重载 new_model = tf.keras.models.load_model("saved_model") ``` 注意:这个方法没有保留优化器配置。 **保存为pb文件,保存整个模型。**(方法二) ```python # 保存 tf.saved_model.save(model, "saved_model") # 重载 tf.saved_model.load("saved_model") ``` 当我们使用这个方法后,对应目录下会出现一个**文件夹**,文件夹下有**两个子文件夹和一个子文件:assets、variables、save_model.pb**。TensorFlow 为我们提供的SavedModel这一格式可在不同的平台上部署模型文件,当模型导出为 SavedModel 文件时,无需建立。模型的源代码即可再次运行模型,这使得SavedModel尤其适用于**模型的分享和部署**。 ```bash # 查看保存信息 saved_model_cli show --dir saved_model --all ``` ## 自定义模型的保存和重载 注意这里要用以下命令 ```python @tf.function(input_signature=[tf.TensorSpec([None,xxx], tf.float32, name='digits')]) ``` 把动态图变成静态图。 **模型保存方法一:保存weight:** ```text model.save_weights("adasd.h5") model.load_weights("adasd.h5") model.predict(x_test) ``` ```text model.save_weights('./checkpoints/mannul_checkpoint') model.load_weights('./checkpoints/mannul_checkpoint') model.predict(x_test) ``` **模型保存方法二:保留h5,方法失败,因为自定义模型无法保留h5** ```python #model.save('my_saved_model.h5') 自定义模型不能这么写!!!!!!! ``` **模型保存方法三:pb格式:** ```python model.save('path_to_my_model',save_format='tf') new_model = tf.keras.models.load_model('path_to_my_model') new_model.predict(x_test) ``` 或者 ```python tf.saved_model.save(model,'my_saved_model') restored_saved_model = tf.saved_model.load('my_saved_model') f = restored_saved_model.signatures["serving_default"] f(digits = tf.constant(x_test.tolist())) ```