LiteRT modellerine meta veri ekleme

LiteRT meta verileri, model açıklamaları için bir standart sağlar. Meta veriler, modelin ne yaptığı ve giriş / çıkış bilgileri hakkında önemli bir bilgi kaynağıdır. Meta veriler hem

Kaggle Models'da yayınlanan tüm görüntü modelleri meta verilerle doldurulmuştur.

Meta veri biçimine sahip model

model_with_metadata
Şekil 1. Meta verileri ve ilişkili dosyaları içeren TFLite modeli.

Model meta verileri, metadata_schema.fbs adlı FlatBuffer dosyasında tanımlanır. Şekil 1'de gösterildiği gibi, "TFLITE_METADATA" adı altında TFLite model şemasının metadata alanında depolanır. Bazı modellerle ilişkili dosyalar (ör. sınıflandırma etiketi dosyaları) olabilir. Bu dosyalar, ZipFile "append" modu ('a' modu) kullanılarak orijinal model dosyasının sonuna ZIP olarak eklenir. TFLite Interpreter, yeni dosya biçimini eskisi gibi kullanabilir. Daha fazla bilgi için İlişkili dosyaları paketleme başlıklı makaleyi inceleyin.

Meta verileri doldurma, görselleştirme ve okumayla ilgili talimatları aşağıda bulabilirsiniz.

Meta veri araçlarını ayarlama

Modelinize meta veri eklemeden önce TensorFlow'u çalıştırmak için bir Python programlama ortamı ayarlamanız gerekir. Bu özelliği nasıl ayarlayacağınızla ilgili ayrıntılı kılavuzu burada bulabilirsiniz.

Python programlama ortamını kurduktan sonra ek araçlar yüklemeniz gerekir:

pip install tflite-support

LiteRT meta veri aracı, Python 3'ü destekler.

Flatbuffers Python API'yi kullanarak meta veri ekleme

Şemadaki model meta verileri üç bölümden oluşur:

  1. Model bilgileri: Modelin genel açıklaması ve lisans şartları gibi öğeler. ModelMetadata başlıklı makaleyi inceleyin. 2. Giriş bilgileri: Girişlerin ve ön işlemenin açıklaması (ör. normalleştirme gibi gerekli işlemler). SubGraphMetadata.input_tensor_metadata bölümüne bakın. 3. Çıkış bilgileri: Çıkışın açıklaması ve etiketlerle eşleme gibi gerekli olan sonradan işleme. SubGraphMetadata.output_tensor_metadata bölümüne bakın.

LiteRT şu anda yalnızca tek alt grafiği desteklediğinden LiteRT kod oluşturucu ve Android Studio ML Bağlama özelliği, meta verileri görüntülerken ve kod oluştururken SubGraphMetadata.name ve SubGraphMetadata.description yerine ModelMetadata.name ve ModelMetadata.description kullanır.

Desteklenen giriş / çıkış türleri

Giriş ve çıkış için LiteRT meta verileri, belirli model türleri yerine giriş ve çıkış türleri dikkate alınarak tasarlanır. Giriş ve çıkış türleri aşağıdakilerden veya bunların bir kombinasyonundan oluştuğu sürece modelin işlevsel olarak ne yaptığı önemli değildir. Bu türler, TensorFlow Lite meta verileri tarafından desteklenir:

  • Özellik: İşaretsiz tam sayılar veya float32 olan sayılar.
  • Resim: Meta veriler şu anda RGB ve gri tonlamalı resimleri desteklemektedir.
  • Sınırlayıcı kutu: Dikdörtgen şekilli sınırlayıcı kutular. Şema, çeşitli numaralandırma şemalarını destekler.

İlişkili dosyaları paketleme

LiteRT modelleri, farklı ilişkili dosyalarla birlikte gelebilir. Örneğin, doğal dil modellerinde genellikle kelime parçalarını kelime kimlikleriyle eşleyen sözcük dosyaları bulunur. Sınıflandırma modellerinde ise nesne kategorilerini belirten etiket dosyaları olabilir. İlişkili dosyalar (varsa) olmadan bir model iyi çalışmaz.

İlişkili dosyalar artık meta veri Python kitaplığı aracılığıyla modelle birlikte paketlenebilir. Yeni LiteRT modeli, hem modeli hem de ilişkili dosyaları içeren bir ZIP dosyası haline gelir. Yaygın zip araçlarıyla açılabilir. Bu yeni model biçimi, aynı dosya uzantısını (.tflite) kullanmaya devam eder. Mevcut TFLite çerçevesi ve yorumlayıcısıyla uyumludur. Daha fazla bilgi için Paket meta verilerini ve ilişkili dosyaları modele yerleştirme başlıklı makaleye bakın.

