Shtimi i meta të dhënave në modelet LiteRT

Metadata LiteRT ofron një standard për përshkrimet e modeleve. Meta të dhënat janë një burim i rëndësishëm njohurish për atë që modeli bën dhe informacionin e tij hyrës/dalës. Meta të dhënat përbëhen nga të dyja

Të gjitha modelet e imazheve të publikuara në Kaggle Models janë mbushur me meta të dhëna.

Modeli me formatin e meta të dhënave

modeli_me_metadata
Figura 1. Modeli TFLite me meta të dhëna dhe skedarë shoqërues.

Modeli i meta të dhënave përcaktohet në metadata_schema.fbs , një skedar FlatBuffer . Siç tregohet në figurën 1, ai ruhet në fushën e meta të dhënaveskemës së modelit TFLite , nën emrin, "TFLITE_METADATA" . Disa modele mund të vijnë me skedarë shoqërues, të tillë si skedarët e etiketës së klasifikimit . Këta skedarë janë të lidhur në fund të skedarit të modelit origjinal si një ZIP duke përdorur modalitetin "Shtoj" ZipFile (modaliteti 'a' ). TFLite Interpreter mund të konsumojë formatin e ri të skedarit në të njëjtën mënyrë si më parë. Shikoni Paketimi i skedarëve të lidhur për më shumë informacion.

Shihni udhëzimin më poshtë se si të plotësoni, vizualizoni dhe lexoni meta të dhënat.

Vendosni mjetet e meta të dhënave

Përpara se të shtoni metadata në modelin tuaj, do t'ju duhet një konfigurim i mjedisit programues Python për ekzekutimin e TensorFlow. Ekziston një udhëzues i detajuar se si ta vendosni këtë këtu .

Pas konfigurimit të mjedisit të programimit Python, do t'ju duhet të instaloni vegla shtesë:

pip install tflite-support

Veglat metadata LiteRT mbështet Python 3.

Shtimi i meta të dhënave duke përdorur Flatbuffers Python API

Ekzistojnë tre pjesë të meta të dhënave të modelit në skemë :

  1. Informacioni i modelit - Përshkrimi i përgjithshëm i modelit si dhe artikuj të tillë si kushtet e licencës. Shih Model Metadata .
    1. Informacioni i hyrjes - Përshkrimi i inputeve dhe përpunimi paraprak i kërkuar si normalizimi. Shihni SubGraphMetadata.input_tensor_metadata .
      1. Informacioni i daljes - Përshkrimi i rezultatit dhe pas përpunimit të kërkuar, si p.sh. hartë në etiketa. Shihni SubGraphMetadata.output_tensor_metadata .

Meqenëse LiteRT mbështet vetëm nëngrafinë e vetme në këtë pikë, gjeneruesi i kodit LiteRT dhe funksioni i lidhjes së Android Studio ML do të përdorin ModelMetadata.name dhe ModelMetadata.description , në vend të SubGraphMetadata.name dhe SubGraphMetadata.description , kur shfaqin metadata dhe gjeneron kodin.

Llojet hyrëse/dalëse të mbështetura

Meta të dhënat e LiteRT për hyrje dhe dalje nuk janë të dizajnuara duke pasur parasysh lloje të veçanta modelesh, por përkundrazi, llojet hyrëse dhe dalëse. Nuk ka rëndësi se çfarë bën modeli funksionalisht, për sa kohë që llojet e hyrjes dhe daljes përbëhen nga sa vijon ose një kombinim i mëposhtëm, ai mbështetet nga metadatat e TensorFlow Lite:

  • Veçori - Numra që janë numra të plotë të panënshkruar ose float32.
  • Imazhi - Metadata aktualisht mbështet imazhe RGB dhe gri.
  • Kutia kufizuese - Kutitë kufizuese në formë drejtkëndore. Skema mbështet një sërë skemash numërimi .

Paketoni skedarët e lidhur

Modelet LiteRT mund të vijnë me skedarë të ndryshëm të lidhur. Për shembull, modelet e gjuhëve natyrore zakonisht kanë skedarë vokab që lidhin pjesët e fjalëve me ID-të e fjalëve; Modelet e klasifikimit mund të kenë skedarë etiketash që tregojnë kategoritë e objekteve. Pa skedarët e lidhur (nëse ka), një model nuk do të funksionojë mirë.

