0
点赞
收藏
分享

微信扫一扫

【ArcGIS微课1000例】0112:沿线(面)按距离或百分比生成点

君之言之 2024-05-24 阅读 40

5保存和序列化

5.1 全模型的保存和导入

5.1.1 save方法
Model.save(filepath, overwrite=True, **kwargs)

功能描述:
将模型保存为.keras文件。

参数:

  • filepath: 字符串或pathlib.Path对象。保存模型的路径。路径必须以.keras结尾。
  • overwrite: 是否应该覆盖目标位置上的任何现有模型,或者通过交互式提示询问用户。
  • save_format: 在Keras 3中,save_format参数已被弃用。要使用的格式,以字符串形式表示。目前仅支持"keras"格式。

示例翻译:

model = keras.Sequential(
    [
        keras.layers.Dense(5, input_shape=(3,)),
        keras.layers.Softmax(),
    ],
)
model.save("model.keras")
loaded_model = keras.saving.load_model("model.keras")
x = keras.random.uniform((10, 3))
assert np.allclose(model.predict(x), loaded_model.predict(x))

请注意,model.save()keras.saving.save_model() 的别名。

保存的 .keras 文件包含:

  • 模型的配置(架构)
  • 模型的权重
  • 模型的优化器的状态(如果有的话)

因此,模型可以在完全相同的状态下被重新实例化。

简单来说,这意味着当你保存一个模型为一个 .keras 文件时,程序员可以稍后在不同的时间或环境中加载它,并且该模型将具有与之前完全相同的状态,包括它的架构、权重和优化器的状态(例如,如果你在使用梯度下降时中断了训练,那么当你重新加载模型时,你可以从那个中断的点继续训练)。

5.1.2 save_model函数

这个函数通常用于保存深度学习模型的状态,包括模型的架构、权重、优化器状态等,以便后续可以重新加载和继续训练或使用该模型。在 Keras 这样的深度学习库中,save_model 函数(或它的别名 model.save())是非常常用的。

keras.saving.save_model(model, filepath, overwrite=True, **kwargs)

功能描述:
将 Keras 模型保存为 .keras 文件。

参数:

  • model: 要保存的 Keras 模型实例。
  • filepath: 字符串或 pathlib.Path 对象。保存模型的路径。
  • overwrite: 是否应该覆盖目标位置上的任何现有模型,或者通过交互式提示询问用户。

示例:

from keras.models import Sequential
from keras.layers import Dense
import os

# 假设我们有一个简单的序贯模型
model = Sequential()
model.add(Dense(32, input_dim=784))
model.add(Dense(10, activation='softmax'))

# 编译模型
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

# 设置保存路径
filepath = 'my_model.keras'

# 检查文件是否存在,并询问是否覆盖(这里为了简化示例,我们直接设置 overwrite=True)
if os.path.exists(filepath) and not overwrite:
    print(f"The file {filepath} already exists. Overwrite it? (y/n)")
    # 这里可以添加用户交互代码来询问是否覆盖
    # 为了示例,我们直接假设用户输入 'y'
    overwrite_answer = 'y'
else:
    overwrite_answer = 'y'

if overwrite_answer.lower() == 'y':
    # 保存模型
    model.save(filepath)
    print(f"Model saved at {filepath}")
else:
    print("Model not saved.")

请注意,在上面的示例中,我添加了一个简单的检查来模拟用户交互,但在实际应用中,你可能需要使用更复杂的逻辑来与用户进行交互。在这个示例中,我假设用户总是选择覆盖现有文件(overwrite_answer = 'y'),但在实际代码中,你需要根据用户的实际输入来决定是否覆盖文件。

model.save()keras.saving.save_model() 的别名,它用于将 Keras 模型保存为 .keras 文件。保存的 .keras 文件包含了以下信息:

  • 模型的配置(架构):这包括了模型的所有层、层的类型、层的参数(例如,神经元数量、激活函数等)以及它们之间的连接方式。

  • 模型的权重:这是模型在训练过程中学习到的参数值,它们定义了模型的实际行为。

  • 模型的优化器的状态(如果有的话):这包括了优化器在训练过程中维护的任何内部状态,例如动量、学习率等。这些信息对于恢复训练(即从上次保存的点继续训练)非常有用。

