举个例子:先训练出一个模型
接下来第一种方法:只保留模型的参数:这个有2种方法:
model.save_weights("adasd.h5")
model.load_weights("adasd.h5")
model.save_weights('./checkpoints/mannul_checkpoint') model.load_weights('./checkpoints/mannul_checkpoint')
因为这种方法只保留了参数,而并没有保留整个模型,所以说在加载的时候需要使用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')]) # 使用在 (in `__init__`)定义的层
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)
train_acc_metric = tf.keras.metrics.CategoricalAccuracy() val_acc_metric = tf.keras.metrics.CategoricalAccuracy()
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) for epoch in range(epochs): print('Start of epoch %d' % (epoch,))
for 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))
train_acc_metric(y_batch_train, logits)
print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value))) print('Seen so far: %s samples' % ((step + 1) * 64))
train_acc = train_acc_metric.result() print('Training acc over epoch: %s' % (float(train_acc),)) train_acc_metric.reset_states()
for x_batch_val, y_batch_val in val_dataset: val_logits = model(x_batch_val) val_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.save_weights('./checkpoints/mannul_checkpoint') model.load_weights('./checkpoints/mannul_checkpoint')
模型保存方法二:保留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的顺序模型和函数式模型中,不能使用在子类模型和自定义模型中。
|