Hinzufügen von Metadaten zu TensorFlow Lite-Modellen

TensorFlow Lite-Metadaten bieten einen Standard für Modellbeschreibungen. Die Metadaten sind eine wichtige Wissensquelle über die Funktionsweise des Modells und seine Eingabe-/Ausgabeinformationen. Die Metadaten bestehen aus beidem

Alle Bilder Modelle auf veröffentlichten TensorFlow Lite gehosteten Modelle und TensorFlow Hub hat mit Metadaten besiedelt.

Modell mit Metadatenformat

model_with_metadata
Abbildung 1. TFLite-Modell mit Metadaten und zugehörigen Dateien.

Modell Metadaten werden in definierten metadata_schema.fbs , eine FlatBuffer Datei. Wie in 1 gezeigt ist , ist es in dem gespeicherten Metadatenfeld des TFLite Modellschemas , unter dem Namen "TFLITE_METADATA" . Einige Modelle können kommen mit zugehörigen Dateien, wie Klassifizierung Etikettendateien . Diese Dateien werden bis zum Ende der ursprünglichen Modelldatei verknüpft als ZIP den ZipFile mit „append“ -Modus ( 'a' Modus). TFLite Interpreter kann das neue Dateiformat auf die gleiche Weise wie zuvor verarbeiten. Siehe Packung der zugehörigen Dateien für weitere Informationen.

Weitere Informationen zum Auffüllen, Visualisieren und Lesen von Metadaten finden Sie unten.

Richten Sie die Metadaten-Tools ein

Bevor Sie Ihrem Modell Metadaten hinzufügen, müssen Sie eine Python-Programmierumgebung einrichten, um TensorFlow auszuführen. Es gibt eine detaillierte Anleitung, wie man dies einzurichten hier .

Nachdem Sie die Python-Programmierumgebung eingerichtet haben, müssen Sie zusätzliche Tools installieren:

pip install tflite-support

Die Metadatentools von TensorFlow Lite unterstützen Python 3.

Hinzufügen von Metadaten mit der Flatbuffers Python API

Es gibt drei Teile zum Modell Metadaten im Schema :

  1. Modellinformationen - Allgemeine Beschreibung des Modells sowie Gegenstände wie Lizenzbedingungen. Siehe ModelMetadata .
  2. Eingabeinformationen - Beschreibung der Ein- und Vorverarbeitung erforderlich , wie beispielsweise Normalisierung. Siehe SubGraphMetadata.input_tensor_metadata .
  3. Ausgabeinformationen - Beschreibung der Ausgang und Nachverarbeitung erforderlich ist, wie beispielsweise Mapping auf Etiketten. Siehe SubGraphMetadata.output_tensor_metadata .

Da nur TensorFlow Lite einzelne Subgraphen an diesem Punkt unterstützt, der TensorFlow Lite - ModelMetadata.name ModelMetadata.description SubGraphMetadata.name SubGraphMetadata.description Code - Generator und die Android Studio ML Binding - Funktion werden verwenden ModelMetadata.name und ModelMetadata.description , statt SubGraphMetadata.name und SubGraphMetadata.description , wenn Metadaten Anzeige und Code - Generierung.

Unterstützte Eingabe-/Ausgabetypen

TensorFlow Lite-Metadaten für Eingabe und Ausgabe wurden nicht mit Blick auf bestimmte Modelltypen entwickelt, sondern eher für Eingabe- und Ausgabetypen. Es spielt keine Rolle, was das Modell funktional macht, solange die Eingabe- und Ausgabetypen aus den folgenden oder einer Kombination der folgenden bestehen, wird es von TensorFlow Lite-Metadaten unterstützt:

  • Feature - Zahlen, die vorzeichenlose Ganzzahlen oder float32 sind.
  • Bild - Metadaten unterstützen derzeit RGB- und Graustufenbilder.
  • Begrenzungsrahmen - Rechteckige Begrenzungsrahmen. Das Schema unterstützt eine Vielzahl von Nummernschemata .

Packen Sie die zugehörigen Dateien

TensorFlow Lite-Modelle können mit verschiedenen zugehörigen Dateien geliefert werden. Zum Beispiel verfügen natürliche Sprachmodelle normalerweise über Vokabeldateien, die Wortteile Wort-IDs zuordnen; Klassifizierungsmodelle können Etikettendateien haben, die Objektkategorien angeben. Ohne die zugehörigen Dateien (sofern vorhanden) wird ein Modell nicht gut funktionieren.

