Добавление метаданных в модели TensorFlow Lite

Метаданные TensorFlow Lite предоставляют стандарт для описания моделей. Метаданные - важный источник знаний о том, что делает модель, и ее входной / выходной информации. Метаданные состоят из обоих

Все модели изображения , опубликованные на TensorFlow Lite принимали модели и TensorFlow Hub были заселены с метаданными.

Модель с форматом метаданных

model_with_metadata
Рисунок 1. Модель TFLite с метаданными и связанными файлами.

Модель метаданных определяется в metadata_schema.fbs , а FlatBuffer файл. Как показано на рисунке 1, она хранится в метаданных поля модели схемы TFLite , под названием, "TFLITE_METADATA" . Некоторые модели могут прийти с соответствующими файлами, такими как файлы классификации меток . Эти файлы объединяются в конец исходного файла модели как ZIP , используя ZipFile режим «Добавить» ( 'a' режим). TFLite Interpreter может использовать новый формат файла так же, как и раньше. См пакета обновления для связанных файлов для получения дополнительной информации.

См. Инструкцию ниже о том, как заполнять, визуализировать и читать метаданные.

Настройте инструменты метаданных

Перед добавлением метаданных в вашу модель вам потребуется настроить среду программирования Python для запуска TensorFlow. Существует подробное руководство о том , как установить это здесь .

После настройки среды программирования Python вам потребуется установить дополнительные инструменты:

pip install tflite-support

Инструмент метаданных TensorFlow Lite поддерживает Python 3.

Добавление метаданных с помощью Flatbuffers Python API

Есть три части модели метаданных в схеме :

  1. Информация о модели - Общее описание модели, а также такие элементы, как лицензионные условия. См ModelMetadata .
  2. Входная информация - Описание входов и предварительная обработка , такая как требуется нормализация. См SubGraphMetadata.input_tensor_metadata .
  3. Выходная информация - Описание производства и пост-обработки требуется , такие как отображение на этикетках. См SubGraphMetadata.output_tensor_metadata .

Поскольку TensorFlow Lite поддерживает только единственный подграф в данный момент, генератор кода TensorFlow Lite и Binding функция Android Studio ML будет использовать ModelMetadata.name и ModelMetadata.description , вместо SubGraphMetadata.name и SubGraphMetadata.description при отображении метаданных и генерации кода.

Поддерживаемые типы ввода / вывода

Метаданные TensorFlow Lite для ввода и вывода разработаны не с учетом конкретных типов моделей, а с учетом типов ввода и вывода. Не имеет значения, что функционально выполняет модель, если типы ввода и вывода состоят из следующего или их комбинации, они поддерживаются метаданными TensorFlow Lite:

  • Feature - Числа, которые являются целыми числами без знака или float32.
  • Изображение - метаданные в настоящее время поддерживают изображения в RGB и оттенках серого.
  • Ограничительная рамка - ограничивающие рамки прямоугольной формы. Схема поддерживает различные схемы нумерации .

Упакуйте связанные файлы

Модели TensorFlow Lite могут поставляться с разными связанными файлами. Например, модели естественного языка обычно имеют файлы словаря, которые сопоставляют части слова с идентификаторами слов; модели классификации могут иметь файлы меток, которые указывают категории объектов. Без связанных файлов (если они есть) модель не будет хорошо работать.

Связанные файлы теперь можно связать с моделью через библиотеку метаданных Python. Новая модель TensorFlow Lite становится zip-файлом, который содержит как модель, так и связанные файлы. Его можно распаковать с помощью обычных инструментов для архивирования. Этот новый формат модель продолжает использовать то же расширение файла, .tflite . Он совместим с существующей структурой TFLite и интерпретатором. См метаданных обновления и связанные с ним файлы в модель для более подробной информации.

Информация о связанном файле может быть записана в метаданных. В зависимости от типа файла и где файл прикреплен к (т.е. ModelMetadata , SubGraphMetadata и TensorMetadata ), генератор TensorFlow Lite Android код может применять соответствующие до / после обработки автоматически объекта. Смотрите раздел <использования Codegen> каждого ассоциированного типа файла в схеме для получения более подробной информации.

Параметры нормализации и квантования

Нормализация - это распространенный метод предварительной обработки данных в машинном обучении. Цель нормализации - изменить значения к общей шкале, не искажая различия в диапазонах значений.

Модель квантование является методом , который позволяет уменьшить точные весы представлений и необязательно активаций как для хранения и вычислений.

С точки зрения предварительной обработки и постобработки, нормализация и квантование - это два независимых шага. Вот подробности.

Нормализация Квантование

