Ajouter des métadonnées aux modèles TensorFlow Lite

Les métadonnées TensorFlow Lite fournissent une norme pour les descriptions de modèles. La les métadonnées sont une importante source de connaissances sur le fonctionnement du modèle et sur ses des informations d'entrée / de sortie. Les métadonnées comprennent à la fois

Tous les modèles d'images publiés sur Kaggle les modèles ont été renseignés avec de métadonnées.

Modèle avec format de métadonnées

model_with_metadata
Figure 1 Modèle TFLite avec les métadonnées et les fichiers associés.

Les métadonnées du modèle sont définies metadata_schema.fbs un FlatBuffer . Comme le montre la figure 1, il est stocké dans la métadonnées du modèle TFLite d'entraînement, sous le nom "TFLITE_METADATA". Certains modèles peuvent être associés à des fichiers, par exemple étiquette de classification fichiers. Ces fichiers sont concaténés à la fin du fichier de modèle d'origine sous forme de fichier ZIP à l'aide du fichier ZipFile "append" (mode 'a'). TFLite L'interpréteur peut utiliser le nouveau format de fichier de la même manière qu'auparavant. Voir Pack les fichiers associés.

Consultez les instructions ci-dessous pour découvrir comment renseigner, visualiser et lire les métadonnées.

Configurer les outils de métadonnées

Avant d'ajouter des métadonnées à votre modèle, vous devez utiliser un langage de programmation Python pour exécuter TensorFlow. Il existe un guide détaillé sur la façon de cliquez ici pour configurer cela.

Après avoir configuré l'environnement de programmation Python, vous devez installer des outils supplémentaires:

pip install tflite-support

Les outils de métadonnées TensorFlow Lite sont compatibles avec Python 3.

Ajouter des métadonnées à l'aide de l'API Python Flatbuffers

La section "Présentation du modèle" contient trois parties schema:

  1. Informations sur le modèle : description générale du modèle et des articles. telles que les conditions de licence. Voir ModelMetadata :
    1. Informations d'entrée : description des entrées et du prétraitement comme la normalisation. Voir SubGraphMetadata.input_tensor_metadata :
      1. Informations sur le résultat : description du résultat et post-traitement requis, par exemple un mappage sur des étiquettes. Voir SubGraphMetadata.output_tensor_metadata :

Comme TensorFlow Lite n'accepte qu'un seul sous-graphe pour le moment, Générateur de code TensorFlow Lite et l'API Android Studio ML Binding fonctionnalité utilisera ModelMetadata.name et ModelMetadata.description, au lieu de SubGraphMetadata.name et SubGraphMetadata.description, lors de l'affichage les métadonnées et la génération de code.

Types d'entrées / sorties compatibles

Les métadonnées TensorFlow Lite pour les entrées et les sorties ne sont pas conçues avec des types de modèles à l'esprit, mais plutôt que les types d'entrée et de sortie. Peu importe ce que fonctionnellement du modèle, tant que les types d'entrée et de sortie sont les éléments suivants ou une combinaison des suivants, ils sont compatibles avec TensorFlow Métadonnées Lite:

  • Fonctionnalité - Nombres qui sont des entiers non signés ou des valeurs float32.
  • Image : les métadonnées sont actuellement compatibles avec les images RVB et en niveaux de gris.
  • Cadre de délimitation : cadres de délimitation de forme rectangulaire. Le schéma accepte variété de numérotation méthodologies.

Empaqueter les fichiers associés

Les modèles TensorFlow Lite peuvent être associés à différents fichiers. Par exemple : Les modèles de langage naturel comportent généralement des fichiers de vocabulaire qui mappent des morceaux de mots à des mots Identifiants les modèles de classification peuvent comporter des fichiers de libellés indiquant des catégories d'objets. Sans les fichiers associés (s'il y en a), un modèle ne fonctionnera pas correctement.