İlişkili dosya bilgileri meta verilere kaydedilebilir. Dosya türüne ve dosyanın eklendiği yere (ör. ModelMetadata, SubGraphMetadata ve TensorMetadata) bağlı olarak LiteRT Android kodu oluşturucu, nesneye otomatik olarak ilgili ön/son işlemeyi uygulayabilir. Daha fazla bilgi için şemadaki her bir ilişkilendirilmiş dosya türünün <Codegen usage> bölümüne bakın.

Normalleştirme ve nicelendirme parametreleri

Normalleştirme, makine öğreniminde yaygın olarak kullanılan bir veri ön işleme tekniğidir. Normalleştirmenin amacı, değer aralıklarındaki farklılıkları bozmadan değerleri ortak bir ölçeğe dönüştürmektir.

Model niceleme, ağırlıkların ve isteğe bağlı olarak hem depolama hem de hesaplama için etkinleştirmelerin daha az hassas temsillerine olanak tanıyan bir tekniktir.

Ön işleme ve son işleme açısından normalleştirme ve nicemleme iki bağımsız adımdır. Sorunla ilgili ayrıntılar aşağıda belirtilmiştir.

Normalleştirme Kuantizasyon

Kayan ve nicemlenmiş modeller için MobileNet'teki giriş görüntüsünün parametre değerlerine örnek.
Kayan nokta modeli:
- ortalama: 127,5
- standart sapma: 127,5
Kuantize edilmiş model:
- ortalama: 127,5
- standart sapma: 127,5
Kayan nokta modeli:
- zeroPoint: 0
- scale: 1.0
Quant modeli:
- zeroPoint: 128.0
- scale:0.0078125f




Ne zaman çağrılır?


Girişler: Giriş verileri eğitimde normalleştirilmişse çıkarım giriş verilerinin de buna göre normalleştirilmesi gerekir.
Çıkışlar: Çıkış verileri genel olarak normalleştirilmez.
Kayan nokta modellerinin nicemlenmesi gerekmez.
Kuantize edilmiş modelin ön/son işlemede kuantizasyona ihtiyacı olabilir veya olmayabilir. Giriş/çıkış tensörlerinin veri türüne bağlıdır.
- Kayan nokta tensörleri: Ön/son işlemede nicelendirme gerekmez. Quant op ve dequant op, model grafiğine yerleştirilir.
- int8/uint8 tensörleri: ön/son işlemede nicelendirme gerekir.


Formül


normalized_input = (input - mean) / std
Girişler için nicemleme:
q = f / scale + zeroPoint
Çıkışlar için nicemleme kaldırma:
f = (q - zeroPoint) * scale

Parametreler nerede bulunur?
Modeli oluşturan kişi tarafından doldurulur ve model meta verilerinde NormalizationOptions olarak depolanır. TFLite dönüştürücü tarafından otomatik olarak doldurulur ve tflite modeli dosyasında saklanır.
Parametreler nasıl alınır? MetadataExtractor API'si üzerinden [2] TFLite Tensor API [1] veya MetadataExtractor API [2] üzerinden
Do float and quant models share the same value? Evet, float ve quant modelleri aynı Normalleştirme parametrelerine sahiptir. Hayır, kayan nokta modelinin nicemlenmesi gerekmez.
TFLite Code Generator veya Android Studio ML bağlama özelliği, veri işleme sırasında otomatik olarak oluşturur mu?
Evet

Evet

[1] LiteRT Java API ve LiteRT C++ API.
[2] Meta veri ayıklayıcı kitaplığı

uint8 modelleri için görüntü verileri işlenirken bazen normalleştirme ve nicemleme atlanır. Piksel değerleri [0, 255] aralığında olduğunda bu işlemi yapabilirsiniz. Ancak genel olarak, geçerli olduğunda verileri her zaman normalleştirme ve nicelleştirme parametrelerine göre işlemeniz gerekir.

Örnekler

Farklı model türleri için meta verilerin nasıl doldurulması gerektiğiyle ilgili örnekleri burada bulabilirsiniz:

Görüntü sınıflandırma

Meta verileri mobilenet_v1_0.75_160_quantized.tflite ile dolduran komut dosyasını buradan indirin. Komut dosyasını şu şekilde çalıştırın:

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

