InterpreterApi

公共接口 InterpreterApi
已知的间接子类

TensorFlow Lite 模型解释器的接口,不包括实验性方法。

InterpreterApi 实例封装了预训练的 TensorFlow Lite 模型,在该模型中执行操作以进行模型推断。

例如,如果模型仅接受一个输入并且仅返回一个输出:

try (InterpreterApi interpreter =
     new InterpreterApi.create(file_of_a_tensorflowlite_model)) {
   interpreter.run(input, output);
 }
 

如果模型接受多个输入或输出:

Object[] inputs = {input0, input1, ...};
 Map<Integer, Object> map_of_indices_to_outputs = new HashMap<>();
 FloatBuffer ith_output = FloatBuffer.allocateDirect(3 * 2 * 4);  // Float tensor, shape 3x2x4.
 ith_output.order(ByteOrder.nativeOrder());
 map_of_indices_to_outputs.put(i, ith_output);
 try (InterpreterApi interpreter =
     new InterpreterApi.create(file_of_a_tensorflowlite_model)) {
   interpreter.runForMultipleInputsOutputs(inputs, map_of_indices_to_outputs);
 }
 

如果模型获取或生成字符串张量:

String[] input = {"foo", "bar"};  // Input tensor shape is [2].
 String[][] output = new String[3][2];  // Output tensor shape is [3, 2].
 try (InterpreterApi interpreter =
     new InterpreterApi.create(file_of_a_tensorflowlite_model)) {
   interpreter.runForMultipleInputsOutputs(input, output);
 }
 

请注意,形状 [] 和形状 [1] 是有区别的。对于标量字符串张量输出:

String[] input = {"foo"};  // Input tensor shape is [1].
 ByteBuffer outputBuffer = ByteBuffer.allocate(OUTPUT_BYTES_SIZE);  // Output tensor shape is [].
 try (Interpreter interpreter = new Interpreter(file_of_a_tensorflowlite_model)) {
   interpreter.runForMultipleInputsOutputs(input, outputBuffer);
 }
 byte[] outputBytes = new byte[outputBuffer.remaining()];
 outputBuffer.get(outputBytes);
 // Below, the `charset` can be StandardCharsets.UTF_8.
 String output = new String(outputBytes, charset);
 

使用 Toco 将 TensorFlow 模型转换为 TensorFlowLite 模型时,系统会确定输入和输出的顺序,以及输入的默认形状。

以(多维)数组形式提供输入时,相应的输入张量将根据该数组的形状隐式调整大小。以 Buffer 类型提供输入时,不会隐式调整大小;调用方必须确保 Buffer 字节大小与相应张量的大小一致,或者先通过 resizeInput(int, int[]) 调整张量的大小。您可以通过 Tensor 类(通过 getInputTensor(int)getOutputTensor(int) 获得)获取张量形状和类型信息。

警告InterpreterApi 实例不是线程安全的。

警告InterpreterApi 实例拥有的资源必须通过调用 close() 来明确释放

TFLite 库是基于 NDK API 19 构建的。它可能适用于低于 19 的 Android API 级别,但不能保证。

嵌套类

类别 InterpreterApi.Options 用于控制运行时解释器行为的选项类。

公共方法

抽象 void
allocateTensors()
根据需要显式更新所有张量的分配。
抽象 void
close()
释放与 InterpreterApi 实例关联的资源。
static InterpreterApi
createFile modelFile、InterpreterApi.Options 选项)
使用指定的模型和选项构造 InterpreterApi 实例。
static InterpreterApi
createByteBuffer byteBuffer、InterpreterApi.Options 选项)
使用指定的模型和选项构造 InterpreterApi 实例。
abstract int
getInputIndex(String opName)
根据输入的操作名称获取输入的索引。
abstract Tensor
getInputTensor(int inputIndex)
获取与提供的输入索引相关联的张量。
abstract int
getInputTensorCount()
获取输入张量的数量。
abstract Long
getLastNativeInferenceDurationNanoseconds()
返回原生推断时间。
abstract int
getOutputIndex(String opName)
根据输出的操作名称获取输出的索引。
abstract Tensor
getOutputTensor(int outputIndex)
获取与提供的输出索引相关联的张量。
abstract int
getOutputTensorCount()
获取输出张量的数量。
抽象 void
resizeInput(int idx, int[] dims, boolean strict)
将原生模型的第 idx 输入的大小调整为指定的维度。
抽象 void
resizeInput(int idx, int[] dims)
将原生模型的第 idx 输入的大小调整为指定的维度。
抽象 void
runObject 输入、Object 输出)
如果模型只接受一个输入且仅提供一个输出,则运行模型推断。
抽象 void
runForMultipleInputsOutputs(Object[] 输入、Map<Integer, Object> 输出)
如果模型接受多个输入或返回多个输出,则运行模型推断。

