TensorFlow Lite modellerine meta veri ekleme

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

Kaggle Modelleri'nde yayınlanan tüm görüntü modelleri meta verilerle dolduruldu.

Meta veri biçimine sahip model

model_with_metadata
Şekil 1. Meta veriler 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 model şemasının metadata alanında "TFLITE_METADATA" adı altında depolanır. Bazı modeller, sınıflandırma etiketi dosyaları gibi ilişkili dosyalarla birlikte gelebilir. Bu dosyalar, ZipFile "ekleme" modu ('a' modu) kullanılarak, orijinal model dosyasının sonuna bir ZIP dosyası olarak birleştirilir. TFLite Çevirmen, yeni dosya biçimini öncekiyle aynı şekilde kullanabilir. Daha fazla bilgi için İlişkili dosyaları paketleme bölümüne bakın.

Meta verileri doldurma, görselleştirme ve okuma ile ilgili aşağıdaki talimata bakın.

Meta veri araçlarını ayarlayın

Modelinize meta veri eklemeden önce, TensorFlow'u çalıştırmak için bir Python programlama ortamı kurulumuna ihtiyacınız vardır. Bu ayarın nasıl yapılacağıyla ilgili ayrıntılı kılavuzu burada bulabilirsiniz.

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

pip install tflite-support

TensorFlow Lite meta veri araçları, Python 3'ü destekler.

Flatbuffers Python API 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 konusuna bakın.
    1. Giriş bilgileri: Girişlerin ve normalleştirme gibi gerekli ön işlemlerin açıklaması. SubGraphMetadata.input_tensor_metadata bölümüne bakın.
      1. Çıkış bilgileri: Çıkışın açıklaması ve etiketlere eşleme gibi gerekli işleme sonrası. SubGraphMetadata.output_tensor_metadata bölümüne bakın.

TensorFlow Lite bu noktada yalnızca tek bir alt grafiği desteklediğinden, TensorFlow Lite 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 TensorFlow Lite meta verileri, belirli model türleri dikkate alınarak tasarlanmamış, bunun yerine giriş ve çıkış türleri düşünülerek tasarlanmıştır. Giriş ve çıkış türleri aşağıdakilerden veya aşağıdakilerin bir kombinasyonundan oluştuğu sürece modelin işlevsel olarak ne yaptığı önemli değildir. Model, TensorFlow Lite meta verileri tarafından desteklenir:

  • Özellik: İmzalanmamış tam sayılar veya kayan noktalı sayılardır.
  • 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.

İlgili dosyaları paketleyin

TensorFlow Lite modelleri farklı ilişkili dosyalarla gelebilir. Örneğin, doğal dil modelleri genellikle kelime parçalarını kelime kimlikleriyle eşleyen kelime bilgisi dosyalarına sahiptir. Sınıflandırma modellerinde nesne kategorilerini belirten etiket dosyaları bulunabilir. İlişkili dosyalar (varsa) olmadan model düzgün çalışmaz.

İlişkili dosyalar artık meta veri Python kitaplığı aracılığıyla modelle birlikte paketlenebilir. Yeni TensorFlow Lite modeli, hem modeli hem de ilişkili dosyaları içeren bir ZIP dosyası hâline gelir. Yaygın olarak kullanılan zip araçlarıyla açılabilir. Bu yeni model biçimi, aynı dosya uzantısını (.tflite) kullanmaya devam ediyor. Mevcut TFLite çerçevesi ve Çevirmeni ile uyumludur. Daha fazla ayrıntı için Meta verileri ve ilişkili dosyaları modele paketleme bölümüne 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, TensorFlow Lite Android kod oluşturucu otomatik olarak nesneye karşılık gelen ön/son işleme uygulayabilir. Daha fazla ayrıntı için şemadaki her ilişkilendirme dosya türünün <Codegen kullanımı> bölümüne bakın.

Normalleştirme ve niceleme 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çekte değiştirmektir.