Les fichiers associés peuvent désormais être regroupés avec le modèle par le biais des métadonnées bibliothèque Python. Le nouveau modèle TensorFlow Lite devient un fichier ZIP contenant le modèle et les fichiers associés. Il peut être décompressé à l'aide du code outils. Ce nouveau format de modèle continue à utiliser la même extension de fichier, .tflite. Il est compatible avec le framework et l'interpréteur TFLite existants. Voir Métadonnées des packs et les fichiers associés modèle pour en savoir plus.

Les informations du fichier associé peuvent être enregistrées dans les métadonnées. En fonction de le type de fichier et l'emplacement auquel il est joint (par exemple, ModelMetadata, SubGraphMetadata et TensorMetadata), le code Android TensorFlow Lite le générateur peut appliquer les modifications automatiquement à l'objet. Consultez la section <Codegen usage> de chaque fichier associé d'entraînement dans le schéma pour en savoir plus.

Paramètres de normalisation et de quantification

La normalisation est une technique courante de prétraitement des données dans le machine learning. La l'objectif de la normalisation est de remplacer les valeurs par une échelle commune de distorsion des différences dans les plages de valeurs.

La quantification de modèle est une technique qui permet de représenter les pondérations avec une précision réduite. pour le stockage et le calcul.

En ce qui concerne le prétraitement et le post-traitement, la normalisation et la quantification sont deux étapes indépendantes. Voici les informations détaillées relatives à cet incident.

Normalization Quantification

Un exemple de des valeurs de paramètres image d'entrée dans MobileNet pour float et des modèles quantitatifs, respectivement.
Modèle à virgule flottante:
- moyenne: 127,5
- standard: 127,5
Modèle de quantification:
- moyenne: 127,5
- std: 127,5
Modèle à virgule flottante:
- zeroPoint: 0
- Échelle: 1,0
Modèle de quantification:
- zeroPoint: 128,0
- scale:0.0078125f




Quand appeler ?


Inputs (Entrées) : si l'entrée les données sont normalisées dans l'entraînement, l'entrée de données nécessaires à l'inférence à normaliser en conséquence.
Sorties: sortie les données ne seront pas normalisé en général.
Les modèles float pas besoin de quantification.
Le modèle quantifié peut ou n'ont peut-être pas besoin la quantification avant/après en cours de traitement. Cela dépend sur le type de données les Tensors d'entrée/de sortie.
- Tensors à virgule flottante: non la quantification avant/après le traitement requis. Quant "op" et "dequant op" intégrées au modèle graphique.
- Tensors int8/uint8: besoin d'une quantification avant ou après le traitement.


Formule


normalized_input = (entrée - moyenne) / std
Quantifier les entrées:
q = f / échelle + zeroPoint
Déquantifier pour résultats:
f = (q - zeroPoint) * échelle

Où se trouvent les paramètres
Rempli par le créateur du modèle et stockées dans le modèle de métadonnées, telles que NormalizationOptions Rempli automatiquement par convertisseur TFLite stocké dans un modèle tflite .
Comment obtenir ? Grâce aux API MetadataExtractor [2]. Via le TFLite API Tensor [1] ou via le API MetadataExtractor [2].
Flouter et quantifier partagent le même ? Oui, float et quant ont le même rôle Normalisation paramètres Non, le modèle float pas besoin de quantification.
Est-ce que TFLite Code ou Android Liaison ML dans Studio générer automatiquement lors du traitement des données ?
Oui

Oui

[1] Le modèle TensorFlow Lite Java API et la bibliothèque TensorFlow Lite C++ API.
[2] La bibliothèque d'extracteurs de métadonnées

Lors du traitement des données d'image pour les modèles uint8, la normalisation et la quantification sont parfois ignorés. Cela ne pose pas de problème lorsque les valeurs en pixels sont comprises dans la plage [0, 255]. Mais en général, vous devez toujours traiter les données conformément de normalisation et de quantification, le cas échéant.

Exemples

Vous trouverez des exemples sur la façon dont les métadonnées doivent être renseignées pour différentes types de modèles ici:

Classification d'images

