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)
Используйте get_signature_runner() для более удобного API вывода.
| Аргументы | |
|---|---|
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()
Получает список SignatureDefs в модели.
Пример,
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)
# }
None можно передать для signature_key, если в модели всего одна подпись.
Все используемые имена — имена этой конкретной 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 | Форма tensor_shape, на которую необходимо изменить размер входа. |
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