举个例子:先训练出一个模型
import
接下来第一种方法:只保留模型的参数:这个有2种方法:
model.save_weights("adasd.h5")model.load_weights("adasd.h5")
model.predict(x_test)
model.save_weights('./checkpoints/mannul_checkpoint')
model.load_weights('./checkpoints/mannul_checkpoint')
model.predict(x_test)
因为这种方法只保留了参数,而并没有保留整个模型,所以说在加载的时候需要使用model.load_weights。这个函数只会保留模型的权重,它不包含模型的结构,所以当我们加载权重文件时候,需要先输入网络结构
再第2种方法:保留h5文件,保留整个模型
这种方法已经保存了模型的结构和权重,以及损失函数和优化器
model.save('keras_model_hdf5_version.h5')new_model = tf.keras.models.load_model('keras_model_hdf5_version.h5')
new_model.predict(x_test)
注意:这种方法只可以使用在keras的顺序模型和函数式模型中,不能使用在子类模型和自定义模型中,否则会报错。
再第3种方法:保留pb文件,保留整个模型
# Export the model to a SavedModel
model.save('keras_model_tf_version', save_format='tf')# Recreate the exact same model
new_model = tf.keras.models.load_model('keras_model_tf_version')
new_model.predict(x_test)
这个方法没有保留优化器配置。
保留pb文件还有另一种方法:
tf.saved_model.save(model,'文件夹名')和 tf.saved_model.load('文件夹名')
注意:这里是文件夹名称!!
当我们使用这个方法后,对应目录下会出现一个文件夹,文件夹下有两个子文件夹和一个子文件:assets、variables、save_model.pb
TensorFlow 为我们提供的SavedModel这一格式可在不同的平台上部署模型文件,当模型导出为 SavedModel 文件时,无需建立。
模型的源代码即可再次运行模型,这使得SavedModel尤其适用于模型的分享和部署。
tf.saved_model.save(model,'tf_saved_model_version')
restored_saved_model = tf.saved_model.load('tf_saved_model_version')
f = restored_saved_model.signatures["serving_default"]
注意这里加载好了以后不能直接用predict进行预测哦。
我们这里看一下保存信息:
!saved_model_cli show --dir tf_saved_model_version --all
使用模型的命令是:
f(digits = tf.constant(x_test.tolist()) )
输出为:
关键是f = restored_saved_model.signatures["serving_default"]。
最后我们看看自定义模型的保存与加载:
注意这里要用以下命令
@tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])
把动态图变成静态图:
class MyModel(tf.keras.Model):def __init__(self, num_classes=10):super(MyModel, self).__init__(name='my_model')self.num_classes = num_classes# 定义自己需要的层self.dense_1 = tf.keras.layers.Dense(32, activation='relu')self.dense_2 = tf.keras.layers.Dense(num_classes)@tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])def call(self, inputs):#定义前向传播# 使用在 (in `__init__`)定义的层x = self.dense_1(inputs)return self.dense_2(x)
import numpy as np
x_train = np.random.random((1000, 32))
y_train = np.random.random((1000, 10))
x_val = np.random.random((200, 32))
y_val = np.random.random((200, 10))
x_test = np.random.random((200, 32))
y_test = np.random.random((200, 10))# 优化器
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
# 损失函数
loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)# 准备metrics函数
train_acc_metric = tf.keras.metrics.CategoricalAccuracy()
val_acc_metric = tf.keras.metrics.CategoricalAccuracy()# 准备训练数据集
batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)# 准备测试数据集
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)model = MyModel(num_classes=10)
epochs = 3
for epoch in range(epochs):print('Start of epoch %d' % (epoch,))# 遍历数据集的batch_sizefor step, (x_batch_train, y_batch_train) in enumerate(train_dataset):with tf.GradientTape() as tape:logits = model(x_batch_train)loss_value = loss_fn(y_batch_train, logits)grads = tape.gradient(loss_value, model.trainable_weights)optimizer.apply_gradients(zip(grads, model.trainable_weights))# 更新训练集的metricstrain_acc_metric(y_batch_train, logits)# 每200 batches打印一次.if step % 200 == 0:print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))print('Seen so far: %s samples' % ((step + 1) * 64))# 在每个epoch结束时显示metrics。train_acc = train_acc_metric.result()print('Training acc over epoch: %s' % (float(train_acc),))# 在每个epoch结束时重置训练指标train_acc_metric.reset_states()# 在每个epoch结束时运行一个验证集。for x_batch_val, y_batch_val in val_dataset:val_logits = model(x_batch_val)# 更新验证集mericsval_acc_metric(y_batch_val, val_logits)val_acc = val_acc_metric.result()val_acc_metric.reset_states()print('Validation acc: %s' % (float(val_acc),))
模型保存方法一:保存weight:
model.save_weights("adasd.h5")
model.load_weights("adasd.h5")
model.predict(x_test)
model.save_weights('./checkpoints/mannul_checkpoint')
model.load_weights('./checkpoints/mannul_checkpoint')
model.predict(x_test)
模型保存方法二:保留h5,方法失败,因为自定义模型无法保留h5:
#model.save('my_saved_model.h5')
模型保存方法三:pb格式:
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)
输出为:
或者:
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()) )
!saved_model_cli show --dir my_saved_model --all
注意前面模型定义时候:
@tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])
这个digits,对应的就是input['digits'],也对应的是f函数中的自变量digits。
总结:
注意第2种方法h5格式只可以使用在keras的顺序模型和函数式模型中,不能使用在子类模型和自定义模型中。