Skedarët e lidhur tani mund të bashkohen me modelin përmes bibliotekës së meta të dhënave Python. Modeli i ri LiteRT bëhet një skedar zip që përmban si modelin ashtu edhe skedarët e lidhur. Mund të shpaketohet me mjete të zakonshme zip. Ky format i ri i modelit vazhdon të përdorë të njëjtën shtesë të skedarit, .tflite . Është në përputhje me kornizën ekzistuese TFLite dhe Interpreter. Shikoni Paketimin e meta të dhënave dhe skedarët e lidhur në model për më shumë detaje.

Informacioni i skedarit të lidhur mund të regjistrohet në metadata. Në varësi të llojit të skedarit dhe vendit ku është bashkangjitur skedari (p.sh. ModelMetadata , SubGraphMetadata dhe TensorMetadata ), gjeneruesi i kodit Android LiteRT mund të aplikojë automatikisht përpunimin përkatës para/post në objekt. Shihni seksionin <Përdorimi i kodit> të secilit lloj skedari shoqërues në skemë për më shumë detaje.

Parametrat e normalizimit dhe kuantizimit

Normalizimi është një teknikë e zakonshme e parapërpunimit të të dhënave në mësimin e makinerive. Qëllimi i normalizimit është ndryshimi i vlerave në një shkallë të përbashkët, pa shtrembëruar dallimet në vargjet e vlerave.

Kuantizimi i modelit është një teknikë që lejon paraqitje me saktësi të reduktuar të peshave dhe opsionalisht, aktivizime si për ruajtjen ashtu edhe për llogaritjen.

Për sa i përket parapërpunimit dhe pas-përpunimit, normalizimi dhe kuantizimi janë dy hapa të pavarur. Këtu janë detajet.

Normalizimi Kuantizimi

Një shembull i vlerave të parametrave të imazhit hyrës në MobileNet për modelet float dhe quant, përkatësisht.
Modeli i lundrimit :
- mesatarja: 127.5
- std: 127,5
Modeli sasior :
- mesatarja: 127.5
- std: 127,5
Modeli i lundrimit :
- pika zero: 0
- shkalla: 1.0
Modeli sasior :
- pika zero: 128.0
- shkalla:0,0078125f




Kur të thirret?


Inputet : Nëse të dhënat hyrëse normalizohen në trajnim, të dhënat hyrëse të konkluzionit duhet të normalizohen në përputhje me rrethanat.
Rezultatet : të dhënat dalëse nuk do të normalizohen në përgjithësi.
Modelet Float nuk kanë nevojë për kuantizim.
Modeli i kuantizuar mund ose nuk mund të ketë nevojë për kuantizim në përpunimin para/pas. Varet nga lloji i të dhënave të tensorëve hyrës/dalës.
- tensorët float: nuk nevojitet kuantizimi në përpunimin para/pas. Op kuanti dhe op dekuant futen në grafikun e modelit.
- tensorët int8/uint8: kanë nevojë për kuantizim në përpunimin para/pas.


Formula


hyrje e_normalizuar = (hyrje - mesatare) / std
Kuantizoni për hyrjet :
q = f / shkallë + pikë zero
Dekuantizimi për rezultatet :
f = (q - pikë zero) * shkallë

Ku janë parametrat
Mbushur nga krijuesi i modelit dhe ruhet në meta të dhënat e modelit, si NormalizationOptions Mbushet automatikisht nga konverteri TFLite dhe ruhet në skedarin e modelit tflite.
Si të merrni parametrat? Përmes API-së MetadataExtractor [2] Përmes API-së TFLite Tensor [1] ose përmes API-së MetadataExtractor [2]
A ndajnë të njëjtën vlerë modelet float dhe quant? Po, modelet float dhe quant kanë të njëjtat parametra Normalizimi Jo, modeli float nuk ka nevojë për kuantizim.
A e gjeneron automatikisht gjeneratori i kodit TFLite ose lidhja Android Studio ML në përpunimin e të dhënave?
po

po

[1] LiteRT Java API dhe LiteRT C++ API .
[2] Biblioteka e nxjerrjes së meta të dhënave

Kur përpunohen të dhënat e imazhit për modelet uint8, normalizimi dhe kuantizimi ndonjëherë anashkalohen. Është mirë ta bësh këtë kur vlerat e pikselit janë në intervalin [0, 255]. Por në përgjithësi, gjithmonë duhet t'i përpunoni të dhënat sipas parametrave të normalizimit dhe kuantizimit kur është e mundur.

Shembuj

Këtu mund të gjeni shembuj se si duhet të plotësohen meta të dhënat për lloje të ndryshme modelesh:

Klasifikimi i imazhit