由于保存了这些信息,模型可以在以后被重新实例化(或加载)到完全相同的状态,从而可以继续训练、评估或进行预测,而无需从头开始。

5.1.3 load_model函数

load_model 函数是 Keras 提供的一个工具,用于从保存的模型中加载(或重新实例化)模型。这个函数能够从文件中读取模型的配置、权重和优化器状态(如果已保存),并返回一个完全重建的模型实例。

以下是 load_model 函数的基本用法:

from keras.models import load_model

# 假设我们之前保存了一个模型到 'my_model.keras'
model = load_model('my_model.keras')

# 现在,'model' 变量包含了之前保存的模型的完全重建的实例
# 你可以使用它来进行预测、评估或继续训练

在使用 load_model 函数时,需要注意以下几点:

  • 文件路径:确保你提供了正确的文件路径来加载模型。

  • 自定义层和对象:如果你的模型使用了自定义层或自定义对象(如自定义的损失函数、激活函数等),你需要在加载模型之前确保这些自定义类和函数是可用的。这通常意味着你需要在加载模型之前导入或定义这些自定义类和函数。

  • 版本兼容性:由于 Keras 和 TensorFlow 的版本更新,有时在保存模型时使用的 Keras 或 TensorFlow 版本可能与加载模型时的版本不同。这可能会导致兼容性问题。在可能的情况下,最好使用相同的版本来保存和加载模型。

  • 依赖项:如果模型依赖于特定的库或包,请确保这些依赖项在加载模型时是可用的。

  • 优化器状态:如果模型在保存时包含了优化器的状态,那么在加载模型时,这些状态也会被恢复。这意味着你可以从上次保存的点继续训练模型,而无需从头开始。

  • 硬件和配置:虽然加载模型本身通常不需要特殊的硬件或配置,但使用加载的模型进行预测、评估或训练可能需要适当的硬件和配置(如 GPU 支持、足够的内存等)。

load_model 函数用于加载通过 model.save() 方法保存的 Keras 模型。以下是该函数的参数、返回值和示例的详细描述:

参数:

  • filepath: str 或 pathlib.Path 对象,指向已保存模型文件的路径。
  • custom_objects: 可选字典,映射名称(字符串)到自定义类或函数,这些自定义类或函数在反序列化过程中将被考虑。如果模型使用了自定义层、损失函数、优化器等,需要在这里提供。
  • compile: 布尔值,加载模型后是否要编译模型。如果原始模型已经编译,并且设置了 compile=True,则返回的模型也将被编译。否则,模型将保持未编译状态。
  • safe_mode: 布尔值,是否禁止不安全的 lambda 表达式反序列化。当 safe_mode=False 时,加载对象有可能触发任意代码执行。这个参数仅适用于 Keras v3 模型格式。默认为 True。

返回值:

一个 Keras 模型实例。如果原始模型已编译,并且设置了 compile=True,则返回的模型将被编译。否则,模型将保持未编译状态。

示例:

model = keras.Sequential([
    keras.layers.Dense(5, input_shape=(3,)),
    keras.layers.Softmax()])
model.save("model.keras")
loaded_model = keras.saving.load_model("model.keras")
x = np.random.random((10, 3))
assert np.allclose(model.predict(x), loaded_model.predict(x))

5.2 保存和导入权重

在Keras中,保存和加载模型的权重(weights-only)而不保存整个模型结构或优化器状态是常见的需求。这在你想要保存和加载预训练的权重,或者仅关心模型的参数时非常有用。

5.2.1 save_weights方法

save_weights 方法是 Keras 框架中用于保存模型权重到文件的方法。它仅保存模型的权重(即训练得到的参数),而不保存模型的结构或优化器的状态。这对于在多个模型之间共享权重或在不同训练阶段之间保存和加载权重特别有用。

Model.save_weights(filepath, overwrite=True)

函数功能

保存所有层的权重到一个 .weights.h5 文件中。

参数

filepath: 字符串或 pathlib.Path 对象。保存模型的路径。必须以 .weights.h5 结尾。
overwrite: 是否应该覆盖目标位置上的任何现有模型,或者通过交互式提示询问用户。

(注意:在实际的 Keras API 中,save_weights 方法并不强制要求文件扩展名为 .weights.h5,但这是一个推荐的约定。另外,save_weights 方法没有 overwrite 参数,因为它总是覆盖目标文件,不会询问用户。如果需要这个功能,你需要自己实现检查文件是否存在的逻辑,如上面的示例代码所示。)