Model niceleme, ağırlıkların daha düşük hassasiyet temsili ve isteğe bağlı olarak hem depolama hem de hesaplama için etkinleştirme olanağı tanıyan bir tekniktir.

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

Normalleştirme Nicelendirme

Sırasıyla kayan ve nicel modeller için MobileNet'teki giriş görüntüsünün parametre değerlerinin örneği.
Kayan noktalı model:
- ortalama: 127,5
- std: 127,5
Nicelik modeli:
- ortalama: 127,5
- std: 127,5
Kayan noktalı model:
- sıfır Nokta: 0
- ölçek: 1,0
Nice model:
- zeroPoint: 128,0
- ölçek:0.0078125f




Ne zaman çağrılmalı?


Girişler: Giriş verileri eğitimde normalleştirilirse çıkarım giriş verilerinin buna uygun şekilde normalleştirilmesi gerekir.
Çıkışlar: Çıkış verileri genel olarak normalleştirilmez.
Kayanlık modellerinde nicelik belirleme gerekmez.
Nicelleştirilmiş model, öncesi/sonrası işlemede nicelik olarak ölçülebilir veya gerekmeyebilir. Bu, giriş/çıkış tensörlerinin veri türüne bağlıdır.
- kayan tensörler: Ön/son işlemede miktar belirleme gerekmez. Niceliksel işlem ve dequant işlemi model grafiğine eklenir.
- int8/uint8 tensörleri: Öncesi/sonrası işlemede miktarların ölçülmesi gerekir.


Formülü


normalized_input = (giriş - ortalama) / std
Girişler için nicelleştirme:
q = f / ölçek + zeroPoint
Çıkışlar için miktar olarak ayrıştır:
f = (q - zeroPoint) * ölçek

Parametreler
Model oluşturucu tarafından doldurulur ve model meta verilerinde NormalizationOptions TFLite dönüştürücü tarafından otomatik olarak doldurulur ve tflite model dosyasında depolanır.
Parametreler nasıl alınır? MetadataExtractor API aracılığıyla [2] TFLite Tensor API [1] veya MetadataExtractor API [2]
Bolluk ve nicel modeller aynı değeri mi paylaşır? Evet, bolluk ve miktar modelleri aynı normalleştirme parametrelerine sahiptir. Hayır, kayan model için nicel belirleme gerekmez.
TFLite kod oluşturucu veya Android Studio ML bağlaması veri işleme sırasında kod oluşturucuyu otomatik olarak oluşturur mu?
Evet

Evet

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

uint8 modelleri için görüntü verileri işlenirken normalleştirme ve miktar belirleme bazen atlanır. Piksel değerleri [0, 255] aralığında olduğunda bunu yapabilirsiniz. Ancak genel olarak, verileri uygun olduğunda her zaman normalleştirme ve niceleme parametrelerine göre işlemeniz gerekir.

Örnekler

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

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

Meta verileri mobilenet_v1_0.75_160_quantized.tflite olarak dolduran komut dosyasını buradan indirebilirsiniz. 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 modellerine ait meta verileri doldurmak için komut dosyasına bunun gibi model özelliklerini ekleyin. Bu kılavuzun geri kalanında, önemli öğeleri göstermek için görüntü sınıflandırma örneğindeki önemli bölümlerden bazıları vurgulanacaktır.

Resim sınıflandırma örneğini ayrıntılı olarak inceleme

Model bilgileri

Meta veri, yeni bir model bilgisi oluşturarak 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ın nasıl açıklanacağı gösterilmektedir. Bu meta veriler, otomatik kod oluşturucular tarafından işleme öncesi ve sonrası kod 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

Resim, makine öğreniminde yaygın olarak kullanılan bir giriş türüdür. TensorFlow Lite meta verileri, renk alanı gibi bilgileri ve normalleştirme gibi ön işleme bilgilerini destekler. Resmin boyutu, zaten giriş tensörünün şekliyle sağlandığı ve otomatik olarak tahmin edilebileceği için manuel belirtim 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 bir çıkış tensörüyle 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 Flatbuffers 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()