Diğer görüntü sınıflandırma modellerinin meta verilerini doldurmak için model özelliklerini (ör. bu) komut dosyasına ekleyin. Bu kılavuzun geri kalanında, temel öğeleri göstermek için resim sınıflandırma örneğindeki bazı önemli bölümler vurgulanacaktır.

Görüntü sınıflandırma örneğinin ayrıntılı incelemesi

Model bilgileri

Meta veriler, yeni bir model bilgisi oluşturularak başlar:

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

Giriş / çıkış bilgileri

Bu bölümde, modelinizin giriş ve çıkış imzasını nasıl açıklayacağınız gösterilmektedir. Bu meta veriler, otomatik kod oluşturucular tarafından ön ve son işleme kodu oluşturmak için kullanılabilir. Bir tensör hakkında giriş veya çıkış bilgileri oluşturmak için:

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

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

Resim girişi

Görüntü, makine öğreniminde yaygın bir giriş türüdür. LiteRT meta verileri, renk alanı ve normalleştirme gibi ön işleme bilgileri gibi bilgileri destekler. Görüntünün boyutu, giriş tensörünün şekli tarafından sağlandığı ve otomatik olarak çıkarılabildiği için manuel olarak belirtilmesini gerektirmez.

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

Etiket çıkışı

Etiket, TENSOR_AXIS_LABELS kullanılarak ilişkili bir dosya aracılığıyla çıkış tensörüne eşlenebilir.

# 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]

Meta veri Flatbuffer'larını oluşturma

Aşağıdaki kod, model bilgilerini giriş ve çıkış bilgileriyle birleştirir:

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

Paket meta verilerini ve ilişkili dosyaları modele yerleştirme

Meta veri Flatbuffers oluşturulduktan sonra, meta veriler ve etiket dosyası populate yöntemiyle TFLite dosyasına yazılır:

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

load_associated_files ile istediğiniz sayıda ilişkili dosyayı modele paketleyebilirsiniz. Ancak meta verilerde belgelenen dosyaların en azından paketlenmesi gerekir. Bu örnekte, etiket dosyasının paketlenmesi zorunludur.

Meta verileri görselleştirme

Meta verilerinizi görselleştirmek için Netron'u kullanabilir veya MetadataDisplayer kullanarak meta verileri bir LiteRT modelinden json biçiminde okuyabilirsiniz:

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, meta verilerin Android Studio ML Binding özelliği aracılığıyla gösterilmesini de destekler.

Meta veri sürümü oluşturma

Meta veri şeması, hem şema dosyasındaki değişiklikleri izleyen Semantik sürüm oluşturma numarası hem de gerçek sürüm uyumluluğunu gösteren Flatbuffers dosya tanımlaması ile sürüm oluşturulur.

Semantik sürüm oluşturma numarası

Meta veri şeması, anlamsal sürüm oluşturma numarası (ör. MAJOR.MINOR.PATCH) ile sürüm oluşturulur. Buradaki kurallara göre şema değişikliklerini izler. 1.0.0 sürümünden sonra eklenen alanların geçmişini görün.

Flatbuffers dosya tanımlaması

Anlamsal sürüm oluşturma, kurallara uyulduğu takdirde uyumluluğu garanti eder ancak gerçek uyumsuzluğu ifade etmez. MAJOR numarası artırıldığında geriye dönük uyumluluğun bozulduğu anlamına gelmez. Bu nedenle, meta veri şemasının gerçek uyumluluğunu belirtmek için Flatbuffers dosyası tanımlama, file_identifier kullanılır. Dosya tanımlayıcısı tam olarak 4 karakter uzunluğundadır. Belirli bir meta veri şemasına sabitlenmiştir ve kullanıcılar tarafından değiştirilemez. Meta veri şemasının geriye dönük uyumluluğunun herhangi bir nedenle bozulması gerekirse file_identifier, örneğin "M001"den "M002"ye yükseltilir. File_identifier'ın metadata_version'dan çok daha az sıklıkta değiştirilmesi beklenir.

Gerekli minimum meta veri ayrıştırıcı sürümü

