TensorFlow Lite 如何使用 signature API 指定模型输入输出张量?

发布时间:2026/9/9 12:28:45
TensorFlow Lite 如何使用 signature API 指定模型输入输出张量? TensorFlow Lite 如何使用 signature API 指定模型输入输出张量【免费下载链接】tensorflowAn Open Source Machine Learning Framework for Everyone项目地址: https://gitcode.com/GitHub_Trending/te/tensorflow当你转换出的 TensorFlow Lite 模型有多个入口例如一个模型同时承担编码和解码两种任务或者输入输出张量有明确命名时用整数索引去指定输入/输出张量既脆弱又难读。TensorFlow Lite 的 signature API 就是解决这个问题通过签名中定义的张量名称喂入输入、按名称取回输出并用签名键signature key选择要执行哪个入口。本文给出从准备带签名的模型、转换、验证签名存在到用 Python / Java / C 按名执行推理的完整路径。适用前提均来自官方文档模型本身必须带有签名。签名可以在构建 SavedModel 或创建 concrete function 时指定通过from_saved_model转换器支持签名自 TensorFlow 2.5 起自 TensorFlow 2.7.0 起所有转换器 API包括from_keras_model、from_concrete_functions转换出的模型都带有签名当前提供 Java、C 和 Python 三种语言绑定iOS/Swift 尚不支持。Signature 由什么组成根据 Signatures in TensorFlow Lite 的定义一个签名由三部分构成Inputs签名内输入名到输入张量的映射Outputs签名内输出名到输出张量的映射Signature Key标识图中一个入口点entry point的名称。由此带来两个能力转换出的 TensorFlow Lite 模型遵循原 TensorFlow 模型签名来指定输入输出单个 TensorFlow Lite 模型可以支持多个入口点。文档中的示例模型就是一个双入口模型class Model(tf.Module): tf.function(input_signature[tf.TensorSpec(shape[None], dtypetf.float32)]) def encode(self, x): result tf.strings.as_string(x) return { encoded_result: result } tf.function(input_signature[tf.TensorSpec(shape[None], dtypetf.string)]) def decode(self, x): result tf.strings.to_number(x) return { decoded_result: result }从签名角度看这个模型有两个签名签名键输入输出encode{x}{encoded_result}decode{x}{decoded_result}也就是说后面所有按名访问张量的代码里x、encoded_result等名称都来自这里而不是自己起的名字。转换出带签名的模型从 SavedModel 转换主路径先把签名显式写入 SavedModel再交给TFLiteConverter。tf.saved_model.save的signatures参数就是指定签名键与对应 concrete function 的地方model Model() # Save the model SAVED_MODEL_PATH content/saved_models/coding tf.saved_model.save( model, SAVED_MODEL_PATH, signatures{ encode: model.encode.get_concrete_function(), decode: model.decode.get_concrete_function() }) # Convert the saved model using TFLiteConverter converter tf.lite.TFLiteConverter.from_saved_model(SAVED_MODEL_PATH) converter.target_spec.supported_ops [ tf.lite.OpsSet.TFLITE_BUILTINS, # enable TensorFlow Lite ops. tf.lite.OpsSet.SELECT_TF_OPS # enable TensorFlow ops. ] tflite_model converter.convert() # Print the signatures from the converted model interpreter tf.lite.Interpreter(model_contenttflite_model) signatures interpreter.get_signature_list() print(signatures)示例中模型包含tf.strings这类 TensorFlow 算子因此文档设置了converter.target_spec.supported_ops同时启用TFLITE_BUILTINS与SELECT_TF_OPS。你的模型若只含纯 TFLite 内置算子可以按自身情况调整。最后一步interpreter.get_signature_list()就是文档给出的验证方式在转换器把签名信息带入.tflite模型后用它打印出模型中实际存在的签名列表确认转换结果与预期一致。替代入口Keras 模型与 concrete functions如果输入不是 SavedModel文档提供了两个等价路径Keras 模型走from_keras_model转换器会自动使用默认签名keras_model tf.keras.Sequential( [ tf.keras.layers.Dense(2, input_dim4, activationrelu, namex), tf.keras.layers.Dense(1, activationrelu, nameoutput), ] ) converter tf.lite.TFLiteConverter.from_keras_model(keras_model) tflite_model converter.convert() interpreter tf.lite.Interpreter(model_contenttflite_model) signatures interpreter.get_signature_list() print(signatures)多个 concrete function 走from_concrete_functions把encode和decode两个入口一次性传入model Model() converter tf.lite.TFLiteConverter.from_concrete_functions( [model.encode.get_concrete_function(), model.decode.get_concrete_function()], model) converter.target_spec.supported_ops [ tf.lite.OpsSet.TFLITE_BUILTINS, # enable TensorFlow Lite ops. tf.lite.OpsSet.SELECT_TF_OPS # enable TensorFlow ops. ] tflite_model converter.convert() interpreter tf.lite.Interpreter(model_contenttflite_model) signatures interpreter.get_signature_list() print(signatures)用 signature API 按名指定输入输出张量转换完成后tf.lite.Interpreter提供两个与签名相关的方法get_signature_list()列出模型内的签名get_signature_runner(key)拿到某个入口的执行器。拿到 runner 后按参数名传输入、按字典名取输出全程不接触张量索引# Load the TFLite model in TFLite Interpreter interpreter tf.lite.Interpreter(model_contenttflite_model) # Print the signatures from the converted model signatures interpreter.get_signature_list() print(Signature:, signatures) # encode and decode are callable with input as arguments. encode interpreter.get_signature_runner(encode) decode interpreter.get_signature_runner(decode) # encoded and decoded are dictionaries with all outputs from the inference. input tf.constant([1, 2, 3], dtypetf.float32) print(Input:, input) encoded encode(xinput) print(Encoded result:, encoded) decoded decode(xencoded[encoded_result]) print(Decoded result:, decoded)注意两处按名访问的细节调用encode(xinput)时参数名x必须与签名中的输入名一致返回值是包含全部输出的字典所以decode的输入直接写作encoded[encoded_result]——这正是签名把上一个入口的输出名和下一个入口的输入名接起来的用法。如果模型里只定义了一个签名可以省略签名键get_signature_runner()会默认返回它有多个签名时必须传名称。文档在 inference.md 中给出了自定义签名名的示例保存时用signatures{my_signature: module.add.get_concrete_function()}运行端再按get_signature_runner(my_signature)取用。JavaAndroidJava 端通过Interpreter.runSignature(inputs, outputs, signatureName)执行三个参数分别是输入名到输入对象的 Map、输出名到输出数据的 Map、签名键模型只有一个签名时可省略。同一个Interpreter实例上分别跑两个入口try (Interpreter interpreter new Interpreter(file_of_tensorflowlite_model)) { // Run encoding signature. MapString, Object inputs new HashMap(); inputs.put(x, input); MapString, Object outputs new HashMap(); outputs.put(encoded_result, encoded_result); interpreter.runSignature(inputs, outputs, encode); // Run decoding signature. MapString, Object inputs new HashMap(); inputs.put(x, encoded_result); MapString, Object outputs new HashMap(); outputs.put(decoded_result, decoded_result); interpreter.runSignature(inputs, outputs, decode); }runSignature适用于自 TensorFlow 2.5 起转换的模型。inputs/outputsMap 中的键x、encoded_result等必须与签名中定义的输入输出名一致。CAndroid、iOS、LinuxC 端通过GetSignatureRunner(key)拿到每个入口独立的SignatureRunner之后ResizeInputTensor、input_tensor、output_tensor全部接受张量名称而非索引SignatureRunner* encode_runner interpreter-GetSignatureRunner(encode); encode_runner-ResizeInputTensor(x, {100}); encode_runner-AllocateTensors(); TfLiteTensor* input_tensor encode_runner-input_tensor(x); float* input GetTensorDatafloat(input_tensor); // Fill input. encode_runner-Invoke(); const TfLiteTensor* output_tensor encode_runner-output_tensor( encoded_result); float* output GetTensorDatafloat(output_tensor); // Access output.模型没有签名时怎么办signature API 的前提是模型带有签名。若你的模型没有定义 SignatureDefinference.md 给出的是索引式 API 这一条替代路径Python 中用allocate_tensors()get_input_details()/get_output_details()set_tensor(index, ...)invoke()get_tensor(index)Java 中用Interpreter.run()单输入单输出或runForMultipleInputsOutputs(inputs, map_of_indices_to_outputs)张量索引必须与转换时给 Converter 的顺序一致且getInputIndex(opName)/getOutputIndex(opName)在名称不是模型中的合法操作时会抛出IllegalArgumentException。这条路径不能指定多个入口这正是多入口模型应使用 signature API 的原因。已知限制与版本边界线程安全由于 TFLite 解释器不保证线程安全同一解释器上的多个 signature runner 不会并发执行iOS/Swift签名支持尚不可用版本2.5 起from_saved_model支持签名2.7 起实现多签名功能且所有转换器 API 都生成带签名的 TensorFlow Lite 模型。如果你的模型只有一个固定入口索引式 API 已经够用只有在多入口、或需要按名称对接上游输出与下游输入时才值得按上面的路径改用 signature API。完整代码可直接对照仓库中的 signatures.ipynb 与 inference.md。【免费下载链接】tensorflowAn Open Source Machine Learning Framework for Everyone项目地址: https://gitcode.com/GitHub_Trending/te/tensorflow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