Пример значений параметров входного изображения в MobileNet для моделей с плавающей точкой и квантовой модели соответственно.
Поплавок модель:
- среднее значение: 127,5
- стандарт: 127,5
Quant модель:
- среднее значение: 127,5
- стандарт: 127,5
Поплавок модель:
- нулевая точка: 0
- масштаб: 1.0
Quant модель:
- нулевая точка: 128,0
- шкала: 0.0078125f




Когда вызывать?


Входы: Если входные данные нормализованы в обучении, входные данные потребности вывода нормированные соответственно.
Выходы: выходные данные не будут нормализованы в целом.
Модели Поплавок не нужно квантование.
Квантовое модель может быть или может не потребоваться квантование в предварительной / последующей обработке. Это зависит от типа данных тензоров ввода / вывода.
- тензоры с плавающей запятой: квантование при предварительной / постобработке не требуется. Quant op и dequant op запекаются в графике модели.
- тензоры int8 / uint8: требуется квантование при предварительной / постобработке.


Формула


normalized_input = (ввод - среднее) / стандартное
Квантование для входов:
q = f / масштаб + нулевая точка
Деквантования для выходов:
f = (q - нулевая точка) * масштаб

Где параметры
Заполняется модели создателя и хранятся в модели метаданных, а NormalizationOptions Заполняется автоматически конвертером TFLite и сохраняется в файле модели tflite.
Как получить параметры? Через MetadataExtractor API [2] Через TFLite Tensor API [1] или через MetadataExtractor API [2]
Имеют ли одинаковую ценность модели с плавающей точкой и квантовой модели? Да, у поплавковых и квантовых моделей одинаковые параметры нормализации. Нет, модель с плавающей запятой не требует квантования.
Генератор кода TFLite или привязка Android Studio ML автоматически генерируют его при обработке данных?
да

да

[1] TensorFlow Lite Java API и в TensorFlow Lite C ++ API .
[2] метаданных библиотеки экстрактор

При обработке данных изображения для моделей uint8 нормализация и квантование иногда пропускаются. Это нормально, когда значения пикселей находятся в диапазоне [0, 255]. Но в целом вы всегда должны обрабатывать данные в соответствии с параметрами нормализации и квантования, если это применимо.

TensorFlow Lite Задача библиотека может обрабатывать нормировку для вас , если вы настроили NormalizationOptions в метаданных. Обработка квантования и деквантования всегда инкаплюирована.

Примеры

Вы можете найти примеры того, как должны заполняться метаданные для различных типов моделей, здесь:

Классификация изображений

Скачать скрипт здесь , который заполняет метаданные mobilenet_v1_0.75_160_quantized.tflite . Запускаем скрипт так:

python ./metadata_writer_for_image_classifier.py \
    --model_file=./model_without_metadata/mobilenet_v1_0.75_160_quantized.tflite \
    --label_file=./model_without_metadata/labels.txt \
    --export_directory=model_with_metadata

Для заполнения метаданных для других моделей классификации изображения, добавить модель спецификации , как это в сценарий. В оставшейся части этого руководства будут выделены некоторые ключевые разделы в примере классификации изображений, чтобы проиллюстрировать ключевые элементы.

Погрузитесь в пример классификации изображений

Информация о модели

Метаданные начинаются с создания новой информации о модели:

from tflite_support import flatbuffers
from tflite_support import metadata as _metadata
from tflite_support import metadata_schema_py_generated as _metadata_fb

""" ... """
"""Creates the metadata for an image classifier."""

# Creates model info.
model_meta = _metadata_fb.ModelMetadataT()
model_meta.name = "MobileNetV1 image classifier"
model_meta.description = ("Identify the most prominent object in the "
                          "image from a set of 1,001 categories such as "
                          "trees, animals, food, vehicles, person etc.")
model_meta.version = "v1"
model_meta.author = "TensorFlow"
model_meta.license = ("Apache License. Version 2.0 "
                      "http://www.apache.org/licenses/LICENSE-2.0.")

Информация о вводе / выводе

В этом разделе показано, как описать входную и выходную сигнатуру вашей модели. Эти метаданные могут использоваться автоматическими генераторами кода для создания кода предварительной и постобработки. Чтобы создать входную или выходную информацию о тензоре:

# Creates input info.
input_meta = _metadata_fb.TensorMetadataT()

# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()

Ввод изображения

Изображение - это распространенный тип ввода для машинного обучения. Метаданные TensorFlow Lite поддерживают такую ​​информацию, как цветовое пространство, и информацию предварительной обработки, такую ​​как нормализация. Размер изображения не требует указания вручную, так как он уже определяется формой входного тензора и может быть вычислен автоматически.

input_meta.name = "image"
input_meta.description = (
    "Input image to be classified. The expected image is {0} x {1}, with "
    "three channels (red, blue, and green) per pixel. Each value in the "
    "tensor is a single byte between 0 and 255.".format(160, 160))
