¡Reserva! Google I / O regresa del 18 al 20 de mayo Regístrese ahora
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Agregar metadatos a los modelos de TensorFlow Lite

Los metadatos de TensorFlow Lite proporcionan un estándar para las descripciones de modelos. Los metadatos son una fuente importante de conocimiento sobre lo que hace el modelo y su información de entrada / salida. Los metadatos constan de ambos

Todos los modelos de imágenes publicados en los modelos alojados de TensorFlow Lite y TensorFlow Hub se completaron con metadatos.

Modelo con formato de metadatos

model_with_metadata
Figura 1. Modelo TFLite con metadatos y archivos asociados.

Los metadatos del modelo se definen en metadata_schema.fbs , un archivo FlatBuffer . Como se muestra en la Figura 1, se almacena en el campo de metadatos del esquema del modelo TFLite , bajo el nombre "TFLITE_METADATA" . Algunos modelos pueden venir con archivos asociados, como archivos de etiquetas de clasificación . Estos archivos se concatenan al final del archivo del modelo original como un ZIP usando el modo "agregar" ZipFile ( modo 'a' ). TFLite Interpreter puede consumir el nuevo formato de archivo de la misma manera que antes. Consulte Empaquetar los archivos asociados para obtener más información.

Consulte las instrucciones a continuación sobre cómo completar, visualizar y leer metadatos.

Configurar las herramientas de metadatos

Antes de agregar metadatos a su modelo, necesitará una configuración de entorno de programación Python para ejecutar TensorFlow. Hay una guía detallada sobre cómo configurar esto aquí .

Después de configurar el entorno de programación de Python, deberá instalar herramientas adicionales:

pip install tflite-support

Las herramientas de metadatos de TensorFlow Lite son compatibles con Python 2 y Python 3.

Agregar metadatos

Hay tres partes de los metadatos del modelo en el esquema :

  1. Información del modelo : descripción general del modelo, así como elementos como los términos de la licencia. Consulte ModelMetadata .
  2. Información de entrada : descripción de las entradas y preprocesamiento necesarios, como la normalización. Consulte SubGraphMetadata.input_tensor_metadata .
  3. Información de salida : descripción de la salida y el posprocesamiento necesarios, como la asignación a etiquetas. Consulte SubGraphMetadata.output_tensor_metadata .

Dado que TensorFlow Lite solo admite un subgrafo único en este punto, el generador de código de TensorFlow Lite y la función de enlace ML de Android Studio usarán ModelMetadata.name y ModelMetadata.description , en lugar de SubGraphMetadata.name y SubGraphMetadata.description , al mostrar metadatos y generar código.

Tipos de entrada / salida admitidos

Los metadatos de TensorFlow Lite para entrada y salida no están diseñados con tipos de modelos específicos en mente, sino más bien con tipos de entrada y salida. No importa lo que haga funcionalmente el modelo, siempre que los tipos de entrada y salida consistan en lo siguiente o una combinación de lo siguiente, es compatible con los metadatos de TensorFlow Lite:

  • Característica: números que son enteros sin signo o float32.
  • Imagen: actualmente, los metadatos admiten imágenes RGB y en escala de grises.
  • Cuadro delimitador: cuadros delimitadores de forma rectangular. El esquema admite una variedad de esquemas de numeración .

Empaque los archivos asociados

Los modelos de TensorFlow Lite pueden venir con diferentes archivos asociados. Por ejemplo, los modelos de lenguaje natural suelen tener archivos de vocabulario que asignan partes de palabras a ID de palabras; Los modelos de clasificación pueden tener archivos de etiquetas que indiquen categorías de objetos. Sin los archivos asociados (si los hay), un modelo no funcionará bien.

Los archivos asociados ahora se pueden empaquetar con el modelo a través de la biblioteca Python de metadatos. El nuevo modelo de TensorFlow Lite se convierte en un archivo zip que contiene tanto el modelo como los archivos asociados. Se puede desembalar con herramientas zip comunes. Este nuevo formato de modelo sigue usando la misma extensión de archivo, .tflite . Es compatible con el intérprete y el framework TFLite existente. Consulte Empaquetar mtadatos y archivos asociados en el modelo para obtener más detalles.

La información del archivo asociado se puede registrar en los metadatos. Según el tipo de archivo y dónde se adjunta el archivo (es decir, ModelMetadata , SubGraphMetadata y TensorMetadata ), el generador de código de Android TensorFlow Lite puede aplicar el procesamiento previo / posterior correspondiente automáticamente al objeto. Consulte la sección <Uso de Codegen> de cada tipo de archivo asociado en el esquema para obtener más detalles.

Parámetros de normalización y cuantificación

La normalización es una técnica de preprocesamiento de datos común en el aprendizaje automático. El objetivo de la normalización es cambiar los valores a una escala común, sin distorsionar las diferencias en los rangos de valores.

La cuantificación del modelo es una técnica que permite representaciones de pesos de precisión reducida y, opcionalmente, activaciones tanto para el almacenamiento como para el cálculo.