5.2.2 load_weights 方法

load_weights 方法是 Keras 中用于从文件加载模型权重的方法。这个方法通常用于在训练过程中加载预训练的权重,或者当你想要从一个保存的权重文件中恢复模型的训练状态时。

Model.load_weights(filepath, skip_mismatch=False, **kwargs)

函数功能
load_weights 方法用于从通过 save_weights() 方法保存的文件中加载权重。

权重的加载是基于网络的拓扑结构进行的。这意味着网络的结构(即层的类型和顺序)应该与保存权重时相同。请注意,不包含权重的层在拓扑排序中不会被考虑,因此添加或删除不包含权重的层是可以的。

部分权重加载

如果你修改了模型,例如添加了一个新层(带有权重)或者改变了某层权重的形状,你可以通过设置 skip_mismatch=True 来选择忽略错误并继续加载。在这种情况下,任何权重不匹配的层都将被跳过。对于每个被跳过的层,都会显示一个警告。

参数

  • filepath: 字符串,指向要加载的权重文件的路径。它可以是 .weights.h5 文件或旧的 .h5 权重文件。
  • skip_mismatch: 布尔值,是否跳过加载权重数量不匹配或权重形状不匹配的层。

5.3 模型配置序列化

在TensorFlow和Keras等机器学习框架的上下文中,模型配置序列化是指将模型的配置,包括其架构(层、激活函数等)和训练配置(优化器、损失函数等),转换为一种可以轻松保存、加载和共享的格式的过程。这种序列化的表示形式通常用于模型部署、可重复性和协作。

例如,在Keras中,您可以使用to_json()to_yaml()方法序列化模型的配置。这些方法生成指定格式(JSON或YAML)的模型配置的字符串表示形式。然后,您可以将此字符串保存到文件中或通过网络传输。

要加载序列化的模型配置,您可以使用Keras中的model_from_json()model_from_yaml()函数,传递序列化字符串或包含序列化配置的文件路径。这将创建一个具有与原始模型相同架构的新未训练模型。

但是,仅序列化模型配置并不包括训练后的权重。要同时保存和加载训练后的权重,您可以使用Keras中的save_weights()load_weights()方法。这些方法允许您将训练后的权重保存到单独的文件中(通常以HDF5格式保存,具有.h5扩展名),并将它们加载回具有相同架构的模型中。

总之,模型配置序列化允许您保存和共享模型的架构和训练配置,而单独保存和加载权重则允许您保留模型的训练状态。这些机制共同实现了机器学习模型的可重复性、协作和部署。

5.3.1get_config 方法

get_config 方法在深度学习框架(如 TensorFlow 和 Keras)中通常用于获取模型的配置信息。当您在创建自定义层或模型时,可能需要这个方法来获取或序列化模型的配置,以便之后可以重新创建具有相同架构的模型实例。

具体来说,get_config 方法会返回一个字典,其中包含定义模型架构所需的所有参数和设置。这个字典可以进一步用于:

  • 模型保存:您可以将配置字典与模型的权重一起保存,以便稍后可以重新加载并重新创建模型。
  • 模型复制:通过获取配置字典并使用它创建一个新的模型实例,您可以复制一个模型。
  • 模型检查:您可以通过查看配置字典来检查模型的参数和设置。

对于自定义层或模型,您通常需要覆盖(override)get_config 方法以确保它返回所有必要的配置信息。同样地,为了能够从配置字典重新创建模型或层,您还需要覆盖 from_config 方法。

请注意,get_config 方法本身并不涉及模型权重的加载或保存。要保存和加载模型的权重,您通常会使用 save_weightsload_weights 方法。

Model.get_config()
5.3.2 from_config 方法

在深度学习框架(特别是TensorFlow和Keras)中,from_config方法是一个用于从配置字典中恢复(或“反序列化”)模型或层的方法。这个方法通常与get_config方法一起使用,后者生成一个包含模型或层配置信息的字典。

当您实现自定义的模型或层时,您可能需要覆盖(override)这两个方法以确保可以正确地序列化和反序列化您的模型或层。get_config方法返回一个包含模型或层配置信息的字典,而from_config方法则使用这个字典来创建一个新的模型或层实例。

