Menambahkan metadata ke model TensorFlow Lite

Metadata TensorFlow Lite menyediakan standar untuk deskripsi model. Metadata adalah sumber pengetahuan penting tentang fungsi model dan informasi input / output-nya. {i>Metadata<i} terdiri dari

Semua model gambar yang dipublikasikan di TensorFlow Hub telah diisi dengan metadata.

Model dengan format metadata

model_with_metadata
Gambar 1. Model TFLite dengan metadata dan file terkait.

Metadata model ditentukan dalam metadata_schema.fbs, file FlatBuffer. Seperti ditunjukkan dalam Gambar 1, jenis data ini disimpan di kolom metadata dari skema model TFLite, dengan nama, "TFLITE_METADATA". Beberapa model mungkin dilengkapi dengan file terkait, seperti file label klasifikasi. File-file ini digabungkan ke akhir file model asli sebagai ZIP menggunakan mode"append" ZipFile (mode 'a'). TFLite Interpreter dapat menggunakan format {i>file<i} baru dengan cara yang sama seperti sebelumnya. Lihat Memaketkan file terkait untuk mengetahui informasi selengkapnya.

Lihat petunjuk di bawah tentang cara mengisi, memvisualisasikan, dan membaca metadata.

Menyiapkan alat metadata

Sebelum menambahkan metadata ke model, Anda perlu menyiapkan lingkungan pemrograman Python untuk menjalankan TensorFlow. Panduan terperinci tentang cara menyiapkannya dapat dibaca di sini.

Setelah menyiapkan lingkungan pemrograman Python, Anda perlu menginstal alat tambahan:

pip install tflite-support

Alat metadata TensorFlow Lite mendukung Python 3.

Menambahkan metadata menggunakan Flatbuffers Python API

Ada tiga bagian dari metadata model dalam skema:

  1. Informasi model - Deskripsi keseluruhan model serta item seperti istilah lisensi. Lihat ModelMetadata.
  2. Informasi input - Deskripsi input dan pra-pemrosesan yang diperlukan seperti normalisasi. Lihat SubGraphMetadata.input_tensor_metadata.
  3. Informasi output - Deskripsi output dan pascapemrosesan yang diperlukan seperti pemetaan ke label. Lihat SubGraphMetadata.output_tensor_metadata.

Karena pada tahap ini TensorFlow Lite hanya mendukung subgrafik tunggal, generator kode TensorFlow Lite dan fitur ML Binding Android Studio akan menggunakan ModelMetadata.name dan ModelMetadata.description, bukan SubGraphMetadata.name dan SubGraphMetadata.description, saat menampilkan metadata dan membuat kode.

Jenis Input / Output yang didukung

Metadata TensorFlow Lite untuk input dan output tidak dirancang dengan mempertimbangkan jenis model tertentu, melainkan jenis input dan output. Apa pun fungsi model secara fungsional, selama jenis input dan output terdiri dari hal berikut atau kombinasi berikut, model akan didukung oleh metadata TensorFlow Lite:

  • Fitur - Angka yang merupakan bilangan bulat tanpa tanda atau float32.
  • Gambar - Metadata saat ini mendukung gambar RGB dan hitam putih.
  • Kotak pembatas - Kotak pembatas berbentuk persegi panjang. Skema ini mendukung berbagai skema penomoran.

Mengemas file terkait

Model TensorFlow Lite dapat dilengkapi dengan file terkait yang berbeda. Misalnya, model bahasa natural biasanya memiliki file kosakata yang memetakan potongan kata ke ID kata; model klasifikasi mungkin memiliki file label yang menunjukkan kategori objek. Tanpa file terkait (jika ada), model tidak akan berfungsi dengan baik.

File terkait kini dapat dipaketkan dengan model melalui library metadata Python. Model TensorFlow Lite baru menjadi file zip yang berisi model dan file terkait. Paket dapat dibuka dengan alat zip umum. Format model baru ini terus menggunakan ekstensi file yang sama, .tflite. API ini kompatibel dengan framework TFLite dan Interpreter yang ada. Baca Memaketkan metadata dan file terkait ke dalam model untuk mengetahui detail selengkapnya.

Informasi file terkait dapat direkam dalam metadata. Bergantung pada jenis file dan tempat file dilampirkan (yaitu ModelMetadata, SubGraphMetadata, dan TensorMetadata), generator kode Android TensorFlow Lite dapat otomatis menerapkan pemrosesan pra/pasca yang sesuai ke objek. Lihat bagian <Codegen usage> untuk setiap jenis file terkait dalam skema untuk mengetahui detail selengkapnya.

Parameter normalisasi dan kuantisasi

Normalisasi adalah teknik pra-pemrosesan data yang umum dalam machine learning. Tujuan normalisasi adalah untuk mengubah nilai ke skala umum, tanpa mengganggu perbedaan dalam rentang nilai.

Kuantisasi model adalah teknik yang memungkinkan pengurangan representasi bobot yang presisi dan , secara opsional, aktivasi untuk penyimpanan dan komputasi.

Dalam hal prapemrosesan dan pascapemrosesan, normalisasi dan kuantisasi adalah dua langkah independen. Berikut detailnya.

