分享

keras保存模型...

 行走在理想边缘 2022-05-26 发布于四川
83b58c97ed5c720b41dd1a1ec0b0e72a.png

举个例子:先训练出一个模型

import 

接下来第一种方法:只保留模型的参数:这个有2种方法:

  1. model.save_weights("adasd.h5")

  2. model.load_weights("adasd.h5")
  3. model.predict(x_test)
  1. model.save_weights('./checkpoints/mannul_checkpoint')
  2. model.load_weights('./checkpoints/mannul_checkpoint')
  3. model.predict(x_test)

因为这种方法只保留了参数,而并没有保留整个模型,所以说在加载的时候需要使用model.load_weights。这个函数只会保留模型的权重,它不包含模型的结构,所以当我们加载权重文件时候,需要先输入网络结构


再第2种方法:保留h5文件,保留整个模型

这种方法已经保存了模型的结构和权重,以及损失函数和优化器

  1. model.save('keras_model_hdf5_version.h5')

  2. new_model = tf.keras.models.load_model('keras_model_hdf5_version.h5')
  3. new_model.predict(x_test)

注意:这种方法只可以使用在keras的顺序模型和函数式模型中,不能使用在子类模型和自定义模型中,否则会报错。


再第3种方法:保留pb文件,保留整个模型

  1. # Export the model to a SavedModel
  2. model.save('keras_model_tf_version', save_format='tf')

  3. # Recreate the exact same model
  4. new_model = tf.keras.models.load_model('keras_model_tf_version')
  5. new_model.predict(x_test)

这个方法没有保留优化器配置。

保留pb文件还有另一种方法:

tf.saved_model.save(model,'文件夹名') tf.saved_model.load('文件夹名')

注意:这里是文件夹名称!!

当我们使用这个方法后,对应目录下会出现一个文件夹,文件夹下有两个子文件夹和一个子文件:assets、variables、save_model.pb

TensorFlow 为我们提供的SavedModel这一格式可在不同的平台上部署模型文件,当模型导出为 SavedModel 文件时,无需建立。

模型的源代码即可再次运行模型,这使得SavedModel尤其适用于模型的分享和部署

  1. tf.saved_model.save(model,'tf_saved_model_version')
  2. restored_saved_model = tf.saved_model.load('tf_saved_model_version')
  3. 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')])

把动态图变成静态图:

  1. class MyModel(tf.keras.Model):

  2. def __init__(self, num_classes=10):
  3. super(MyModel, self).__init__(name='my_model')
  4. self.num_classes = num_classes
  5. # 定义自己需要的层
  6. self.dense_1 = tf.keras.layers.Dense(32, activation='relu')
  7. self.dense_2 = tf.keras.layers.Dense(num_classes)

  8. @tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])
  9. def call(self, inputs):
  10. #定义前向传播
  11. # 使用在 (in `__init__`)定义的层
  12. x = self.dense_1(inputs)
  13. return self.dense_2(x)
  1. import numpy as np
  2. x_train = np.random.random((1000, 32))
  3. y_train = np.random.random((1000, 10))
  4. x_val = np.random.random((200, 32))
  5. y_val = np.random.random((200, 10))
  6. x_test = np.random.random((200, 32))
  7. y_test = np.random.random((200, 10))




  8. # 优化器
  9. optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
  10. # 损失函数
  11. loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)

  12. # 准备metrics函数
  13. train_acc_metric = tf.keras.metrics.CategoricalAccuracy()
  14. val_acc_metric = tf.keras.metrics.CategoricalAccuracy()

  15. # 准备训练数据集
  16. batch_size = 64
  17. train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
  18. train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)

  19. # 准备测试数据集
  20. val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
  21. val_dataset = val_dataset.batch(64)

  22. model = MyModel(num_classes=10)
  23. epochs = 3
  24. for epoch in range(epochs):
  25. print('Start of epoch %d' % (epoch,))

  26. # 遍历数据集的batch_size
  27. for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
  28. with tf.GradientTape() as tape:
  29. logits = model(x_batch_train)
  30. loss_value = loss_fn(y_batch_train, logits)
  31. grads = tape.gradient(loss_value, model.trainable_weights)
  32. optimizer.apply_gradients(zip(grads, model.trainable_weights))

  33. # 更新训练集的metrics
  34. train_acc_metric(y_batch_train, logits)

  35. # 每200 batches打印一次.
  36. if step % 200 == 0:
  37. print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))
  38. print('Seen so far: %s samples' % ((step + 1) * 64))

  39. # 在每个epoch结束时显示metrics。
  40. train_acc = train_acc_metric.result()
  41. print('Training acc over epoch: %s' % (float(train_acc),))
  42. # 在每个epoch结束时重置训练指标
  43. train_acc_metric.reset_states()

  44. # 在每个epoch结束时运行一个验证集。
  45. for x_batch_val, y_batch_val in val_dataset:
  46. val_logits = model(x_batch_val)
  47. # 更新验证集merics
  48. val_acc_metric(y_batch_val, val_logits)
  49. val_acc = val_acc_metric.result()
  50. val_acc_metric.reset_states()
  51. print('Validation acc: %s' % (float(val_acc),))

模型保存方法一:保存weight:

  1. model.save_weights("adasd.h5")
  2. model.load_weights("adasd.h5")
  3. model.predict(x_test)
  1. model.save_weights('./checkpoints/mannul_checkpoint')
  2. model.load_weights('./checkpoints/mannul_checkpoint')
  3. model.predict(x_test)

模型保存方法二:保留h5,方法失败,因为自定义模型无法保留h5:

#model.save('my_saved_model.h5')

模型保存方法三:pb格式:

  1. model.save('path_to_my_model',save_format='tf')
  2. new_model = tf.keras.models.load_model('path_to_my_model')
  3. new_model.predict(x_test)

输出为:

或者:

  1. tf.saved_model.save(model,'my_saved_model')
  2. restored_saved_model = tf.saved_model.load('my_saved_model')
  3. f = restored_saved_model.signatures["serving_default"]

  4. 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的顺序模型和函数式模型中,不能使用在子类模型和自定义模型中。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多