具体来说,from_config方法接受一个配置字典作为输入,并使用这个字典中的信息来创建一个新的模型或层实例。这个方法应该使用字典中的参数来设置新实例的属性,并确保新实例具有与原始实例相同的结构和功能。

Model.from_config(config, custom_objects=None)

函数功能
from_config 方法用于从配置字典中创建一个层。这个方法是 get_config 方法的逆操作,能够从配置字典中实例化出与原层具有相同配置的层。然而,这个方法并不处理层的连接(这由 Network 类处理)或权重(这通过 set_weights 方法处理)。

参数

  • config: 一个Python字典,通常是 get_config 方法的输出。

返回值

  • 一个层实例。

当您定义自定义层时,通常需要覆盖 get_configfrom_config 方法。get_config 方法应返回一个包含定义该层所需的所有参数的字典。然后,from_config 方法应使用这些参数来创建一个新的层实例。

下面是一个自定义层及其 get_configfrom_config 方法的示例:

from tensorflow.keras.layers import Layer

class MyCustomLayer(Layer):
    def __init__(self, num_units, **kwargs):
        super(MyCustomLayer, self).__init__(**kwargs)
        self.num_units = num_units

    def build(self, input_shape):
        # 假设我们要创建一个权重矩阵
        self.kernel = self.add_weight(name='kernel', 
                                      shape=(input_shape[1], self.num_units),
                                      initializer='uniform',
                                      trainable=True)
        super(MyCustomLayer, self).build(input_shape)  # 确保构建方法被正确调用

    def call(self, inputs):
        # 这里是层的实际计算
        return tf.matmul(inputs, self.kernel)

    def get_config(self):
        # 返回包含层的配置信息的字典
        config = super(MyCustomLayer, self).get_config()
        config.update({'num_units': self.num_units})
        return config

    @classmethod
    def from_config(cls, config):
        # 使用配置字典来创建层的新实例
        return cls(**config)

# 使用示例
layer_config = MyCustomLayer(num_units=64).get_config()
new_layer = MyCustomLayer.from_config(layer_config)

在上面的示例中,我们定义了一个简单的自定义层 MyCustomLayer,它有一个权重矩阵和一个可配置的 num_units 参数。get_config 方法返回包含 num_units 的字典,而 from_config 方法则使用这个字典来创建新的层实例。请注意,在 from_config 方法中,我们使用 @classmethod 装饰器,以便我们可以直接通过类名调用它,而无需先创建类的实例。

5.3.3 clone_model 函数

在Keras框架中,clone_model函数用于复制(克隆)一个已存在的模型(Model)实例,但不复制模型的状态(如训练权重或优化器状态)。这意味着克隆后的模型将具有与原模型相同的架构,但没有任何训练过的权重,且不会保持原模型的训练状态。

clone_model函数通常用于以下情况:

  • 模型复用:当你想要在新的数据集上从头开始训练一个与原模型具有相同架构的模型时。
  • 模型扩展:在保持原模型结构的基础上,对模型进行扩展或修改,如添加额外的层或改变某些层的配置。

下面是clone_model函数的基本用法示例:

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam

# 假设我们有一个已存在的模型
original_model = Model()  # 这里应该是你定义好的模型,为了示例简单,这里省略了模型定义
original_model.add(Dense(32, input_dim=784, activation='relu'))
original_model.add(Dense(10, activation='softmax'))

# 编译模型(这一步在实际应用中通常是需要的)
original_model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])

# 使用clone_model函数克隆模型
cloned_model = tf.keras.models.clone_model(original_model)

# 注意:cloned_model现在与原模型具有相同的架构,但没有权重或训练状态

# 如果需要,可以为克隆后的模型设置新的权重或编译设置
# cloned_model.set_weights(some_new_weights)  # 设置新权重(如果需要的话)
# cloned_model.compile(optimizer='sgd', loss='mse')  # 编译模型(如果需要不同的编译设置)

需要注意的是,clone_model只复制模型的架构(即层的类型和连接),而不复制模型的权重、训练配置(如优化器、损失函数)或模型的状态(如学习率、动量等)。如果你想要在新数据集上从头开始训练一个与原模型结构相同的模型,你可以使用clone_model来快速获取相同的架构,然后再进行编译和训练。

参数