Shkarkoni skriptin këtu , i cili plotëson meta të dhënat në mobilenet_v1_0.75_160_quantized.tflite . Ekzekutoni skriptin si kjo:

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

Për të plotësuar meta të dhënat për modelet e tjera të klasifikimit të imazheve, shtoni specifikimet e modelit si kjo në skenar. Pjesa tjetër e këtij udhëzuesi do të nxjerrë në pah disa nga seksionet kryesore në shembullin e klasifikimit të imazhit për të ilustruar elementët kryesorë.

Zhytje e thellë në shembullin e klasifikimit të imazheve

Informacioni i modelit

Metadata fillon duke krijuar një informacion të ri modeli:

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

Informacioni hyrës/dalës

Ky seksion ju tregon se si të përshkruani nënshkrimin hyrës dhe dalës të modelit tuaj. Këto meta të dhëna mund të përdoren nga gjeneruesit automatikë të kodit për të krijuar kodin para dhe pas përpunimit. Për të krijuar informacione hyrëse ose dalëse për një tensor:

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

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

Hyrja e imazhit

Imazhi është një lloj i zakonshëm i hyrjes për mësimin e makinerive. Metadatat e LiteRT mbështesin informacione të tilla si hapësira e ngjyrave dhe informacione të përpunimit paraprak siç është normalizimi. Dimensioni i figurës nuk kërkon specifikim manual, pasi ai është dhënë tashmë nga forma e tensorit të hyrjes dhe mund të konkludohet automatikisht.

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

Prodhimi i etiketës

Etiketa mund të vendoset në një tensor dalës nëpërmjet një skedari të lidhur duke përdorur 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]

Krijoni Flatbuffers të meta të dhënave

Kodi i mëposhtëm kombinon informacionin e modelit me informacionin hyrës dhe dalës:

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

Paketoni meta të dhënat dhe skedarët e lidhur në model

Pasi të krijohen Flatbuffers të meta të dhënave, meta të dhënat dhe skedari i etiketës shkruhen në skedarin TFLite përmes metodës 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()

Ju mund të paketoni sa më shumë skedarë të shoqëruar në model përmes load_associated_files . Sidoqoftë, kërkohet të paketohen të paktën ato skedarë të dokumentuar në metadata. Në këtë shembull, paketimi i skedarit të etiketës është i detyrueshëm.

Vizualizoni meta të dhënat

Ju mund të përdorni Netron për të vizualizuar meta të dhënat tuaja, ose mund t'i lexoni meta të dhënat nga një model LiteRT në një format json duke përdorur 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 gjithashtu mbështet shfaqjen e meta të dhënave përmes veçorisë Android Studio ML Binding .

Versionimi i meta të dhënave

Skema e meta të dhënave versionohet si nga numri i versionit Semantik, i cili gjurmon ndryshimet e skedarit të skemës, ashtu edhe nga identifikimi i skedarit Flatbuffers, i cili tregon përputhshmërinë e vërtetë të versionit.

Numri i versionit semantik

Skema e meta të dhënave është versionuar nga numri i versionit semantik , si p.sh. MAJOR.MINOR.PATCH. Ajo gjurmon ndryshimet e skemës sipas rregullave këtu . Shikoni historinë e fushave të shtuara pas versionit 1.0.0 .

Identifikimi i skedarit Flatbuffers

Versionimi semantik garanton përputhshmërinë nëse ndiqni rregullat, por nuk nënkupton papajtueshmërinë e vërtetë. Kur rritni numrin KRYESOR, nuk do të thotë domosdoshmërisht prishja e përputhshmërisë së prapambetur. Prandaj, ne përdorim identifikimin e skedarit Flatbuffers , file_identifier , për të treguar përputhshmërinë e vërtetë të skemës së meta të dhënave. Identifikuesi i skedarit është saktësisht 4 karaktere i gjatë. Është fiksuar në një skemë të caktuar të meta të dhënave dhe nuk i nënshtrohet ndryshimit nga përdoruesit. Nëse përputhshmëria e prapambetur e skemës së meta të dhënave duhet të prishet për ndonjë arsye, identifikuesi i skedarit do të rritet, për shembull, nga "M001" në "M002". File_identifier pritet të ndryshohet shumë më rrallë se metadata_version.

Versioni minimal i nevojshëm i analizuesit të meta të dhënave