En términos de preprocesamiento y posprocesamiento, la normalización y la cuantificación son dos pasos independientes. Aquí están los detalles.

Normalización Cuantización

Un ejemplo de los valores de los parámetros de la imagen de entrada en MobileNet para modelos flotantes y cuantitativos, respectivamente.
Modelo de flotador :
- media: 127,5
- estándar: 127,5
Modelo cuantico :
- media: 127,5
- estándar: 127,5
Modelo de flotador :
- zeroPoint: 0
- escala: 1.0
Modelo cuantico :
- zeroPoint: 128.0
- escala: 0.0078125f




¿Cuándo invocar?


Entradas : si los datos de entrada se normalizan en el entrenamiento, los datos de entrada de inferencia deben normalizarse en consecuencia.
Salidas : los datos de salida no se normalizarán en general.
Los modelos flotantes no necesitan cuantificación.
El modelo cuantificado puede necesitar o no cuantificación en el pre / post procesamiento. Depende del tipo de datos de los tensores de entrada / salida.
- Tensores de flotación: no se necesita cuantificación en pre / post procesamiento. La operación cuántica y la operación decuante se incorporan al gráfico del modelo.
- Tensores int8 / uint8: necesitan cuantificación en pre / post procesamiento.


Fórmula


normalized_input = (entrada - media) / std
Cuantizar para entradas :
q = f / escala + punto cero
Descuantizar para salidas :
f = (q - zeroPoint) * escala

¿Dónde están los parámetros?
Completado por el creador del modelo y almacenado en metadatos del modelo, como NormalizationOptions Completado automáticamente por el convertidor TFLite y almacenado en el archivo de modelo tflite.
¿Cómo obtener los parámetros? A través de la API MetadataExtractor [2] A través de la API TFLite Tensor [1] o mediante la API MetadataExtractor [2]
¿Los modelos flotantes y cuantitativos comparten el mismo valor? Sí, los modelos flotantes y cuantitativos tienen los mismos parámetros de normalización No, el modelo flotante no necesita cuantificación.
¿El generador de código TFLite o el enlace de Android Studio ML lo generan automáticamente en el procesamiento de datos?

[1] La API de Java de TensorFlow Lite y la API de C ++ de TensorFlow Lite .
[2] La biblioteca de extractores de metadatos

Al procesar datos de imagen para modelos uint8, a veces se omiten la normalización y la cuantificación. Está bien hacerlo cuando los valores de los píxeles están en el rango de [0, 255]. Pero, en general, siempre debe procesar los datos de acuerdo con los parámetros de normalización y cuantificación cuando corresponda.

Ejemplos de

Puede encontrar ejemplos sobre cómo se deben completar los metadatos para diferentes tipos de modelos aquí:

Clasificación de imágenes

Descargue el script aquí , que completa los metadatos en mobilenet_v1_0.75_160_quantized.tflite . Ejecute el script así:

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

Para completar metadatos para otros modelos de clasificación de imágenes, agregue las especificaciones del modelo como esta en el script. El resto de esta guía destacará algunas de las secciones clave en el ejemplo de clasificación de imágenes para ilustrar los elementos clave.

Profundice en el ejemplo de clasificación de imágenes

Información del modelo

Los metadatos comienzan creando una nueva información de modelo:

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.")

Información de entrada / salida

Esta sección le muestra cómo describir la firma de entrada y salida de su modelo. Estos metadatos pueden ser utilizados por generadores de código automáticos para crear código de procesamiento previo y posterior. Para crear información de entrada o salida sobre un tensor:

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

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

Entrada de imagen

La imagen es un tipo de entrada común para el aprendizaje automático. Los metadatos de TensorFlow Lite admiten información como el espacio de color y la información de procesamiento previo, como la normalización. La dimensión de la imagen no requiere una especificación manual, ya que la forma del tensor de entrada ya la proporciona y se puede inferir automáticamente.

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

Salida de etiqueta

La etiqueta se puede asignar a un tensor de salida a través de un archivo asociado usando 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]

Crear los búferes planos de metadatos

El siguiente código combina la información del modelo con la información de entrada y salida:

# 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()

Empaquetar metadatos y archivos asociados en el modelo

Una vez creado el Flatbuffers de metadatos, los metadatos y el archivo de etiquetas se escriben en el archivo TFLite a través de la populate método:

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()

Puede empaquetar tantos archivos asociados como desee en el modelo a través de load_associated_files . Sin embargo, es necesario empaquetar al menos los archivos documentados en los metadatos. En este ejemplo, es obligatorio empaquetar el archivo de etiquetas.

Visualiza los metadatos

Puede usar Netron para visualizar sus metadatos, o puede leer los metadatos de un modelo de TensorFlow Lite en un formato json usando 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 también admite la visualización de metadatos a través de la función de enlace ML de Android Studio .

Control de versiones de metadatos

El esquema de metadatos está versionado tanto por el número de versión semántico, que rastrea los cambios del archivo de esquema, como por la identificación del archivo Flatbuffers, que indica la verdadera compatibilidad de la versión.

El número de versión semántica