Die zugehörigen Dateien können nun über die Metadaten-Python-Bibliothek mit dem Modell gebündelt werden. Das neue TensorFlow Lite-Modell wird zu einer ZIP-Datei, die sowohl das Modell als auch die zugehörigen Dateien enthält. Es kann mit gängigen Zip-Tools entpackt werden. Dieses neue Modell Format behält die gleiche Dateierweiterung, .tflite . Es ist mit dem bestehenden TFLite-Framework und Interpreter kompatibel. Siehe Pack - Metadaten und zugehörige Dateien in das Modell für weitere Details.

Die zugehörigen Dateiinformationen können in den Metadaten festgehalten werden. Je nach Dateityp und in dem die Datei angehängt wird (dh ModelMetadata , SubGraphMetadata und TensorMetadata ), der TensorFlow Lite Android - Code - Generator anwenden kann auf das Objekt automatisch Pre / Post - Verarbeitung. Siehe den <Codegen Nutzung> Abschnitt jeden assoziierten Dateitypen in dem Schema für weitere Details.

Normalisierungs- und Quantisierungsparameter

Die Normalisierung ist eine gängige Datenvorverarbeitungstechnik beim maschinellen Lernen. Das Ziel der Normalisierung besteht darin, die Werte auf eine gemeinsame Skala zu ändern, ohne Unterschiede in den Wertebereichen zu verzerren.

Modell Quantisierung ist eine Technik , die für reduzierte Präzision Darstellungen von Gewichten und optional Aktivierungen für beide Speicher und Berechnung ermöglicht.

Hinsichtlich der Vorverarbeitung und Nachverarbeitung sind Normalisierung und Quantisierung zwei unabhängige Schritte. Hier sind die Details.

Normalisierung Quantisierung

Ein Beispiel für die Parameterwerte des Eingabebilds in MobileNet für Float- bzw. Quant-Modelle.
Float - Modell:
- Mittelwert: 127,5
- Standard: 127,5
Quant - Modell:
- Mittelwert: 127,5
- Standard: 127,5
Float - Modell:
- Nullpunkt: 0
- Skala: 1.0
Quant - Modell:
- Nullpunkt: 128.0
- Skala: 0,0078125f




Wann aufrufen?


Eingänge: Wenn Eingangsdaten in der Ausbildung normiert ist, entsprechend werden die Eingangsdaten des Schließens Bedürfnisse normalisiert.
Ausgänge: Ausgangsdaten werden im allgemeinen nicht normalisiert werden.
Float - Modelle benötigen keine Quantisierung.
Quantisiert Modell kann oder nicht Quantisierung in Pre / Post - Verarbeitung benötigen. Dies hängt vom Datentyp der Eingabe-/Ausgabe-Tensoren ab.
- Float-Tensoren: keine Quantisierung in der Vor-/Nachbearbeitung erforderlich. Quant op und dequant op werden in den Modellgraphen eingebrannt.
- int8/uint8-Tensoren: benötigen Quantisierung in der Vor-/Nachbearbeitung.


Formel


normalized_input = (Eingabe - Mittelwert) / std
Quantisieren für die Eingänge:
q = f / Skala + Nullpunkt
Dequantisieren für Ausgänge:
f = (q - Nullpunkt) * Skala

Wo sind die Parameter
Gefüllt nach Modell Schöpfer und in Modell - Metadaten gespeichert, wie NormalizationOptions Wird automatisch vom TFLite-Konverter gefüllt und in der TFLite-Modelldatei gespeichert.
Wie bekomme ich die Parameter? Durch den MetadataExtractor API [2] Durch die TFLite Tensor API [1] oder durch den MetadataExtractor API [2]
Haben Float- und Quant-Modelle denselben Wert? Ja, Float- und Quant-Modelle haben die gleichen Normalisierungsparameter Nein, das Float-Modell benötigt keine Quantisierung.
Generiert der TFLite-Codegenerator oder die Android Studio ML-Bindung automatisch bei der Datenverarbeitung?
Jawohl

Jawohl

[1] Die TensorFlow Lite Java API und die TensorFlow Lite C ++ API .
[2] Die Metadaten - Extraktor Bibliothek

Bei der Verarbeitung von Bilddaten für uint8-Modelle werden Normalisierung und Quantisierung manchmal übersprungen. Dies ist in Ordnung, wenn die Pixelwerte im Bereich von [0, 255] liegen. Im Allgemeinen sollten Sie die Daten jedoch immer gemäß den Normalisierungs- und Quantisierungsparametern verarbeiten, sofern zutreffend.

TensorFlow Lite Taskbibliothek kann Normalisierung für Sie handhaben, wenn Sie einrichten NormalizationOptions in Metadaten. Die Quantisierungs- und Dequantisierungsverarbeitung ist immer gekapselt.

Beispiele

Beispiele dafür, wie die Metadaten für verschiedene Modelltypen ausgefüllt werden sollten, finden Sie hier:

Bildklassifizierung

Laden Sie das Skript hier , das Füllen von Metadaten mobilenet_v1_0.75_160_quantized.tflite . Führen Sie das Skript wie folgt aus:

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

So füllen Sie Metadaten für andere Bildklassifizierungsmodelle, fügen Sie die Modelldaten wie diese in das Skript. Im Rest dieses Handbuchs werden einige der Schlüsselabschnitte im Beispiel zur Bildklassifizierung hervorgehoben, um die Schlüsselelemente zu veranschaulichen.

Tauchen Sie ein in das Beispiel für die Bildklassifizierung

Modellinformationen

Metadaten beginnen mit der Erstellung einer neuen Modellinfo:

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

Eingabe- / Ausgabeinformationen

In diesem Abschnitt erfahren Sie, wie Sie die Eingabe- und Ausgabesignatur Ihres Modells beschreiben. Diese Metadaten können von automatischen Codegeneratoren verwendet werden, um Vor- und Nachbearbeitungscode zu erstellen. So erstellen Sie Eingabe- oder Ausgabeinformationen zu einem Tensor:

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

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

Bildeingabe

Bild ist ein gängiger Eingabetyp für maschinelles Lernen. TensorFlow Lite-Metadaten unterstützen Informationen wie den Farbraum und Vorverarbeitungsinformationen wie die Normalisierung. Die Dimension des Bildes erfordert keine manuelle Angabe, da sie bereits durch die Form des Eingabetensors vorgegeben wird und automatisch abgeleitet werden kann.

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

Etikettenausgabe

Label kann über eine zugehörige Datei mit einem Ausgang Tensor abgebildet wird 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]

Erstellen Sie die Metadaten-Flatbuffers

Der folgende Code kombiniert die Modellinformationen mit den Eingabe- und Ausgabeinformationen:

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

Packen Sie Metadaten und zugehörige Dateien in das Modell

Sobald die Metadaten Flatbuffers erstellt wird, werden die Metadaten und die Etikettendatei über die in die Datei geschrieben TFLite populate Methode:

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

Sie können so viele zugehörigen Dateien packen , wie Sie in das Modell durch wollen load_associated_files . Es ist jedoch erforderlich, mindestens die in den Metadaten dokumentierten Dateien zu packen. In diesem Beispiel ist das Packen der Etikettendatei obligatorisch.

Visualisieren Sie die Metadaten

Sie können mit Netron Ihre Metadaten zu visualisieren, oder Sie können die Metadaten aus einem TensorFlow Lite - Modell in ein JSON - Format mit dem Lesen 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 unterstützt auch Metadaten durch die Anzeige von Android Studio ML Binding - Funktion .

Versionierung von Metadaten

Das Metadatenschema versioniert sowohl durch die Semantic Versionsnummer, die die Änderungen der Schemadatei verfolgt und durch die Flatbuffers Datei Identifizierung, die die wahre Version Kompatibilität anzeigt.

Die semantische Versionsnummer

Das Metadatenschema wird durch die versioniert Semantic Versionsnummer , wie MAJOR.MINOR.PATCH. Es verfolgt Schemaänderungen nach den Regeln hier . Sehen Sie sich die Geschichte der Felder hinzugefügt , nachdem Version 1.0.0 .

Die Flatbuffers-Dateiidentifikation

Die semantische Versionierung garantiert die Kompatibilität, wenn die Regeln befolgt werden, aber sie impliziert nicht die wahre Inkompatibilität. Wenn Sie die MAJOR-Nummer erhöhen, bedeutet dies nicht unbedingt, dass die Abwärtskompatibilität unterbrochen ist. Daher verwenden wir die Flatbuffers Datei Identifizierung , file_identifier , die wahre Kompatibilität des Metadatenschemas zu bezeichnen. Die Dateikennung ist genau 4 Zeichen lang. Es ist auf ein bestimmtes Metadatenschema festgelegt und kann von Benutzern nicht geändert werden. Wenn die Abwärtskompatibilität des Metadatenschemas aus irgendeinem Grund gebrochen werden muss, wird der file_identifier beispielsweise von „M001“ auf „M002“ hochgestuft. Es wird erwartet, dass File_identifier viel seltener geändert wird als die metadata_version.

Die minimal erforderliche Metadaten-Parser-Version

