# 保存模型详解
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()))
```