Versioni minimal i nevojshëm i analizuesit të meta të dhënave është versioni minimal i analizuesit të meta të dhënave (kodi i gjeneruar nga Flatbuffers) që mund të lexojë plotësisht Flatbufferët e meta të dhënave. Versioni është efektivisht numri më i madh i versionit midis versioneve të të gjitha fushave të mbushura dhe versioni më i vogël i pajtueshëm i treguar nga identifikuesi i skedarit. Versioni minimal i nevojshëm i analizuesit të meta të dhënave plotësohet automatikisht nga MetadataPopulator kur të dhënat plotësohen në një model TFLite. Shikoni nxjerrësin e meta të dhënave për më shumë informacion se si përdoret versioni minimal i nevojshëm i analizuesit të meta të dhënave.

Lexoni meta të dhënat nga modelet

Biblioteka Metadata Extractor është mjet i përshtatshëm për të lexuar meta të dhënat dhe skedarët e lidhur nga një model nëpër platforma të ndryshme (shih versionin Java dhe versionin C++ ). Mund të ndërtoni mjetin tuaj për nxjerrjen e meta të dhënave në gjuhë të tjera duke përdorur bibliotekën Flatbuffers.

Lexoni meta të dhënat në Java

Për të përdorur bibliotekën Metadata Extractor në aplikacionin tuaj Android, ju rekomandojmë të përdorni LiteRT Metadata AAR të pritur në MavenCentral . Ai përmban klasën MetadataExtractor , si dhe lidhjet FlatBuffers Java për skemën e meta të dhënave dhe skemën e modelit .

Ju mund ta specifikoni këtë në varësitë tuaja build.gradle si më poshtë:

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

Për të përdorur fotografitë e çastit gjatë natës, sigurohuni që të keni shtuar depon e fotografive të Sonatype .

Ju mund të inicializoni një objekt MetadataExtractor me një ByteBuffer që tregon modelin:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer duhet të mbetet i pandryshuar gjatë gjithë jetës së objektit MetadataExtractor . Inicializimi mund të dështojë nëse identifikuesi i skedarit Flatbuffers i meta të dhënave të modelit nuk përputhet me atë të analizuesit të meta të dhënave. Shih versionimin e meta të dhënave për më shumë informacion.

Me identifikuesit e skedarëve që përputhen, nxjerrësi i meta të dhënave do të lexojë me sukses meta të dhënat e krijuara nga të gjitha skemat e kaluara dhe të ardhshme për shkak të mekanizmit të përputhshmërisë përpara dhe prapa të Flatbuffers. Megjithatë, fushat nga skemat e ardhshme nuk mund të nxirren nga nxjerrës më të vjetër të meta të dhënave. Versioni minimal i nevojshëm i analizuesit të meta të dhënave tregon versionin minimal të analizuesit të meta të dhënave që mund të lexojë plotësisht Flatbufferët e meta të dhënave. Ju mund të përdorni metodën e mëposhtme për të verifikuar nëse plotësohet kushti minimal i nevojshëm i versionit të analizuesit:

public final boolean isMinimumParserVersionSatisfied();

Lejohet kalimi në një model pa meta të dhëna. Megjithatë, thirrja e metodave që lexojnë nga meta të dhënat do të shkaktojë gabime në kohën e ekzekutimit. Ju mund të kontrolloni nëse një model ka metadata duke thirrur metodën hasMetadata :

public boolean hasMetadata();

MetadataExtractor ofron funksione të përshtatshme për ju që të merrni meta të dhënat e tensoreve hyrëse/dalëse. Për shembull,

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

Megjithëse skema e modelit LiteRT mbështet nëngrafë të shumtë, Interpretuesi TFLite aktualisht mbështet vetëm një nëngraf të vetëm. Prandaj, MetadataExtractor e lë indeksin e nëngrafit si një argument hyrës në metodat e tij.

Lexoni skedarët e lidhur nga modelet

Modeli LiteRT me metadata dhe skedarë të lidhur është në thelb një skedar zip që mund të shpaketohet me mjete të zakonshme zip për të marrë skedarët e lidhur. Për shembull, mund të zhbllokoni mobilenet_v1_0.75_160_quantized dhe të ekstraktoni skedarin e etiketës në model si më poshtë:

$ 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

Ju gjithashtu mund të lexoni skedarë të lidhur përmes bibliotekës Metadata Extractor.

Në Java, kaloni emrin e skedarit në metodën MetadataExtractor.getAssociatedFile :

public InputStream getAssociatedFile(String fileName);

Në mënyrë të ngjashme, në C++, kjo mund të bëhet me metodën ModelMetadataExtractor::GetAssociatedFile :

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