input_meta.content = _metadata_fb.ContentT()
input_meta.content.contentProperties = _metadata_fb.ImagePropertiesT()
input_meta.content.contentProperties.colorSpace = (
    _metadata_fb.ColorSpaceType.RGB)
input_meta.content.contentPropertiesType = (
    _metadata_fb.ContentProperties.ImageProperties)
input_normalization = _metadata_fb.ProcessUnitT()
input_normalization.optionsType = (
    _metadata_fb.ProcessUnitOptions.NormalizationOptions)
input_normalization.options = _metadata_fb.NormalizationOptionsT()
input_normalization.options.mean = [127.5]
input_normalization.options.std = [127.5]
input_meta.processUnits = [input_normalization]
input_stats = _metadata_fb.StatsT()
input_stats.max = [255]
input_stats.min = [0]
input_meta.stats = input_stats

Вывод этикеток

Этикетка может быть сопоставлена с помощью тензора выходного ассоциированного файла , используя TENSOR_AXIS_LABELS .

# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()
output_meta.name = "probability"
output_meta.description = "Probabilities of the 1001 labels respectively."
output_meta.content = _metadata_fb.ContentT()
output_meta.content.content_properties = _metadata_fb.FeaturePropertiesT()
output_meta.content.contentPropertiesType = (
    _metadata_fb.ContentProperties.FeatureProperties)
output_stats = _metadata_fb.StatsT()
output_stats.max = [1.0]
output_stats.min = [0.0]
output_meta.stats = output_stats
label_file = _metadata_fb.AssociatedFileT()
label_file.name = os.path.basename("your_path_to_label_file")
label_file.description = "Labels for objects that the model can recognize."
label_file.type = _metadata_fb.AssociatedFileType.TENSOR_AXIS_LABELS
output_meta.associatedFiles = [label_file]

Создайте метаданные Flatbuffers

Следующий код объединяет информацию о модели с входной и выходной информацией:

# Creates subgraph info.
subgraph = _metadata_fb.SubGraphMetadataT()
subgraph.inputTensorMetadata = [input_meta]
subgraph.outputTensorMetadata = [output_meta]
model_meta.subgraphMetadata = [subgraph]

b = flatbuffers.Builder(0)
b.Finish(
    model_meta.Pack(b),
    _metadata.MetadataPopulator.METADATA_FILE_IDENTIFIER)
metadata_buf = b.Output()

Упакуйте метаданные и связанные файлы в модель

После Flatbuffers метаданных создаются, метаданные и файл этикетка записываются в файл TFLite через populate метод:

populator = _metadata.MetadataPopulator.with_model_file(model_file)
populator.load_metadata_buffer(metadata_buf)
populator.load_associated_files(["your_path_to_label_file"])
populator.populate()

Вы можете упаковать много связанных файлов , как вы хотите в модель через load_associated_files . Однако необходимо упаковать хотя бы те файлы, которые задокументированы в метаданных. В этом примере упаковка файла этикеток обязательна.

Визуализируйте метаданные

Вы можете использовать Netron визуализировать метаданные, или вы можете прочитать метаданные из модели TensorFlow Lite в формате JSON с использованием MetadataDisplayer :

displayer = _metadata.MetadataDisplayer.with_model_file(export_model_path)
export_json_file = os.path.join(FLAGS.export_directory,
                    os.path.splitext(model_basename)[0] + ".json")
json_file = displayer.get_metadata_json()
# Optional: write out the metadata as a json file
with open(export_json_file, "w") as f:
  f.write(json_file)

Android Studio также поддерживает отображение метаданных через Binding функции Android Studio ML .

Управление версиями метаданных

Схема метаданных версирован как на семантическом числа версий, которая отслеживает изменения файла схемы, и по идентификации файла Flatbuffers, что указывает на истинную совместимость версий.

Семантический номер версии

Схема метаданных версирована по семантическому числу версий , такие как MAJOR.MINOR.PATCH. Он отслеживает изменения схемы в соответствии с правилами здесь . Смотрите историю полей , добавленных после версии 1.0.0 .

Идентификация файла Flatbuffers

Семантическое управление версиями гарантирует совместимость при соблюдении правил, но не подразумевает истинной несовместимости. Увеличение числа MAJOR не обязательно означает, что обратная совместимость нарушена. Таким образом, мы используем идентификацию файла Flatbuffers , file_identifier , чтобы обозначить истинную совместимость схемы метаданных. Идентификатор файла состоит ровно из 4 символов. Он привязан к определенной схеме метаданных и не может быть изменен пользователями. Если обратная совместимость схемы метаданных по какой-либо причине должна быть нарушена, file_identifier будет увеличиваться, например, с «M001» на «M002». Ожидается, что File_identifier будет изменяться гораздо реже, чем metadata_version.