继承的方法

公共方法

public abstract void allocateTensors ()

根据需要显式更新所有张量的分配。

这将使用给定的输入张量形状传播依赖张量的形状和内存分配。

注意:此调用 *完全可选*。如果调整了任何输入张量的大小,则在执行期间将自动分配张量。在执行图之前,此调用最有助于确定任何输出张量的形状,例如,

 interpreter.resizeInput(0, new int[]{1, 4, 4, 3}));
 interpreter.allocateTensors();
 FloatBuffer input = FloatBuffer.allocate(interpreter.getInputTensor(0).numElements());
 // Populate inputs...
 FloatBuffer output = FloatBuffer.allocate(interpreter.getOutputTensor(0).numElements());
 interpreter.run(input, output)
 // Process outputs...

注意:某些图具有动态形状的输出,在这种情况下,在执行推断之前,输出形状可能不会完全传播。

抛出
IllegalStateException 如果图的张量无法成功分配,则会发生该错误。

public abstract void close ()

释放与 InterpreterApi 实例关联的资源。

public static InterpreterApi create File modelFile、InterpreterApi.Options options)

使用指定的模型和选项构造 InterpreterApi 实例。模型将从文件加载。

参数
modelFile 包含预训练 TF Lite 模型的文件。
选项 一组用于自定义解释器行为的选项。
抛出
IllegalArgumentException 如果 modelFile 未对有效的 TensorFlow Lite 模型进行编码,则会发生该错误。

public static InterpreterApi create (ByteBuffer byteBuffer, InterpreterApi.Options options)

使用指定的模型和选项构造 InterpreterApi 实例。模型将从 ByteBuffer 中读取。

参数
byteBuffer 采用二进制序列化形式的预训练 TF Lite 模型。构建 InterpreterApi 实例后,不应修改 ByteBuffer。ByteBuffer 可以是对模型文件进行内存映射的 MappedByteBuffer,也可以是包含模型字节内容的 nativeOrder() 的直接 ByteBuffer
选项 一组用于自定义解释器行为的选项。
抛出
IllegalArgumentException 如果 byteBuffer 不是 MappedByteBuffer,也不是 nativeOrder 的直接 ByteBuffer

public abstract int getInputIndex (String opName)

根据输入的操作名称获取输入的索引。

参数
opName
抛出
IllegalArgumentException 如果 opName 与用于初始化解释器的模型中的任何输入都不匹配。

public abstract Tensor getInputTensor (int inputIndex)

获取与提供的输入索引相关联的张量。

参数
inputIndex
抛出
IllegalArgumentException 如果 inputIndex 为负或者不小于模型输入的数量,则会发生该错误。

public abstract int getInputTensorCount ()

获取输入张量的数量。

public abstract Long getLastNativeInferenceDurationNanoseconds ()

返回原生推断时间。

抛出
IllegalArgumentException 如果解释器没有初始化模型,则会发生该错误。

public abstract int getOutputIndex (String opName)

根据输出的操作名称获取输出的索引。

参数
opName
抛出
IllegalArgumentException 如果 opName 与用于初始化解释器的模型中的任何输出都不匹配。

public abstract Tensor getOutputTensor (int outputIndex)

获取与所提供的输出索引相关联的张量。

注意:在执行推理之前,输出张量详细信息(例如形状)可能不会被完全填充。如果您在运行推理 *之前* 需要更新的详细信息(例如,在调整输入张量的大小之后,这可能会使输出张量形状失效),请使用 allocateTensors() 显式触发分配和形状传播。请注意,对于输出形状依赖于输入 *值*的图表,只有在运行推理之前,可能无法完全确定输出形状。

参数
outputIndex
抛出
IllegalArgumentException 如果 outputIndex 为负数或不小于模型输出数,则返回此值。

public abstract int getOutputTensorCount ()

获取输出张量的数量。

public abstract void resizeInput (int idx, int[] dims, boolean strict)

将原生模型的第 idx 输入的大小调整为指定的维度。

当 `strict` 为 True 时,只能调整未知尺寸的大小。在“Tensor.shapeSignature()”返回的数组中,未知维度用“-1”表示。

