tf.lite.Interpreter
Интерфейс интерпретатора для запуска моделей TensorFlow Lite.
tf.lite.Interpreter(
model_path=None,
model_content=None,
experimental_delegates=None,
num_threads=None,
experimental_op_resolver_type=tf.lite.experimental.OpResolverType.AUTO,
experimental_preserve_all_tensors=False,
experimental_disable_delegate_clustering=False
)
Используется в блокнотах
Модели, полученные из TfLiteConverter, можно запускать в Python с помощью Interpreter.
Например, создадим простую модель Keras и преобразуем ее в TFLite (TfLiteConverter также поддерживает другие входные форматы с помощью from_saved_model и from_concrete_function).
x = np.array([[1.], [2.]])
y = np.array([[2.], [4.]])
model = tf.keras.models.Sequential([
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(units=1, input_shape=[1])
])
model.compile(optimizer='sgd', loss='mean_squared_error')
model.fit(x, y, epochs=1)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()tflite_model можно сохранить в файл и загрузить позже либо сразу загрузить в Interpreter. Поскольку TensorFlow Lite заранее планирует выделение тензоров для оптимизации инференса, перед инференсом необходимо вызвать allocate_tensors().
interpreter = tf.lite.Interpreter(model_content=tflite_model) interpreter.allocate_tensors() # Needed before execution!
Пример выполнения:
output = interpreter.get_output_details()[0] # Model has single output. input = interpreter.get_input_details()[0] # Model has single input. input_data = tf.constant(1., shape=[1, 1]) interpreter.set_tensor(input['index'], input_data) interpreter.invoke() interpreter.get_tensor(output['index']).shape (1, 1)
Для более удобного API инференса используйте get_signature_runner().
| Аргументы | |
|---|---|
model_path | Путь к файлу TF-Lite Flatbuffer. |
model_content | Содержимое модели. |
experimental_delegates | Экспериментальная возможность. Может измениться. Список объектов TfLiteDelegate, возвращаемых функцией lite.load_delegate(). |
num_threads | Задает количество потоков, используемых интерпретатором и доступных ядрам CPU. Если значение не задано, интерпретатор использует количество потоков по умолчанию, зависящее от реализации. В настоящее время многопоточность поддерживает только часть ядер, например conv. Значение num_threads должно быть >= -1. Установка num_threads в 0 отключает многопоточность, что эквивалентно установке num_threads в 1. Если задано значение -1, количество используемых потоков определяется реализацией и зависит от платформы. |
experimental_op_resolver_type | Обработчик разрешения операций, используемый интерпретатором. Он должен быть экземпляром OpResolverType. По умолчанию используется встроенный обработчик разрешения операций, соответствующий tflite::ops::builtin::BuiltinOpResolver в C++. |
experimental_preserve_all_tensors | Если значение равно true, промежуточные тензоры, используемые во время вычислений, сохраняются для проверки. Если переданный тип обработчика разрешения операций — AUTO или BUILTIN, он изменяется на BUILTIN_WITHOUT_DEFAULT_DELEGATES, чтобы делегаты TensorFlow Lite по умолчанию не применялись. Если значение равно false, получение промежуточных тензоров может привести к неопределенным значениям или None, особенно если граф был успешно изменен делегатом TensorFlow Lite по умолчанию. |
experimental_disable_delegate_clustering | Если значение равно true, кластеризация делегатов не выполняется на этапе разделения графа делегатов. Отключение кластеризации делегатов обеспечивает соблюдение порядка выполнения операций согласно явно добавленным в граф зависимостям управления (добавленным с помощью with tf.control_dependencies()), поскольку конвертер TF Lite по умолчанию удаляет зависимости управления. Большинству пользователей не следует устанавливать для этого флага значение True, если они не добавляют явные зависимости управления или если важен порядок выполнения графа. Для автоматически добавленных зависимостей управления (с помощью tf.Variable, tf.Print и т. д.) устанавливать для этого флага значение True не требуется, поскольку они учитываются по умолчанию. Обратите внимание, что этот флаг сейчас является экспериментальным и может быть удален или изменен, если конвертер TF Lite перестанет удалять такие зависимости управления из модели. Значение по умолчанию — False. |
| Исключения | |
|---|---|
ValueError | Если не удалось создать интерпретатор. |
Методы
allocate_tensors
allocate_tensors()
get_input_details
get_input_details()
Возвращает сведения о входных тензорах модели.
| Возвращаемое значение | |
|---|---|
Список, каждый элемент которого — словарь со сведениями о входном тензоре. Каждый словарь содержит следующие поля с описанием тензора:
|
get_output_details
get_output_details()
Возвращает сведения о выходных тензорах модели.
| Возвращаемое значение | |
|---|---|
Список, каждый элемент которого — словарь со сведениями о выходном тензоре. Словарь содержит те же поля, что и get_input_details(). |
get_signature_list
get_signature_list()
Возвращает список SignatureDef в модели.
Например:
signatures = interpreter.get_signature_list()
print(signatures)
# {
# 'add': {'inputs': ['x', 'y'], 'outputs': ['output_0']}
# }
Then using the names in the signature list you can get a callable from
get_signature_runner().
| Возвращаемое значение | |
|---|---|
| Список сведений SignatureDef в виде словаря. Ключом служит имя метода SignatureDef, а значением — словарь входных и выходных данных. |
get_signature_runner
get_signature_runner(
signature_key=None
)
Возвращает вызываемый объект для инференса с конкретным SignatureDef.
Пример использования:
interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()
fn = interpreter.get_signature_runner('div_with_remainder')
output = fn(x=np.array([3]), y=np.array([2]))
print(output)
# {
# 'quotient': array([1.], dtype=float32)
# 'remainder': array([1.], dtype=float32)
# }
Если модель содержит только одну сигнатуру, для signature_key можно передать None.
Используются имена, заданные в этом SignatureDef.
| Аргументы | |
|---|---|
signature_key | Ключ SignatureDef. Может быть равен None только в том случае, если модель содержит одну сигнатуру SignatureDef. Значение по умолчанию — None. |
| Возвращаемое значение | |
|---|---|
| Возвращает вызываемый объект, который выполняет инференс для SignatureDef, заданного аргументом 'signature_key'. Вызываемый объект принимает именованные аргументы, соответствующие аргументам SignatureDef; их значениями должны быть массивы NumPy. Вызываемый объект возвращает словарь, сопоставляющий имена выходных данных значениям NumPy с вычисленными результатами. |
| Исключения | |
|---|---|
ValueError | Если передан недопустимый signature_key. |
get_tensor
get_tensor(
tensor_index, subgraph_index=0
)
Возвращает значение выходного тензора (создает копию).
Чтобы избежать копирования, используйте tensor(). Эту функцию нельзя использовать для чтения промежуточных результатов.
| Аргументы | |
|---|---|
tensor_index | Индекс тензора, значение которого нужно получить. Его можно найти в поле 'index' метода get_output_details. |
subgraph_index | Индекс подграфа, из которого нужно получить тензор. По умолчанию равен 0 — это означает, что тензор будет получен из основного подграфа. |
| Возвращаемое значение | |
|---|---|
| массив NumPy. |
get_tensor_details
get_tensor_details()
Возвращает сведения обо всех тензорах, для которых доступны корректные сведения.
Тензоры, для которых не удалось найти необходимые сведения, в список не добавляются. К ним относятся временные тензоры без имени.
| Возвращаемое значение | |
|---|---|
| Список словарей со сведениями о тензорах. |
invoke
invoke()
Запускает интерпретатор.
Перед вызовом этого метода задайте размеры входных данных, выделите тензоры и заполните их значениями. Также обратите внимание: эта функция освобождает GIL, поэтому ресурсоемкие вычисления могут выполняться в фоновом режиме, пока интерпретатор Python продолжает работу. Пока вызов invoke() не завершен, нельзя вызывать другие функции этого объекта.
| Исключения | |
|---|---|
ValueError | Вызывает ValueError, если произошел сбой базового интерпретатора. |
reset_all_variables
reset_all_variables()
resize_tensor_input
resize_tensor_input(
input_index, tensor_size, strict=False
)
Изменяет размер входного тензора.
| Аргументы | |
|---|---|
input_index | Индекс входного тензора, размер которого нужно изменить. Его можно найти в поле 'index' метода get_input_details. |
tensor_size | Новая форма тензора. |
strict | Изменять размер можно только у неизвестных измерений, если strict равно True. Неизвестные измерения обозначаются как -1 в атрибуте shape_signature заданного тензора. (по умолчанию False) |
| Исключения | |
|---|---|
ValueError | Если интерпретатору не удалось изменить размер входного тензора. |
Использование:
interpreter = Interpreter(model_content=tflite_model) interpreter.resize_tensor_input(0, [num_test_images, 224, 224, 3]) interpreter.allocate_tensors() interpreter.set_tensor(0, test_images) interpreter.invoke()
set_tensor
set_tensor(
tensor_index, value
)
Задает значение входного тензора.
Обратите внимание: данные копируются в value.
Чтобы избежать копирования, можно использовать функцию tensor() для получения буфера NumPy, указывающего на входной буфер в интерпретаторе tflite.
| Аргументы | |
|---|---|
tensor_index | Индекс тензора, значение которого нужно задать. Его можно найти в поле 'index' метода get_input_details. |
value | Значение, которое нужно задать тензору. |
| Исключения | |
|---|---|
ValueError | Если интерпретатору не удалось задать значение тензора. |
tensor
tensor(
tensor_index
)
Возвращает функцию, предоставляющую представление текущего буфера тензора в NumPy.
Это позволяет читать и записывать данные этого тензора без копирования. По названию и назначению метод близок к члену tensor() интерфейса класса C++ Interpreter. Не сохраняйте ссылки на выходные данные после вызовов allocate_tensors() и invoke(). Эту функцию нельзя использовать для чтения промежуточных результатов.
Использование:
interpreter.allocate_tensors()
input = interpreter.tensor(interpreter.get_input_details()[0]["index"])
output = interpreter.tensor(interpreter.get_output_details()[0]["index"])
for i in range(10):
input().fill(3.)
interpreter.invoke()
print("inference %s" % output())
Обратите внимание, что эта функция не создает массив NumPy напрямую. Важно не удерживать представления NumPy данных дольше, чем это необходимо. Иначе интерпретатор нельзя будет запустить, поскольку он может изменить размер тензоров и сделать ссылки на них недействительными. API NumPy не позволяет изменять базовые буферы.
НЕПРАВИЛЬНО:
input = interpreter.tensor(interpreter.get_input_details()[0]["index"])() output = interpreter.tensor(interpreter.get_output_details()[0]["index"])() interpreter.allocate_tensors() # This will throw RuntimeError for i in range(10): input.fill(3.) interpreter.invoke() # this will throw RuntimeError since input,output
| Аргументы | |
|---|---|
tensor_index | Индекс тензора, значение которого нужно получить. Его можно найти в поле 'index' метода get_output_details. |
| Возвращаемое значение | |
|---|---|
| Функция, которая в любой момент может вернуть новый массив NumPy, указывающий на внутреннее состояние тензора TFLite. Функцию можно сохранять неограниченно долго, но массив NumPy сохранять небезопасно. |
© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter