Metadane LiteRT zapewniają standard opisów modeli. Metadane są ważnym źródłem wiedzy na temat działania modelu i jego dane wejściowe / wyjściowe. Metadane składają się
- zrozumiałe dla człowieka części, które przekazują sprawdzone metody korzystania z modelu, oraz
- zrozumiałe dla komputera części, które mogą być wykorzystywane przez generatory kodu, takie jak Kod LiteRT na Androida generatora oraz Android Studio ML Binding .
Wszystkie modele obrazów opublikowane w Kaggle Modele zostały wypełnione wartościami metadanych.
Model w formacie metadanych
Metadane modelu są zdefiniowane w
metadata_schema.fbs
w
FlatBuffer
. Jak widać na Rysunku 1, jest on przechowywany w
metadane,
pole modelu TFLite
schemat,
pod nazwiskiem "TFLITE_METADATA"
. Niektóre modele mogą mieć powiązane pliki,
na przykład etykieta klasyfikacji
.
Te pliki są połączone na końcu oryginalnego pliku modelu jako pliki ZIP
przy użyciu pliku ZipFile "append"
tryb (tryb 'a'
). TFLite
Tłumacz może przyswajać nowy format pliku w taki sam sposób jak wcześniej. Zobacz pakiet
powiązane pliki.
Poniżej znajdziesz instrukcje wypełniania, wizualizacji i odczytywania metadanych.
Konfiguracja narzędzi do obsługi metadanych
Przed dodaniem metadanych do modelu musisz zaprogramować w Pythonie konfigurację środowiska do uruchamiania TensorFlow. Dostępny jest szczegółowy przewodnik, skonfiguruj je tutaj.
Po skonfigurowaniu środowiska programistycznego w Pythonie musisz zainstalować dodatkowe narzędzia:
pip install tflite-support
Narzędzia do metadanych LiteRT obsługują język Python 3.
Dodawanie metadanych za pomocą interfejsu Flatbuffers Python API
Metadane modelu składają się z 3 części schemat:
- Informacje o modelu – ogólny opis modelu i produktów
np. warunki licencji. Zobacz
ModelMetadata –
- Dane wejściowe – opis danych wejściowych i wstępnego przetwarzania
takich jak normalizacja. Zobacz
SubGraphMetadata.input_tensor_metadata.
- Informacje wyjściowe – opis danych wyjściowych np. mapowania na etykiety. Zobacz SubGraphMetadata.output_tensor_metadata.
- Dane wejściowe – opis danych wejściowych i wstępnego przetwarzania
takich jak normalizacja. Zobacz
SubGraphMetadata.input_tensor_metadata.
LiteRT obsługuje w tym momencie tylko jeden podgraf,
Generator kodu LiteRT
oraz Android Studio ML Binding
będzie używać ModelMetadata.name
i ModelMetadata.description
zamiast
SubGraphMetadata.name
i SubGraphMetadata.description
, podczas wyświetlania
metadanych
i generowaniu kodu.
Obsługiwane typy wejścia / wyjścia
Metadane LiteRT dla danych wejściowych i wyjściowych nie mają konkretnego lecz także typy danych wejściowych i wyjściowych. Nie ma znaczenia jak funkcjonuje model, o ile typy danych wejściowych i wyjściowych składają się następujący lub ich kombinację jest obsługiwany przez TensorFlow Metadane Lite:
- Cecha – liczby, które są liczbami całkowitymi bez znaku lub liczbą zmiennoprzecinkową zmiennoprzecinkową.
- Obraz – metadane obecnie obsługują obrazy w kolorze RGB i w skali szarości.
- Ramka ograniczająca – prostokątne ramki ograniczające kształtu. Schemat obsługuje a różne numery .
Spakuj powiązane pliki
Modele LiteRT mogą mieć różne powiązane pliki. Przykład: modele języków naturalnych zazwyczaj mają pliki ze słowami, które mapują fragmenty słów na słowa Identyfikatory; Modele klasyfikacji mogą mieć pliki etykiet wskazujące kategorie obiektów. Bez powiązanych plików (jeśli istnieją) model nie będzie działał poprawnie.
Powiązane pliki można teraz grupować z modelem za pomocą metadanych
z biblioteki Pythona. Nowy model LiteRT stanie się plikiem ZIP zawierającym
zarówno model, jak i powiązane pliki. Można go rozpakować za pomocą popularnego pliku ZIP
narzędzi. W nowym formacie modelu nadal jest używane to samo rozszerzenie pliku: .tflite
. it
jest kompatybilna z dotychczasową platformą TFLite i funkcją tłumaczenia rozmowy. Patrz sekcja Spakowanie metadanych
i powiązane pliki
model, aby dowiedzieć się więcej.
Informacje o powiązanych plikach można zarejestrować w metadanych. W zależności od
typ pliku i miejsce jego dołączenia (np. ModelMetadata
,
SubGraphMetadata
i TensorMetadata
), kod LiteRT na Androida
generator może zastosować odpowiednie wyniki przed/post
i przetwarza dane automatycznie. Patrz zastosowanie kodu <Codegen>. sekcji
każdy powiązany plik
typu
aby dowiedzieć się więcej.
Parametry normalizacji i kwantyzacji
Normalizacja to powszechna technika wstępnego przetwarzania danych w uczeniu maszynowym. celem normalizacji jest zmiana wartości na wspólną skalę, bez zniekształcanie różnic w zakresach wartości.
Kwantyzacja modelu to technika który pozwala zmniejszyć precyzję przedstawiania wag oraz opcjonalnie aktywacje pamięci i obliczenia.
W kontekście wstępnego i przetwarzania, normalizacji i kwantyzacji mamy do czynienia z 2 niezależnymi krokami. Oto szczegóły:
Normalizacja | Kwantyfikacja | |
---|---|---|
Oto przykład funkcji funkcji obraz wejściowy w MobileNet dla liczb zmiennoprzecinkowych i modele ilościowe, . |
Model swobodny: - średnia: 127,5 - standardowy: 127,5 Model ilościowy: - średnia: 127,5 - standardowy: 127,5 |
Model swobodny: – zeroPoint: 0 – skala: 1,0 Model ilościowy: - zeroPoint: 128,0 - scale:0.0078125f |
Kiedy wywoływać? |
Dane wejściowe: jeśli dane wejściowe jest znormalizowane w trenowanie, dane wejściowe dane dotyczące wnioskowania do znormalizowania odpowiednio się zmienia. Dane wyjściowe: dane wyjściowe nie będą znormalizowane. |
Modele pływające
nie wymagają kwantyzacji. Model kwantowy może lub może nie potrzebować kwantyzacja przed i po o przetwarzaniu danych. To zależy na typie danych tensory wejściowe/wyjściowe. - tensory zmiennoprzecinkowe: nie kwantyzacja przed i po potrzebne przetwarzanie. Quant Operacje i operacje pomniejszone są w modelu wykres. - tensory int8/uint8: potrzebujesz kwantyzacji w przed przetwarzaniem danych i po ich przetworzeniu. |
Wzór |
znormalizowane_dane_wejściowe = (dane wejściowe – średnia) / standardowe |
Kwantyfikacja danych wejściowych:
q = f / skala + zeroPoint Zdekwantyzuj dla dane wyjściowe: f = (q – punkt zerowy) * skala |
Gdzie są parametry |
Wypełnione przez twórcę modelu
i zapisane w modelu
metadanych,
NormalizationOptions |
Wypełnione automatycznie przez konwertera TFLite, zapisane w modelu tflite . |
Jak uzyskać ? | Przez
Interfejs API MetadataExtractor
[2]
|
Przez TFLite
Tensor API [1] lub
przez
Interfejs API MetadataExtractor
[2] |
Stosuj metody zmiennoprzecinkowe i kwantowe modele mają takie same wartości ? | Tak, używaj liczb zmiennoprzecinkowych i kwantowych modele mają takie same Normalizacja parametry | Nie, model zmiennoprzecinkowy nie wymagają kwantyzacji. |
Czy TFLite Code generatora lub Android Powiązanie Studio ML generuj automatycznie w przetwarzaniu danych? | Tak |
Tak |
[1] Jawa LiteRT
Interfejs API
oraz LiteRT C++
API.
[2] Biblioteka wyodrębniania metadanych
Podczas przetwarzania danych obrazu w modelach uint8 normalizacja i kwantyzacja są czasem pomijane. Jest to dozwolone, gdy wartości pikseli mieszczą się w zakresie [0, 255]. Ogólnie jednak dane należy przetwarzać zgodnie z w stosownych przypadkach parametry normalizacji i kwantyzacji.
Przykłady
Znajdziesz tu przykłady wypełniania metadanych dla różnych typy modeli tutaj:
Klasyfikacja obrazów
Pobierz skrypt tutaj , który uzupełnia metadane mobilenet_v1_0.75_160_quantized.tflite. Uruchom skrypt w ten sposób:
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
Aby wypełnić metadane innych modeli klasyfikacji obrazów, dodaj specyfikację modelu polubienie to w scenariusz. W dalszej części tego przewodnika omawiamy najważniejsze sekcje w przykładzie klasyfikacji obrazów, aby zilustrować kluczowe elementy.
Szczegółowa analiza przykładu klasyfikacji obrazów
Informacje o modelu
Metadane zaczynają się od utworzenia nowych informacji o modelu:
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.")
Informacje wejściowe / wyjściowe
Ta sekcja pokazuje, jak opisać podpis wejściowy i wyjściowy modelu. Automatyczne generatory kodu mogą używać tych metadanych do tworzenia Przetwarzanie kodu. Aby utworzyć dane wejściowe lub wyjściowe dotyczące tensora:
# Creates input info.
input_meta = _metadata_fb.TensorMetadataT()
# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()
Dane wejściowe obrazu
Obraz to typowy typ danych wejściowych systemów uczących się. Metadane LiteRT obsługuje takie informacje, jak przestrzeń kolorów i dane dotyczące wstępnego przetwarzania danych, takie jak z normalizacją. Wymiary obrazu nie wymagają ręcznego określania ponieważ jest on określony przez kształt tensora wejściowego i można go określić automatycznie wywnioskować.
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
Dane wyjściowe etykiety
Etykieta można zmapować na tensor wyjściowy za pomocą powiązanego pliku za pomocą
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]
Tworzenie metadanych Flatbuffers
Ten kod łączy informacje o modelu z danymi wejściowymi i wyjściowymi informacje:
# 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()
Zapakuj do modelu metadane i powiązane pliki
Po utworzeniu metadanych Flatbuffers metadane i plik etykiety zostaną
zapisane w pliku TFLite metodą 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()
Możesz zapakować do modelu dowolną liczbę powiązanych plików
load_associated_files
Należy jednak zapakować co najmniej te pliki
co jest omówione w metadanych. W tym przykładzie spakowanie pliku etykiety będzie wyglądać tak:
obowiązkowe.
Wizualizacja metadanych
Narzędzie Netron pozwala zwizualizować
metadanych lub odczytać metadane z modelu LiteRT do pliku json
w formacie 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 obsługuje również wyświetlanie metadanych za pomocą Android Studio ML Powiązanie .
Obsługa wersji metadanych
Metadane schemat jest objęta wersjami według semantycznego numeru wersji, który śledzi zmiany pliku schema.org, a dzięki identyfikacji plików Flatbuffers, która wskazuje prawdziwą zgodność wersji.
Numer semantycznej obsługi wersji
Schemat metadanych jest obsługiwany przez semantyczną obsługę wersji
,
na przykład GŁÓWNA.PODRZĘDNA.POPRAWKA. Śledzi zmiany schematu na podstawie reguł
tutaj.
Zobacz historię
dodane po wersji 1.0.0
.
Identyfikacja pliku Flatbuffers
Semantyczna obsługa wersji gwarantuje zgodność, jeśli jest zgodna z regułami, ale nie oznacza rzeczywistej niezgodności. Zwiększenie liczby GŁÓWNA powoduje, że nie musi oznaczać, że zgodność wsteczna jest uszkodzona. Dlatego użyj pliku Flatbuffers, dane identyfikacyjne, file_identifier, aby wskazać prawdziwą zgodność schematu metadanych. Identyfikator pliku to dokładnie 4 znaki. Jest ustalony na podstawie określonego schematu metadanych, a nie mogą ulec zmianie przez użytkowników. Jeśli zgodność wsteczna schematu metadanych musi zostać złamany z jakiegoś powodu, parametr file_identifier wyświetla się np. od „M001” do „M002”. File_identifier powinien być znacznie rzadziej zmieniany częściej niż parametr metadata_version.
Minimalna wymagana wersja parsera metadanych
Minimalny niezbędny parser metadanych
wersja
to minimalna wersja parsera metadanych (wygenerowanego kodu Flatbuffers), który
może w całości odczytać metadane Flatbuffers w całości. Ta wersja jest w praktyce
o największym numerze wersji spośród wszystkich wypełnionych pól
najmniejszą zgodną wersję wskazywaną przez identyfikator pliku. Minimalne
niezbędna wersja parsera metadanych jest automatycznie wypełniana przez
MetadataPopulator
, gdy metadane zostaną umieszczone w modelu TFLite. Zobacz
wyodrębnianie metadanych
minimalnej wymaganej wersji parsera metadanych.
Odczytywanie metadanych z modeli
Biblioteka wyodrębniania metadanych to wygodne narzędzie do odczytu metadanych i powiązanych plików z modeli na różnych platformach (zobacz artykuł w języku JavaScript wersja oraz język C++ wersji). Możesz utworzyć własne narzędzie do wyodrębniania metadanych w innych językach za pomocą Biblioteka Flatbuffers.
Odczytywanie metadanych w Javie
Jeśli chcesz używać biblioteki wyodrębniania metadanych w aplikacji na Androida, zalecamy użycie
narzędzie AAR metadanych LiteRT hostowane pod adresem
MavenCentral.
Zawiera klasę MetadataExtractor
oraz środowisko FlatBuffers Java.
powiązania metadanych,
schemat
oraz model
schemat.
Możesz to określić w zależnościach build.gradle
w ten sposób:
dependencies {
implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'
}
Aby korzystać z nocnych zrzutów ekranu, dodaj opcję Sonatype (ujęcie) .
Możesz zainicjować obiekt MetadataExtractor
obiektem ByteBuffer
wskazującym
do modelu:
public MetadataExtractor(ByteBuffer buffer);
Wartość ByteBuffer
musi pozostać niezmieniona przez cały okres istnienia
MetadataExtractor
obiekt. Inicjalizacja może się nie udać, jeśli plik Flatbuffers
identyfikator metadanych modelu nie jest zgodny z identyfikatorem parsera metadanych. Zobacz
obsługi wersji metadanych.
Wyodrębnianie metadanych z pasujących identyfikatorów plików umożliwi odczyt metadanych wygenerowanych na podstawie wszystkich przeszłych i przyszłych schematów ze względu na tag Flatbuffers mechanizm zgodności wstecznej i standardowej. Jednak pola z przyszłości Starsze moduły wyodrębniania metadanych nie mogą wyodrębniać schematów. Minimalna wymagana liczba wersji parsera metadanych. wskazuje minimalną wersję parsera metadanych, która może odczytywać metadane Pełne bufory. Aby sprawdzić, czy wartość minimalna wymagany warunek wersji parsera:
public final boolean isMinimumParserVersionSatisfied();
Dozwolone jest przekazywanie modelu bez metadanych. Wywołanie metod, które
odczyt metadanych spowoduje błędy podczas działania. Możesz sprawdzić, czy model
metadanych przez wywołanie metody hasMetadata
:
public boolean hasMetadata();
MetadataExtractor
udostępnia wygodne funkcje umożliwiające uzyskanie
tensorów wejściowych/wyjściowych metadanych. Na przykład
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);
Chociaż model LiteRT
schemat
obsługuje wiele podgrafów, narzędzie TFLite Interpreter obsługuje obecnie tylko
jednego podgrafu. Dlatego funkcja MetadataExtractor
pomija indeks podgrafu jako dane wejściowe.
w jego metodach.
Odczytywanie powiązanych plików z modeli
Model LiteRT z metadanymi i powiązanymi plikami .zip, które można rozpakować za pomocą popularnych narzędzi do spakowania, aby pobrać powiązane pliki. Możesz na przykład rozpakować plik mobilenet_v1_0.75_160_quantized i wyodrębnij w modelu plik etykiety w ten sposób:
$ 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
Powiązane pliki możesz też odczytywać za pomocą biblioteki ekstraktora metadanych.
W języku Java przekaż nazwę pliku do narzędzia MetadataExtractor.getAssociatedFile
.
:
public InputStream getAssociatedFile(String fileName);
Podobnie w C++ można to zrobić za pomocą metody
ModelMetadataExtractor::GetAssociatedFile
:
tflite::support::StatusOr<absl::string_view> GetAssociatedFile(
const std::string& filename) const;