Gerekli minimum meta veri ayrıştırıcı sürümü, meta veri Flatbuffers'ı tam olarak okuyabilen meta veri ayrıştırıcının (Flatbuffers tarafından oluşturulan kod) minimum sürümüdür. Sürüm, doldurulan tüm alanların sürümleri arasındaki en büyük sürüm numarası ve dosya tanımlayıcısı tarafından belirtilen en küçük uyumlu sürümdür. Gerekli minimum meta veri ayrıştırıcı sürümü, meta veriler bir TFLite modeline doldurulduğunda MetadataPopulator tarafından otomatik olarak doldurulur. Gerekli minimum meta veri ayrıştırıcı sürümünün nasıl kullanıldığı hakkında daha fazla bilgi için meta veri ayıklayıcı bölümüne bakın.

Modellerdeki meta verileri okuma

Metadata Extractor kitaplığı, farklı platformlardaki modellerden meta verileri ve ilişkili dosyaları okumak için kullanışlı bir araçtır (Java sürümüne ve C++ sürümüne bakın). Flatbuffers kitaplığını kullanarak diğer dillerde kendi meta veri ayıklama aracınızı oluşturabilirsiniz.

Java'da meta verileri okuma

Android uygulamanızda Metadata Extractor kitaplığını kullanmak için MavenCentral'da barındırılan LiteRT Metadata AAR'yi kullanmanızı öneririz. MetadataExtractor sınıfının yanı sıra meta veri şeması ve model şeması için FlatBuffers Java bağlamalarını içerir.

Bunu build.gradle bağımlılıklarınızda aşağıdaki gibi belirtebilirsiniz:

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

Gece alınan anlık görüntüleri kullanmak için Sonatype anlık görüntü deposunu eklediğinizden emin olun.

MetadataExtractor nesnesini, modele işaret eden bir ByteBuffer ile başlatabilirsiniz:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer, MetadataExtractor nesnesinin kullanım ömrü boyunca değişmeden kalmalıdır. Model meta verilerinin Flatbuffers dosyası tanımlayıcısı, meta veri ayrıştırıcısının tanımlayıcısıyla eşleşmiyorsa başlatma işlemi başarısız olabilir. Daha fazla bilgi için meta veri sürümü oluşturma konusuna bakın.

Dosya tanımlayıcıları eşleştirildiğinde, meta veri ayıklayıcı, Flatbuffers'ın ileri ve geri uyumluluk mekanizması sayesinde geçmiş ve gelecekteki tüm şemalardan oluşturulan meta verileri başarıyla okur. Ancak gelecekteki şemalardaki alanlar, eski meta veri ayıklayıcılar tarafından ayıklanamaz. Meta verilerin minimum gerekli ayrıştırıcı sürümü, meta veri Flatbuffers'ı tam olarak okuyabilen meta veri ayrıştırıcısının minimum sürümünü gösterir. Gerekli minimum ayrıştırıcı sürümü koşulunun karşılanıp karşılanmadığını doğrulamak için aşağıdaki yöntemi kullanabilirsiniz:

public final boolean isMinimumParserVersionSatisfied();

Meta veriler olmadan model iletmek mümkündür. Ancak meta verilerden okuma yapan yöntemlerin çağrılması, çalışma zamanı hatalarına neden olur. Bir modelin meta verileri olup olmadığını hasMetadata yöntemini çağırarak kontrol edebilirsiniz:

public boolean hasMetadata();

MetadataExtractor, giriş/çıkış tensörlerinin meta verilerini almanızı sağlayan kullanışlı işlevler sunar. Örneğin,

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

LiteRT model şeması birden fazla alt grafiği desteklese de TFLite yorumlayıcı şu anda yalnızca tek bir alt grafiği desteklemektedir. Bu nedenle, MetadataExtractor, yöntemlerinde alt grafik dizinini giriş bağımsız değişkeni olarak atlar.

Modellerdeki ilişkili dosyaları okuma

Meta verileri ve ilişkili dosyaları içeren LiteRT modeli, ilişkili dosyaları almak için yaygın ZIP araçlarıyla açılabilen bir ZIP dosyasıdır. Örneğin, mobilenet_v1_0.75_160_quantized dosyasını aşağıdaki gibi açıp modeldeki etiket dosyasını çıkarabilirsiniz:

$ 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

Ayrıca, ilişkili dosyaları Metadata Extractor kitaplığı aracılığıyla da okuyabilirsiniz.

Java'da dosya adını MetadataExtractor.getAssociatedFile yöntemine iletin:

public InputStream getAssociatedFile(String fileName);

Benzer şekilde, C++'ta bu işlem ModelMetadataExtractor::GetAssociatedFile yöntemiyle yapılabilir:

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