Normalisasi Kuantisasi

Contoh parameter value gambar input di MobileNet masing-masing untuk model float dan quant.
Model floating:
- rata-rata: 127.5
- std: 127.5
Model Quant:
- mean: 127.5
- std: 127.5
Model floating:
- zeroPoint: 0
- skala: 1,0
Model kuant:
- zeroPoint: 128.0
- scale:0.0078125f




Kapan harus memanggil?


Input: Jika data input dinormalkan dalam pelatihan, data input inferensi perlu dinormalkan sebagaimana mestinya.
Output: data output tidak akan dinormalisasi secara umum.
Model floating tidak memerlukan kuantisasi.
Model terkuantisasi mungkin atau mungkin tidak memerlukan kuantisasi dalam pra/pasca-pemrosesan. Hal ini bergantung pada jenis data tensor input/output.
- tensor float: tidak ada kuantisasi dalam pra/pascapemrosesan yang diperlukan. Quant op dan dequant op dimasukkan ke dalam grafik model.
- tensor int8/uint8: memerlukan kuantisasi dalam pra/pasca pemrosesan.


Formula


normalized_input = (input - rata-rata) / std
Kuantisasi untuk input:
q = f / scale + zeroPoint
Dequantize untuk output:
f = (q - zeroPoint) * scale

Di mana parameternya
Diisi oleh pembuat model dan disimpan dalam metadata model, sebagai NormalizationOptions Diisi secara otomatis oleh konverter TFLite, dan disimpan dalam file model tflite.
Bagaimana cara mendapatkan parameternya? Melalui MetadataExtractor API [2] Melalui TFLite Tensor API [1] atau melalui MetadataExtractor API [2]
Apakah model {i>float<i} dan kuantitas memiliki nilai yang sama? Ya, model float dan quant memiliki parameter Normalisasi yang sama Tidak, model {i>float<i} tidak perlu kuantisasi.
Apakah generator Kode TFLite atau binding ML Android Studio secara otomatis membuatnya dalam pemrosesan data?
Ya

Ya

[1] TensorFlow Lite Java API dan TensorFlow Lite C++ API.
[2] Library ekstraktor metadata

Saat memproses data gambar untuk model uint8, normalisasi dan kuantisasi terkadang dilewati. Anda boleh melakukannya jika nilai piksel berada dalam rentang [0, 255]. Namun secara umum, Anda harus selalu memproses data sesuai dengan parameter normalisasi dan kuantisasi jika berlaku.

Contoh

Anda dapat menemukan contoh cara mengisi metadata untuk berbagai jenis model di sini:

Klasifikasi gambar

Download skrip di sini, yang mengisi metadata ke mobilenet_v1_0.75_160_quantized.tflite. Jalankan skrip seperti ini:

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

Guna mengisi metadata untuk model klasifikasi gambar lainnya, tambahkan spesifikasi model seperti ini ke dalam skrip. Bagian selanjutnya dari panduan ini akan menyoroti beberapa bagian penting dalam contoh klasifikasi gambar untuk mengilustrasikan elemen utama.

Mempelajari lebih dalam contoh klasifikasi gambar

Informasi model

Metadata dimulai dengan membuat info model baru:

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

Informasi input / output

Bagian ini menunjukkan cara mendeskripsikan tanda tangan input dan output model Anda. Metadata ini dapat digunakan oleh generator kode otomatis untuk membuat kode sebelum dan sesudah pemrosesan. Untuk membuat informasi input atau output tentang tensor:

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

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

Input gambar

Gambar adalah jenis input yang umum untuk machine learning. Metadata TensorFlow Lite mendukung informasi seperti ruang warna dan informasi pra-pemrosesan seperti normalisasi. Dimensi gambar tidak memerlukan spesifikasi manual karena telah disediakan oleh bentuk tensor input dan dapat secara otomatis ditentukan.

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

Output label

Label dapat dipetakan ke tensor output melalui file terkait menggunakan 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]

Membuat Flatbuffer metadata

Kode berikut menggabungkan informasi model dengan informasi input dan output:

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

Mengemas metadata dan file terkait ke dalam model

Setelah Flatbuffer metadata dibuat, metadata dan file label akan ditulis ke dalam file TFLite melalui metode 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()

Anda dapat mengemas file terkait sebanyak yang Anda inginkan ke dalam model melalui load_associated_files. Namun, Anda harus mengemas setidaknya file yang didokumentasikan dalam metadata. Dalam contoh ini, pengemasan file label bersifat wajib.

Memvisualisasikan {i>metadata<i}

Anda dapat menggunakan Netron untuk memvisualisasikan metadata, atau membaca metadata dari model TensorFlow Lite ke dalam format json menggunakan 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 juga mendukung penayangan metadata melalui fitur ML Binding Android Studio.

Pembuatan versi metadata

Skema metadata dibuat berdasarkan nomor pembuatan versi Semantik, yang melacak perubahan file skema, dan dengan identifikasi file Flatbuffers, yang menunjukkan kompatibilitas versi yang sebenarnya.

Nomor pembuatan versi Semantik