以下是clone_model函数的参数和它们的作用:

  • model: 一个Model实例(可以是功能性模型或顺序模型)。
  • input_tensors: 可选的输入张量或InputLayer对象列表,用于基于这些输入构建模型。如果没有提供,则会创建新的Input对象。
  • clone_function: 一个可调用的函数,其签名是fn(layer),用于克隆目标模型中的每个层(除了Input实例)。它接受要克隆的层实例作为参数,并返回要在模型副本中使用的相应层实例。如果没有指定,这个可调用的函数默认为序列化/反序列化函数:lambda layer: layer.__class__.from_config(layer.get_config())。通过传递一个自定义的可调用函数,您可以自定义模型的副本,例如,通过包装某些感兴趣的层(您可能想要将所有LSTM实例替换为等效的Bidirectional(LSTM(...))实例)。默认为None
    call_function:一个可调用的对象,其签名为 fn(layer, *args, **kwargs),用于调用每个克隆的层以及一组输入。它接收层实例、调用参数和关键字参数,并返回调用输出。如果不指定,这个可调用的对象将默认为层的常规 __call__() 方法:def fn(layer, *args, **kwargs): return layer(*args, **kwargs)。通过传递一个自定义的可调用对象,你可以在给定层之前或之后插入新的层。注意:这个参数只能用于函数式模型(Functional models)。

recursive:布尔值。是否递归地克隆在原始顺序模型(Sequential)或函数式模型(Functional)中遇到的任何顺序模型或函数式模型。如果为 False,则内部模型通过调用 clone_function() 进行克隆。如果为 True,则内部模型通过调用 clone_model() 进行克隆,并使用相同的 clone_functioncall_functionrecursive 参数。请注意,在这种情况下,call_function 不会传播到任何顺序模型(因为顺序模型不适用)。

返回值

一个模型实例,它在新的输入张量上复现原始模型的行为,并使用新实例化的权重。如果通过自定义的 clone_functioncall_function 修改了层或层调用,则克隆的模型可能与原始模型的行为不同。

# Create a test Sequential model.
model = keras.Sequential([
    keras.layers.Input(shape=(728,)),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(1, activation='sigmoid'),
])
# Create a copy of the test model (with freshly initialized weights).
new_model = clone_model(model)
def clone_function(layer):
    config = layer.get_config()
    if "seed" in config:
        config["seed"] = 1337
    return layer.__class__.from_config(config)

new_model = clone_model(model)
def call_function(layer, *args, **kwargs):
    out = layer(*args, **kwargs)
    if isinstance(layer, keras.layers.Dense):
        out = keras.layers.Dropout(0.5)(out)
    return out

new_model = clone_model(
    model,
    clone_function=lambda x: x,  # Reuse the same layers.
    call_function=call_function,
)

注意,由于子类化模型(Subclassed models)的内部层结构是未知的,因此默认情况下无法克隆它们。为了在子类化模型的情况下实现与 clone_model 类似的功能,请确保模型类实现了 get_config() 方法(以及可选的 from_config() 方法),并调用。

5.4 模型导出以进行推理

5.4.1 export方法
Model.export(filepath, format="tf_saved_model")

函数功能
创建一个TensorFlow SavedModel工件用于推理。

注意:这目前只能与TensorFlow或JAX后端一起使用。

此方法允许您将模型导出为轻量级的SavedModel工件,该工件仅包含模型的前向传递(其call()方法),并且可以通过例如TF-Serving进行服务。前向传递在名称为serve()下注册(见下面的示例)。

重新加载工件不再需要原始模型代码(包括您可能使用的任何自定义层)——它是完全独立的。

参数

filepath: str或pathlib.Path对象。保存工件的路径。

示例

# Create the artifact
model.export("path/to/location")

# Later, in a different process / environment...
reloaded_artifact = tf.saved_model.load("path/to/location")
predictions = reloaded_artifact.serve(input_data)

如果你想自定义你的服务端点(serving endpoints),你可以使用更低级别的 keras.export.ExportArchive 类。export() 方法在内部依赖于 ExportArchive 类。

keras.export.ExportArchive 类提供了更多的灵活性和控制,允许你更细致地定制模型导出时的各个方面。通过直接操作 ExportArchive,你可以决定如何组织导出的文件、添加额外的元数据、自定义模型签名(signature)等。