Die minimal notwendige Metadaten - Parser - Version ist die Mindestversion von Metadaten - Parser (die Flatbuffers generierten Code), der die Metadaten Flatbuffers vollständig lesen. Die Version ist effektiv die größte Versionsnummer unter den Versionen aller ausgefüllten Felder und die kleinste kompatible Version, die durch die Dateikennung angezeigt wird. Die minimal notwendige Metadaten - Parser - Version wird automatisch durch den bevölkerten MetadataPopulator , wenn die Metadaten in ein TFLite Modell bestückt ist. Finden Sie in dem Metadaten - Extraktor für weitere Informationen darüber , wie die minimal notwendigen Metadaten - Parser - Version verwendet wird.

Lesen Sie die Metadaten von Modellen

Die Metadaten Extractor Bibliothek ist praktisches Tool die Metadaten und die zugehörigen Dateien von einem Modellen auf verschiedenen Plattformen (siehe lesen Java - Version und die C ++ Version ). Mit der Flatbuffers-Bibliothek können Sie Ihr eigenes Metadatenextraktionstool in anderen Sprachen erstellen.

Lesen Sie die Metadaten in Java

Um die Metadaten Extractor Bibliothek in Ihrem Android - App zu verwenden, empfehlen wir die Verwendung von TensorFlow Lite Metadaten AAR bei MavenCentral gehostet . Es enthält die MetadataExtractor Klasse, sowie die FlatBuffers Java - Bindings für das Metadatenschema und das Modellschema .

Sie können in Ihrem angeben diese build.gradle Abhängigkeiten wie folgt:

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

Um nächtlichen Snapshots zu verwenden, stellen Sie sicher , dass Sie hinzugefügt haben Repository - Snapshot Sonatype .

Sie können ein initialisieren MetadataExtractor mit einem Objekt ByteBuffer dass Punkte zum Modell:

public MetadataExtractor(ByteBuffer buffer);

Die ByteBuffer muss für die gesamte Lebensdauer des unverändert bleiben MetadataExtractor Objekt. Die Initialisierung kann fehlschlagen, wenn die Flatbuffers-Dateikennung der Modellmetadaten nicht mit der des Metadatenparsers übereinstimmt. Siehe Metadaten Versionsverwaltung für weitere Informationen.

Mit übereinstimmenden Dateibezeichnern wird der Metadatenextraktor erfolgreich Metadaten lesen, die aus allen vergangenen und zukünftigen Schemas aufgrund des Vorwärts- und Rückwärtskompatibilitätsmechanismus der Flatbuffers generiert wurden. Felder aus zukünftigen Schemas können jedoch nicht von älteren Metadatenextraktoren extrahiert werden. Die minimal notwendige Parser Version der Metadaten gibt die Mindestversion von Metadaten - Parser, der die Metadaten Flatbuffers vollständig lesen. Sie können die folgende Methode verwenden, um zu überprüfen, ob die minimal erforderliche Parser-Versionsbedingung erfüllt ist:

public final boolean isMinimumParserVersionSatisfied();

Die Übergabe eines Modells ohne Metadaten ist zulässig. Das Aufrufen von Methoden, die aus den Metadaten lesen, führt jedoch zu Laufzeitfehlern. Sie können prüfen , ob ein Modell Metadaten durch Aufrufen der hat hasMetadata Methode:

public boolean hasMetadata();

MetadataExtractor stellt komfortable Funktionen für Sie die Eingabe / Ausgabe - Tensor Metadaten zu erhalten. Zum Beispiel,

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

Obwohl das TensorFlow Lite Modellschema mehr Subgraphen unterstützt, die derzeit der TFLite Interpreter unterstützt nur eine einzige Untergraphen. Daher MetadataExtractor auslässt Subgraphen Index als Eingangsargument in ihren Methoden.

Lesen Sie die zugehörigen Dateien von Modellen

Das TensorFlow Lite-Modell mit Metadaten und zugehörigen Dateien ist im Wesentlichen eine Zip-Datei, die mit gängigen Zip-Tools entpackt werden kann, um die zugehörigen Dateien zu erhalten. Zum Beispiel können Sie entpacken mobilenet_v1_0.75_160_quantized und die Etikettendatei im Modell extrahieren , wie folgt:

$ 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

Sie können verknüpfte Dateien auch über die Metadata Extractor-Bibliothek lesen.

In Java, übergeben Sie die Dateinamen in die MetadataExtractor.getAssociatedFile Methode:

public InputStream getAssociatedFile(String fileName);

Ähnlich, in C ++, kann dies mit dem Verfahren erfolgen, ModelMetadataExtractor::GetAssociatedFile :

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