El esquema de metadatos está versionado por el número de versión semántico , como MAJOR.MINOR.PATCH. Realiza un seguimiento de los cambios de esquema de acuerdo con las reglas aquí . Consulte el historial de campos agregados después de la versión 1.0.0 .

La identificación del archivo Flatbuffers

El versionado semántico garantiza la compatibilidad si se siguen las reglas, pero no implica la verdadera incompatibilidad. Al aumentar el número PRINCIPAL, no significa necesariamente que la compatibilidad con versiones anteriores esté rota. Por lo tanto, utilizamos la identificación de archivo Flatbuffers , file_identifier , para indicar la verdadera compatibilidad del esquema de metadatos. El identificador de archivo tiene exactamente 4 caracteres. Está fijado a un determinado esquema de metadatos y no está sujeto a cambios por parte de los usuarios. Si la compatibilidad con versiones anteriores del esquema de metadatos tiene que romperse por algún motivo, el identificador de archivo aumentará, por ejemplo, de “M001” a “M002”. Se espera que File_identifier se cambie con mucha menos frecuencia que metadata_version.

La versión mínima necesaria del analizador de metadatos

La versión mínima necesaria del analizador de metadatos es la versión mínima del analizador de metadatos (el código generado por Flatbuffers) que puede leer los metadatos Flatbuffers en su totalidad. La versión es efectivamente el número de versión más grande entre las versiones de todos los campos rellenados y la versión compatible más pequeña indicada por el identificador de archivo. MetadataPopulator completa automáticamente la versión mínima necesaria del analizador de MetadataPopulator cuando los metadatos se completan en un modelo TFLite. Consulte el extractor de metadatos para obtener más información sobre cómo se utiliza la versión mínima necesaria del analizador de metadatos.

Leer los metadatos de los modelos

La biblioteca Metadata Extractor es una herramienta conveniente para leer los metadatos y los archivos asociados de un modelo en diferentes plataformas (consulte la versión de Java y la versión de C ++ ). Puede crear su propia herramienta de extracción de metadatos en otros idiomas utilizando la biblioteca Flatbuffers.

Leer los metadatos en Java

Para usar la biblioteca Metadata Extractor en su aplicación de Android, recomendamos usar el AAR de metadatos de TensorFlow Lite alojado en MavenCentral . Contiene la clase MetadataExtractor , así como los enlaces Java FlatBuffers para el esquema de metadatos y el esquema del modelo .

Puede especificar esto en sus dependencias de build.gradle siguiente manera:

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

Para usar instantáneas nocturnas, asegúrese de haber agregado el repositorio de instantáneas de Sonatype .

Puede inicializar un objeto MetadataExtractor con un ByteBuffer que apunte al modelo:

public MetadataExtractor(ByteBuffer buffer);

El ByteBuffer debe permanecer sin cambios durante toda la vida útil del objeto MetadataExtractor . La inicialización puede fallar si el identificador de archivo Flatbuffers de los metadatos del modelo no coincide con el del analizador de metadatos. Consulte Control de versiones de metadatos para obtener más información.

Con identificadores de archivo coincidentes, el extractor de metadatos leerá con éxito los metadatos generados a partir de todos los esquemas pasados ​​y futuros debido al mecanismo de compatibilidad hacia adelante y hacia atrás de Flatbuffers. Sin embargo, los extractores de metadatos más antiguos no pueden extraer campos de esquemas futuros. La versión mínima necesaria del analizador de los metadatos indica la versión mínima del analizador de metadatos que puede leer los Flatbuffers de metadatos en su totalidad. Puede utilizar el siguiente método para verificar si se cumple la condición mínima necesaria de la versión del analizador:

public final boolean isMinimumParserVersionSatisfied();

Se permite pasar un modelo sin metadatos. Sin embargo, la invocación de métodos que leen de los metadatos provocará errores en tiempo de ejecución. Puede verificar si un modelo tiene metadatos invocando el método hasMetadata :

public boolean hasMetadata();

MetadataExtractor proporciona funciones convenientes para que usted obtenga los metadatos de los tensores de entrada / salida. Por ejemplo,

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);

Aunque el esquema del modelo de TensorFlow Lite admite varios subgráficos, el intérprete de TFLite actualmente solo admite un único subgráfico. Por lo tanto, MetadataExtractor omite el índice de subgráfico como argumento de entrada en sus métodos.

Leer los archivos asociados de los modelos

El modelo de TensorFlow Lite con metadatos y archivos asociados es esencialmente un archivo zip que se puede descomprimir con herramientas zip comunes para obtener los archivos asociados. Por ejemplo, puede descomprimir mobilenet_v1_0.75_160_quantized y extraer el archivo de etiqueta en el modelo de la siguiente manera:

$ 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

También puede leer archivos asociados a través de la biblioteca Metadata Extractor.

En Java, pase el nombre del archivo al método MetadataExtractor.getAssociatedFile :

public InputStream getAssociatedFile(String fileName);

De manera similar, en C ++, esto se puede hacer con el método ModelMetadataExtractor::GetAssociatedFile :

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