Минимально необходимая версия парсера метаданных

Минимально необходимый анализатор метаданных версия является минимальной версией метаданных парсера (в Flatbuffers сгенерированного кода) , который может читать Flatbuffers метаданных в полном объеме. Версия фактически является наибольшим номером версии среди версий всех заполненных полей и наименьшей совместимой версией, указанной идентификатором файла. Минимально необходимый анализатор метаданных версия автоматически заполняются по MetadataPopulator , когда метаданные заселены в модель TFLite. См экстрактор метаданных для получения дополнительной информации о том , как используется минимально необходимый анализатор метаданных версии.

Считайте метаданные из моделей

Библиотека метаданных Extractor является удобным инструментом для чтения метаданных и связанных с ними файлов из моделей на различных платформах (см версию Java и в C ++ версии ). Вы можете создать свой собственный инструмент для извлечения метаданных на других языках, используя библиотеку Flatbuffers.

Прочтите метаданные на Java

Для того, чтобы использовать библиотеку метаданных Extractor в вашем Android приложение, мы рекомендуем использовать TensorFlow Lite Metadata AAR размещен на MavenCentral . Он содержит MetadataExtractor класса, а также привязки FlatBuffers Java для схемы метаданных и модель схемы .

Вы можете указать это в вашем build.gradle зависимостей следующим образом :

dependencies {
    implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'
}

Для того, чтобы использовать ночные снимки, убедитесь , что вы добавили Sonatype SNAPSHOT репозитория .

Вы можете инициализировать MetadataExtractor объект с ByteBuffer , что указывает на модель:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer должен оставаться неизменным в течение всего срока службы MetadataExtractor объекта. Инициализация может завершиться неудачно, если идентификатор файла Flatbuffers метаданных модели не совпадает с идентификатором анализатора метаданных. См метаданных управления версиями для получения дополнительной информации.

С совпадающими идентификаторами файлов средство извлечения метаданных будет успешно читать метаданные, сгенерированные из всех прошлых и будущих схем, благодаря механизму прямой и обратной совместимости Flatbuffers. Однако поля из будущих схем не могут быть извлечены старыми экстракторами метаданных. Минимально необходимый анализатор версии метаданных указывает минимальную версию метаданных синтаксический анализатор , который может читать Flatbuffers метаданных в полном объеме. Вы можете использовать следующий метод, чтобы проверить, выполняется ли минимально необходимое условие версии парсера:

public final boolean isMinimumParserVersionSatisfied();

Допускается передача модели без метаданных. Однако вызов методов, считывающих из метаданных, вызовет ошибки времени выполнения. Вы можете проверить , если модель имеет метаданные, вызывая hasMetadata метод:

public boolean hasMetadata();

MetadataExtractor предоставляет удобные функции для вас , чтобы получить метаданные входных / выходных тензоров. Например,

public int getInputTensorCount();
public TensorMetadata getInputTensorMetadata(int inputIndex);
public QuantizationParams getInputTensorQuantizationParams(int inputIndex);
public int[] getInputTensorShape(int inputIndex);
public int getoutputTensorCount();
public TensorMetadata getoutputTensorMetadata(int inputIndex);
public QuantizationParams getoutputTensorQuantizationParams(int inputIndex);
public int[] getoutputTensorShape(int inputIndex);

Хотя модель схема TensorFlow Lite поддерживает несколько подграфов, то TFLite интерпретатор поддерживает только один подграф. Таким образом, MetadataExtractor опускает индекс подграф в качестве входного аргумента в его методах.

Чтение связанных файлов из моделей

Модель TensorFlow Lite с метаданными и связанными файлами, по сути, представляет собой zip-файл, который можно распаковать с помощью обычных zip-инструментов для получения связанных файлов. Например, вы можете распаковать mobilenet_v1_0.75_160_quantized и извлечь файл ярлыка в модели следующим образом :

$ unzip mobilenet_v1_0.75_160_quantized_1_metadata_1.tflite
Archive:  mobilenet_v1_0.75_160_quantized_1_metadata_1.tflite
 extracting: labels.txt

Вы также можете читать связанные файлы через библиотеку Metadata Extractor.

В Java, передать имя файла в MetadataExtractor.getAssociatedFile метод:

public InputStream getAssociatedFile(String fileName);

, Подобным образом , в C ++, это может быть сделано с помощью метода, ModelMetadataExtractor::GetAssociatedFile :

tflite::support::StatusOr<absl::string_view> GetAssociatedFile(
      const std::string& filename) const;