Télécharger le script cliquez ici , qui renseigne les métadonnées sur mobilenet_v1_0.75_160_quantized.tflite. Exécutez le script comme suit:

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

Pour insérer les métadonnées d'autres modèles de classification d'images, ajoutez les spécifications du modèle "J'aime" ce dans le script. Le reste de ce guide aborde certaines des sections clés dans l'exemple de classification d'images pour illustrer les éléments clés.

Présentation détaillée de l'exemple de classification d'images

Informations relatives au modèle

Les métadonnées commencent par créer les informations du modèle:

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

Informations d'entrée / de sortie

Cette section vous explique comment décrire la signature d'entrée et de sortie de votre modèle. Ces métadonnées peuvent être utilisées par les générateurs de code automatiques pour créer des du code de traitement. Pour créer des informations d'entrée ou de sortie concernant un Tensor, procédez comme suit:

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

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

Saisie d'image

L'image est un type d'entrée courant pour le machine learning. Métadonnées TensorFlow Lite prend en charge des informations telles que l'espace colorimétrique et des informations de prétraitement, normalisation. La dimension de l'image ne nécessite pas de spécification manuelle. puisqu'il est déjà fourni par la forme du Tensor d'entrée et peut être automatiquement.

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

Sortie d'étiquette

L'étiquette peut être mappée à un Tensor de sortie via un fichier associé en utilisant 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]

Créer les Flatbuffers de métadonnées

Le code suivant combine les informations du modèle avec les entrées et les sorties informations:

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

Empaqueter les métadonnées et les fichiers associés dans le modèle

Une fois les Flatbuffers de métadonnées créés, les métadonnées et le fichier d'étiquettes sont est écrite dans le fichier TFLite via la méthode 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()

Vous pouvez empaqueter autant de fichiers associés que vous le souhaitez dans le modèle via load_associated_files Cependant, il est nécessaire d'empaqueter au moins ces fichiers documentées dans les métadonnées. Dans cet exemple, l'empaquetage du fichier d'étiquette est obligatoire.

Visualiser les métadonnées

Vous pouvez utiliser Netron pour visualiser ou lire les métadonnées d'un modèle TensorFlow Lite dans un à l'aide de 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 permet également d'afficher des métadonnées via Android Studio ML Liaison fonctionnalité.

Gestion des versions des métadonnées

Les métadonnées schéma est versionnée à la fois par le numéro de gestion sémantique des versions, qui suit les modifications le fichier de schéma et par l'identification du fichier Flatbuffers, qui indique véritable compatibilité des versions.

Numéro de gestion sémantique des versions

La gestion des versions du schéma de métadonnées est assurée par la gestion sémantique des versions numéro, comme MAJEURE.MINEURE.PATCH. Il suit les modifications de schéma selon les règles cliquez ici. Voir l'historique de Champs ajoutée après la version 1.0.0.

Identification du fichier Flatbuffers

La gestion sémantique des versions garantit la compatibilité en respectant les règles, n'implique pas la véritable incompatibilité. En accumulant le chiffre MAJEUR, ne signifie pas nécessairement que la rétrocompatibilité est rompue. Par conséquent, nous utilisez le fichier Flatbuffers l'identification, file_identifier, pour indiquer la véritable compatibilité du schéma de métadonnées. L'identifiant du fichier est ne doit pas comporter plus de 4 caractères. Il est fixé à un certain schéma de métadonnées et n'est pas sont susceptibles d'être modifiées par les utilisateurs. Si la rétrocompatibilité du schéma de métadonnées doit être rompue pour une raison quelconque, l'identifiant de fichier sera renvoyé, par exemple, de "M001" à "M002". File_identifier devrait être modifié beaucoup moins plus fréquemment que "metadata_version".

Version minimale de l'analyseur de métadonnées nécessaire