Skema metadata dibuat menurut Nomor pembuatan versi semantik, seperti MAJOR.MINOR.PATCH. Fitur ini melacak perubahan skema sesuai dengan aturan di sini. Lihat histori kolom yang ditambahkan setelah versi 1.0.0.

Identifikasi file Flatbuffers

Pembuatan versi semantik menjamin kompatibilitas jika mengikuti aturan, tetapi tidak berarti inkompatibilitas yang sebenarnya. Saat menambahkan angka MAJOR, itu bukan berarti kompatibilitas mundur rusak. Oleh karena itu, kami menggunakan Identifikasi file Flatbuffers, file_identifier, untuk menunjukkan kompatibilitas yang sebenarnya dari skema metadata. Panjang ID file adalah tepat 4 karakter. Atribut ini tetap mengikuti skema metadata tertentu dan tidak dapat berubah oleh pengguna. Jika kompatibilitas mundur skema metadata harus rusak karena beberapa alasan, file_identifier akan muncul, misalnya, dari “M001” ke “M002”. File_identifier diharapkan lebih jarang diubah daripada metadata_version.

Versi parser metadata minimum yang diperlukan

Versi parser metadata minimum yang diperlukan adalah versi minimum parser metadata (kode yang dihasilkan Flatbuffers) yang dapat membaca Flatbuffer metadata secara penuh. Versi ini pada dasarnya adalah nomor versi terbesar di antara versi semua kolom yang diisi dan versi kompatibel terkecil yang ditunjukkan oleh ID file. Versi parser metadata minimum yang diperlukan akan otomatis diisi oleh MetadataPopulator saat metadata diisi ke model TFLite. Lihat ekstraktor metadata untuk mengetahui informasi selengkapnya tentang cara penggunaan versi parser metadata minimum yang diperlukan.

Membaca metadata dari model

Library Metadata Extractor adalah alat yang mudah digunakan untuk membaca metadata dan file terkait dari suatu model di berbagai platform (lihat Versi Java dan versi C++). Anda dapat membuat alat ekstraktor metadata sendiri dalam bahasa lain menggunakan library Flatbuffers.

Membaca metadata di Java

Untuk menggunakan library Ekstraktor Metadata di aplikasi Android, sebaiknya gunakan AAR Metadata TensorFlow Lite yang dihosting di MavenCentral. Class ini berisi class MetadataExtractor, serta binding Java FlatBuffers untuk skema metadata dan skema model.

Anda dapat menentukan hal ini dalam dependensi build.gradle sebagai berikut:

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

Untuk menggunakan snapshot setiap malam, pastikan Anda telah menambahkan repositori snapshot Soatype.

Anda dapat melakukan inisialisasi objek MetadataExtractor dengan ByteBuffer yang mengarah ke model:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer tidak boleh diubah selama masa aktif objek MetadataExtractor. Inisialisasi mungkin gagal jika ID file Flatbuffers metadata model tidak cocok dengan parser metadata. Lihat pembuatan versi metadata untuk mengetahui informasi lebih lanjut.

Dengan ID file yang cocok, ekstraktor metadata akan berhasil membaca metadata yang dihasilkan dari semua skema sebelumnya dan mendatang karena mekanisme kompatibilitas maju dan mundur Flatbuffer. Namun, kolom dari skema mendatang tidak dapat diekstrak oleh ekstraktor metadata yang lebih lama. Versi parser minimum yang diperlukan dari metadata menunjukkan versi minimum parser metadata yang dapat membaca Flatbuffer metadata secara penuh. Anda dapat menggunakan metode berikut untuk memverifikasi apakah kondisi versi parser minimum yang diperlukan terpenuhi:

public final boolean isMinimumParserVersionSatisfied();

Meneruskan model tanpa metadata diizinkan. Namun, memanggil metode yang membaca dari metadata akan menyebabkan error runtime. Anda dapat memeriksa apakah model memiliki metadata dengan memanggil metode hasMetadata:

public boolean hasMetadata();

MetadataExtractor menyediakan fungsi yang mudah bagi Anda untuk mendapatkan metadata tensor input/output. Misalnya,

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

Meskipun skema model TensorFlow Lite mendukung beberapa subgrafik, Interpreter TFLite saat ini hanya mendukung satu subgrafik. Oleh karena itu, MetadataExtractor menghilangkan indeks subgrafik sebagai argumen input dalam metodenya.

Membaca file terkait dari model

Model TensorFlow Lite dengan metadata dan file terkait pada dasarnya adalah file zip yang dapat diekstrak dengan alat zip umum untuk mendapatkan file terkait. Misalnya, Anda dapat mengekstrak mobilenet_v1_0.75_160_quantized dan mengekstrak file label dalam model sebagai berikut:

$ 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

Anda juga dapat membaca file terkait melalui library Metadata Extractor.

Di Java, teruskan nama file ke dalam metode MetadataExtractor.getAssociatedFile:

public InputStream getAssociatedFile(String fileName);

Demikian pula, pada C++, hal ini dapat dilakukan dengan metode, ModelMetadataExtractor::GetAssociatedFile:

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