然而,需要注意的是,直接使用 keras.export.ExportArchive 类的操作通常比直接使用模型的 save() 方法或 tf.keras.models.save_model() 函数更加复杂。这要求你对 TensorFlow 和 Keras 的底层实现有一定的了解。

5.4.2 ExportArchive类
keras.export.ExportArchive()

ExportArchive 用于编写 SavedModel 制品(例如用于推理)。

如果你有一个 Keras 模型或层,你想将其导出为 SavedModel 以进行服务(例如,通过 TensorFlow Serving),你可以使用 ExportArchive 来配置你需要提供的不同服务端点以及它们的签名。只需实例化一个 ExportArchive,使用 track() 来注册要使用的层或模型,然后使用 add_endpoint() 方法来注册一个新的服务端点。完成后,使用 write_out() 方法来保存制品。

生成的制品是一个 SavedModel,可以通过 tf.saved_model.load 来重新加载。

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(
    name="serve",
    fn=model.call,
    input_signature=[tf.TensorSpec(shape=(None, 3), dtype=tf.float32)],
)
export_archive.write_out("path/to/location")

# Elsewhere, we can reload the artifact and serve it.
# The endpoint we added is available as a method:
serving_model = tf.saved_model.load("path/to/location")
outputs = serving_model.serve(inputs)

以下是如何导出一个模型,使其具有一个用于推理的端点和一个用于训练模式前向传递(例如,带有dropout)的端点:

  • 首先,你需要有一个Keras模型。

  • 定义一个用于推理的tf.function,它关闭了dropout。

  • 定义一个用于训练模式前向传递的tf.function,它开启了dropout。

  • 使用tf.keras.models.save_model保存模型,并为每个签名指定一个端点。

现在,你已经有了一个包含两个端点的SavedModel:一个用于推理,另一个用于训练模式前向传递(例如,带有dropout)。你可以使用tf.saved_model.load加载这个模型,并根据需要调用相应的签名。

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(
    name="call_inference",
    fn=lambda x: model.call(x, training=False),
    input_signature=[tf.TensorSpec(shape=(None, 3), dtype=tf.float32)],
)
export_archive.add_endpoint(
    name="call_training",
    fn=lambda x: model.call(x, training=True),
    input_signature=[tf.TensorSpec(shape=(None, 3), dtype=tf.float32)],
)
export_archive.write_out("path/to/location")

关于资源追踪的说明

ExportArchive 能够自动追踪其端点所使用的所有 tf.Variables,因此大多数情况下,调用 .track(model) 不是严格必需的。但是,如果你的模型使用了诸如 IntegerLookup、StringLookup 或 TextVectorization 等查找层,那么就需要通过 .track(model) 明确地进行追踪。

如果你需要在恢复后的存档中访问属性变量(如 variables、trainable_variables 或 non_trainable_variables),也需要进行明确的追踪。

5.4.3 add_endpoint 方法
ExportArchive.add_endpoint(name, fn, input_signature=None, jax2tf_kwargs=None)

函数功能
注册一个新的服务端点。

参数

name:字符串,端点的名称。
fn:一个函数。它应该只利用由 ExportArchive 追踪的模型/层所提供的资源(例如 tf.Variable 对象或 tf.lookup.StaticHashTable 对象)。你可以通过调用 .track(model) 来追踪一个新的模型。该函数的输入的形状和类型必须是已知的。为此,你可以:1) 确保 fn 是一个已经被调用过至少一次的 tf.function;或者 2) 提供一个 input_signature 参数来指定输入的形状和类型(见下文)。

注意:如果你选择提供 input_signature 参数,它应该是一个包含 tf.TensorSpec 对象的列表或元组,每个 tf.TensorSpec 对象描述了函数 fn 的一个输入的形状和类型。这允许 TensorFlow 在函数被实际调用之前对其进行图形分析,并确定输入的形状和类型。这在某些情况下是必要的,特别是当函数的输入在图形构建阶段不可用时。

input_signature:用于指定函数 fn 的输入的形状和类型。它是一个 tf.TensorSpec 对象的列表(每个列表项对应于 fn 的一个位置输入参数)。允许嵌套参数(下面将给出一个带有两个输入参数的 Functional 模型示例)。