L'analyseur de métadonnées minimal nécessaire version est la version minimale de l'analyseur de métadonnées (le code généré par Flatbuffers) qui peut lire les Flatbuffers de métadonnées dans leur intégralité. La version est en fait la numéro de version le plus élevé parmi les versions de tous les champs renseignés et la plus petite version compatible indiquée par l'identifiant du fichier. Le minimum la version de l'analyseur de métadonnées nécessaire est automatiquement renseignée par MetadataPopulator lorsque les métadonnées sont renseignées dans un modèle TFLite. Consultez le extracteur de métadonnées pour savoir comment la version minimale de l'analyseur de métadonnées nécessaire est utilisée.

Lire les métadonnées à partir des modèles

La bibliothèque Metadata Extractor est un outil pratique pour lire les métadonnées et les fichiers associés à partir d'un modèle sur différentes plates-formes (voir la documentation version et le langage C++ ). Vous pouvez créer votre propre outil d'extraction de métadonnées dans d'autres langages à l'aide du Flatbuffers.

Lire les métadonnées en Java

Pour utiliser la bibliothèque d'extracteurs de métadonnées dans votre application Android, nous vous recommandons d'utiliser l'AAR de métadonnées TensorFlow Lite, hébergée sur MavenCentral. Elle contient la classe MetadataExtractor, ainsi que la classe Java FlatBuffers. des liaisons pour les métadonnées schéma et le modèle de base.

Vous pouvez le spécifier dans vos dépendances build.gradle comme suit:

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

Pour utiliser des instantanés nocturnes, assurez-vous d'avoir ajouté l'instantané Sonatype un dépôt de clés.

Vous pouvez initialiser un objet MetadataExtractor avec un ByteBuffer qui pointe au modèle:

public MetadataExtractor(ByteBuffer buffer);

Le ByteBuffer doit rester inchangé pendant toute la durée de vie du MetadataExtractor. L'initialisation peut échouer si le fichier Flatbuffers l'identifiant des métadonnées du modèle ne correspond pas à celui de l'analyseur de métadonnées. Voir gestion des versions des métadonnées.

Avec des identifiants de fichiers correspondants, l'extracteur de métadonnées lit de métadonnées générées à partir de tous les schémas passés et futurs en raison des Flatbuffers de rétrocompatibilité. Cependant, les champs des futurs les schémas ne peuvent pas être extraits par les extracteurs de métadonnées plus anciens. Le minimum version de l'analyseur des métadonnées indique la version minimale de l'analyseur de métadonnées capable de lire les métadonnées Flatbuffers plein. Vous pouvez utiliser la méthode suivante pour vérifier si le minimum la condition requise de la version de l'analyseur est remplie:

public final boolean isMinimumParserVersionSatisfied();

La transmission d'un modèle sans métadonnées est autorisée. Toutefois, l'appel de méthodes les données lues à partir des métadonnées provoquent des erreurs d'exécution. Vous pouvez vérifier si un modèle métadonnées en appelant la méthode hasMetadata:

public boolean hasMetadata();

MetadataExtractor fournit des fonctions pratiques pour obtenir Tensors d'entrée/de sortie de métadonnées. Par exemple,

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

Bien que le modèle TensorFlow Lite schéma prend en charge plusieurs sous-graphiques, l'interpréteur TFLite n'accepte actuellement un sous-graphique unique. Par conséquent, MetadataExtractor omet l'index du sous-graphe comme entrée dans ses méthodes.

Lire les fichiers associés à partir des modèles

Le modèle TensorFlow Lite avec des métadonnées et des fichiers associés est zip qui peut être décompressé à l'aide d'outils zip courants pour obtenir les fichiers associés. Par exemple, vous pouvez décompresser mobilenet_v1_0.75_160_quantized puis extrayez le fichier d'étiquettes du modèle comme suit:

$ 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

Vous pouvez également lire les fichiers associés via la bibliothèque d'extracteurs de métadonnées.

En Java, transmettez le nom du fichier à MetadataExtractor.getAssociatedFile. méthode:

public InputStream getAssociatedFile(String fileName);

De même, en C++, cela peut être fait avec la méthode, ModelMetadataExtractor::GetAssociatedFile:

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