Meta verileri ve ilişkili dosyaları modele paketleyin

Meta veri Flatbuffers oluşturulduktan sonra meta veriler ve etiket dosyası populate yöntemi kullanılarak 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 aracılığıyla modele istediğiniz kadar ilişkili dosyayı paketleyebilirsiniz. Ancak, meta veride belgelenen en azından bu dosyaları paketlemek 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 yöntemini kullanarak meta verileri bir TensorFlow Lite modelinden json biçimine dönüştürebilirsiniz:

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, Android Studio ML Bağlama özelliği aracılığıyla meta verilerin görüntülenmesini 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 kimliği ile sürümlandırılır.

Anlamsal sürüm numarası

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

Flatbuffers dosya kimliği

Anlamsal sürüm oluşturma, kurallara uyulması halinde uyumluluğu garanti eder, ancak gerçek uyumsuzluk olduğu anlamına gelmez. MAJOR sayısının yükseltilmesi, 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 dosya kimliği (file_identifier) kullanılır. Dosya tanımlayıcısı tam olarak 4 karakter uzunluğundadır. Belirli bir meta veri şemasına sabittir ve kullanıcılar tarafından değişikliğe tabi değildir. Meta veri şemasının geriye dönük uyumluluğunun bir nedenden dolayı bozulması gerekirse file_identifier, örneğin "M001"den "M002"ye doğru yükselir. File_identifier'nın, meta veri_version'a göre çok daha az 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ında etkili olarak 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. Meta veriler bir TFLite modeline doldurulduğunda, gereken minimum meta veri ayrıştırıcı sürümü 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ıya bakın.

Modellerden meta verileri okuma

Meta Veri Ayıklayıcı 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ıklayıcı aracınızı oluşturabilirsiniz.

Java'da meta verileri okuma

Android uygulamanızda Meta Veri Ayıklayıcı kitaplığını kullanmak için MavenCentral'da barındırılan TensorFlow Lite Metadata AAR'yı 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 şekilde belirtebilirsiniz:

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

Gecelik anlık görüntüleri kullanmak için Sonatype anlık görüntü deposu'nu eklediğinizden emin olun.

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

public MetadataExtractor(ByteBuffer buffer);

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

Meta veri ayıklayıcı, eşleşen dosya tanımlayıcılarıyla Flatbuffers'ın ileri ve geriye dönük uyumluluk mekanizması nedeniyle 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 çıkarılamaz. Meta verinin gerekli minimum ayrıştırıcı sürümü, meta veri Flatbuffers'ı tam olarak okuyabilen minimum meta veri ayrıştırıcı sürümünü belirtir. 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 verileri olmayan bir modelin geçirilmesine izin verilir. Ancak, meta verilerden okunan yöntemlerin çağrılması çalışma zamanı hatalarına neden olur. hasMetadata yöntemini çağırarak bir modelin meta veri içerip içermediğini kontrol edebilirsiniz:

public boolean hasMetadata();

MetadataExtractor, giriş/çıkış tensörlerinin meta verilerini almanız için kullanışlı işlevler sağlar. Ö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);

TensorFlow Lite model şeması birden çok alt grafiği desteklese de, TFLite Çevirmen şu anda yalnızca tek bir alt grafiği desteklemektedir. Bu nedenle MetadataExtractor, yöntemlerinde giriş bağımsız değişkeni olarak alt grafik dizinini atlar.

Modellerden ilişkili dosyaları okuma

Meta veriler ve ilişkili dosyalar içeren TensorFlow Lite modeli aslında, 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çıp modeldeki etiket dosyasını şu şekilde ayıklayabilirsiniz:

$ 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

İlişkili dosyaları Meta Veri Ayıklayıcı 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;