jax2tf_kwargs:可选。一个字典,用于将参数传递给 jax2tf。仅在后端为 JAX 时支持。参见 jax2tf.convert 的文档。如果没有提供 native_serializationpolymorphic_shapes 的值,它们将被自动计算。

返回值

添加到存档中的 tf.function 封装后的 fn 函数。

示例
当模型具有单个输入参数时,使用 input_signature 参数添加端点:

(注:以下是上面描述的翻译,并稍作调整以更清晰地解释)

当模型只接受一个输入参数时,你可以使用 input_signature 参数来指定该输入的形状和类型,并添加一个新的服务端点。input_signature 应该是一个 tf.TensorSpec 对象,该对象描述了输入的形状、数据类型和其他属性。

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(
    name="serve",
    fn=model.call,
    input_signature=[tf.TensorSpec(shape=(None, 3), dtype=tf.float32)],
)

当模型具有两个位置输入参数时,使用 input_signature 参数添加端点:

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(
    name="serve",
    fn=model.call,
    input_signature=[
        tf.TensorSpec(shape=(None, 3), dtype=tf.float32),
        tf.TensorSpec(shape=(None, 4), dtype=tf.float32),
    ],
)

当模型有一个输入参数,该参数是2个张量的列表时(例如,一个具有2个输入的Functional模型),使用input_signature参数添加端点:

model = keras.Model(inputs=[x1, x2], outputs=outputs)

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(
    name="serve",
    fn=model.call,
    input_signature=[
        [
            tf.TensorSpec(shape=(None, 3), dtype=tf.float32),
            tf.TensorSpec(shape=(None, 4), dtype=tf.float32),
        ],
    ],
)

这也适用于字典输入

model = keras.Model(inputs={"x1": x1, "x2": x2}, outputs=outputs)

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(
    name="serve",
    fn=model.call,
    input_signature=[
        {
            "x1": tf.TensorSpec(shape=(None, 3), dtype=tf.float32),
            "x2": tf.TensorSpec(shape=(None, 4), dtype=tf.float32),
        },
    ],
)

添加一个作为 tf.function 的端点:

@tf.function()
def serving_fn(x):
    return model(x)

# The function must be traced, i.e. it must be called at least once.
serving_fn(tf.random.normal(shape=(2, 3)))

export_archive = ExportArchive()
export_archive.track(model)
export_archive.add_endpoint(name="serve", fn=serving_fn)
5.4.4 add_variable_collection方法
ExportArchive.add_variable_collection(name, variables)

函数功能
注册一组变量以便在重新加载后检索。

参数

name: 集合的字符串名称。
variables: 包含 tf.Variable 实例的元组/列表/集合。

export_archive = ExportArchive()
export_archive.track(model)
# Register an endpoint
export_archive.add_endpoint(
    name="serve",
    fn=model.call,
    input_signature=[tf.TensorSpec(shape=(None, 3), dtype=tf.float32)],
)
# Save a variable collection
export_archive.add_variable_collection(
    name="optimizer_variables", variables=model.optimizer.variables)
export_archive.write_out("path/to/location")

# Reload the object
revived_object = tf.saved_model.load("path/to/location")
# Retrieve the variables
optimizer_variables = revived_object.optimizer_variables
5.4.5 track方法
ExportArchive.track(resource)

函数功能
跟踪层或模型的变量(和其他资源)。

默认情况下,当你调用 add_endpoint() 时,端点函数所使用的所有变量都会自动被跟踪。然而,非变量资源(如查找表)需要手动跟踪。请注意,内置 Keras 层(如 TextVectorization、IntegerLookup、StringLookup)所使用的查找表在 add_endpoint() 中会被自动跟踪。

参数

resource: 一个可追踪的 TensorFlow 资源。

5.4.6 write_out方法
ExportArchive.write_out(filepath, options=None)

函数功能
将相应的 SavedModel 写入磁盘。

参数

filepath: str 或 pathlib.Path 对象。指定要保存该工件(artifact)的路径。
options: tf.saved_model.SaveOptions 对象,指定 SavedModel 保存选项。

关于 TF-Serving 的说明:所有通过 add_endpoint() 注册的端点都在 SavedModel 工件中对 TF-Serving 可见。此外,第一个注册的端点将在别名 “serving_default” 下可见(除非已经手动注册了一个名为 “serving_default” 的端点),因为 TF-Serving 要求设置这个端点。

举报

相关推荐

0 条评论