参数
idx
dims
严格
抛出
IllegalArgumentException 如果 idx 为负或者不小于模型输入的数量;或者调整第 idx 个输入的大小时发生错误。此外,如果“strict”为 True,尝试调整具有固定维度的张量大小时也会发生错误。

public abstract void resizeInput (int idx, int[] dims)

将原生模型的第 idx 输入的大小调整为指定的维度。

参数
idx
dims
抛出
IllegalArgumentException 如果 idx 为负或者不小于模型输入的数量;或者调整第 idx 个输入的大小时发生错误。

public abstract void run Object 输入、Object 输出)

如果模型只接受一个输入且仅提供一个输出,则运行模型推断。

警告:如果将 Buffer(最好是直接,但不是必需的)用作输入/输出数据类型,则 API 的效率会更高。请考虑使用 Buffer 来馈送和提取原始数据,以获得更好的效果。系统支持以下具体的 Buffer 类型:

  • ByteBuffer - 与任何底层基元张量类型都兼容。
  • FloatBuffer - 与浮点张量兼容。
  • IntBuffer - 与 int32 Tensor 兼容。
  • LongBuffer - 与 int64 Tensor 兼容。
请注意,布尔值类型仅支持作为数组(而不是 Buffer)或标量输入。

参数
输入 数组、多维数组或基元类型(包括 int、float、long 和 byte)的 BufferBuffer 是为基元类型传递大型输入数据的首选方式,而字符串类型需要使用(多维)数组输入路径。使用 Buffer 时,其内容应保持不变,直到模型推断完成,并且调用方必须确保 Buffer 位于适当的读取位置。仅当调用方使用允许缓冲区句柄互操作的 Delegate 且此类缓冲区已绑定到输入 Tensor 时,才允许 null 值。
output 输出数据的多维数组或基元类型(包括 int、float、long 和 byte)的 Buffer。使用 Buffer 时,调用方必须确保设置了适当的写入位置。允许使用 null 值,但在某些情况下很有用,例如,如果调用方使用允许缓冲区句柄互操作的 Delegate,并且此类缓冲区已绑定到输出 Tensor(另请参阅 Interpreter.Options#setAllowBufferHandleOutput(boolean)),;或者如果图表具有动态形状的输出,并且调用方必须在调用输出后查询输出 Tensor 形状,则直接从 Tensor.asReadOnlyBuffer() 提取数据。
抛出
IllegalArgumentException 如果 input 为 null 或为空,或者运行推断时发生错误。
IllegalArgumentException (实验性,可能会发生变化)如果推断被 setCancelled(true) 中断。

public abstract void runForMultipleInputsOutputs (Object[] 输入, Map<IntegerObject> 输出)

如果模型接受多个输入或返回多个输出,则运行模型推断。

警告:如果将 Buffer(最好是直接,但不是必需的)用作输入/输出数据类型,则 API 的效率会更高。请考虑使用 Buffer 来馈送和提取原始数据,以获得更好的效果。系统支持以下具体的 Buffer 类型:

  • ByteBuffer - 与任何底层基元张量类型都兼容。
  • FloatBuffer - 与浮点张量兼容。
  • IntBuffer - 与 int32 Tensor 兼容。
  • LongBuffer - 与 int64 Tensor 兼容。
请注意,布尔值类型仅支持作为数组(而不是 Buffer)或标量输入。

注意:仅当调用方使用允许缓冲区句柄互操作操作的 Delegate,并且此类缓冲区已绑定到相应的输入或输出 Tensor 时,才允许 inputsoutputs 的各个元素的 null 值。

参数
输入 输入数据的数组。输入的顺序应与模型输入的顺序相同。每个输入可以是数组或多维数组,也可以是基元类型(包括 int、float、long 和 byte)的 BufferBuffer 是传递大量输入数据的首选方式,而字符串类型需要使用(多维)数组输入路径。使用 Buffer 时,其内容应保持不变,直到模型推断完成,并且调用方必须确保 Buffer 位于适当的读取位置。
输出 将输出索引映射到输出数据的多维数组或基元类型(包括 int、float、long 和 byte)的 Buffer 的映射。它只需保留相应条目即可使用输出。使用 Buffer 时,调用方必须确保设置了适当的写入位置。在以下情况下,映射可能为空:缓冲区句柄用于输出张量数据;输出为动态形状,且调用方必须在调用推断后查询输出 Tensor 形状,从而直接从输出张量提取数据(通过 Tensor.asReadOnlyBuffer())。
抛出
IllegalArgumentException 如果 inputs 为 null 或为空,如果 outputs 为 null,或者运行推断时发生错误。