Menambahkan metadata ke model TensorFlow Lite

Metadata TensorFlow Lite memberikan standar untuk deskripsi model. Metadata adalah sumber pengetahuan penting tentang apa yang dilakukan model dan informasi masukan/keluarannya. Metadata terdiri dari keduanya

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

Model dengan format metadata

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

Metadata model ditentukan dalam metadata_schema.fbs , file FlatBuffer . Seperti yang ditunjukkan pada Gambar 1, ini disimpan di bidang metadata 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 "tambahkan" ZipFile (mode 'a' ). TFLite Interpreter dapat menggunakan format file baru dengan cara yang sama seperti sebelumnya. Lihat Mengemas file terkait untuk informasi lebih lanjut.

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

Siapkan alat metadata

Sebelum menambahkan metadata ke model, Anda perlu menyiapkan lingkungan pemrograman Python untuk menjalankan TensorFlow. Ada panduan terperinci tentang cara mengaturnya di sini .

Setelah mengatur lingkungan pemrograman Python, Anda perlu menginstal peralatan tambahan:

pip install tflite-support

Alat metadata TensorFlow Lite mendukung Python 3.

Menambahkan metadata menggunakan Flatbuffers Python API

Ada tiga bagian metadata model dalam skema :

  1. Informasi model - Deskripsi keseluruhan model serta item seperti persyaratan lisensi. Lihat ModelMetadata .
  2. Informasi masukan - Deskripsi masukan dan pra-pemrosesan yang diperlukan seperti normalisasi. Lihat SubGraphMetadata.input_tensor_metadata .
  3. Informasi keluaran - Deskripsi keluaran dan pasca-pemrosesan yang diperlukan seperti pemetaan ke label. Lihat SubGraphMetadata.output_tensor_metadata .

Karena TensorFlow Lite saat ini hanya mendukung satu subgraf, pembuat kode TensorFlow Lite dan fitur Android Studio ML Binding 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 tipe model tertentu, melainkan tipe input dan output. Apa pun fungsi model yang dilakukan, selama jenis input dan output terdiri dari atau kombinasi berikut ini, model tersebut didukung oleh metadata TensorFlow Lite:

  • Fitur - Angka yang merupakan bilangan bulat tidak bertanda tangan atau float32.
  • Gambar - Metadata saat ini mendukung gambar RGB dan skala abu-abu.
  • Kotak pembatas - Kotak pembatas berbentuk persegi panjang. Skema ini mendukung berbagai skema penomoran .

Kemas file terkait

Model TensorFlow Lite mungkin dilengkapi dengan berbagai file terkait. Misalnya, model bahasa alami biasanya memiliki file vocab 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 digabungkan dengan model melalui pustaka metadata Python. Model TensorFlow Lite baru menjadi file zip yang berisi model dan file terkait. Itu dapat dibongkar dengan alat zip umum. Format model baru ini tetap menggunakan ekstensi file yang sama, .tflite . Ini kompatibel dengan kerangka dan Interpreter TFLite yang ada. Lihat Mengemas metadata dan file terkait ke dalam model untuk 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 menerapkan pemrosesan pra/pasca terkait secara otomatis ke objek. Lihat bagian <Codegen usage> dari setiap jenis file terkait dalam skema untuk detail selengkapnya.

Parameter normalisasi dan kuantisasi

Normalisasi adalah teknik prapemrosesan data yang umum dalam pembelajaran mesin. Tujuan normalisasi adalah mengubah nilai ke skala yang sama, tanpa mendistorsi perbedaan rentang nilai.

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

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

Normalisasi Kuantisasi

Contoh nilai parameter gambar masukan di MobileNet untuk model float dan quant.
Model terapung :
- rata-rata : 127,5
- standar: 127,5
Model kuantitas :
- rata-rata : 127,5
- standar: 127,5
Model terapung :
- titik nol: 0
- Skala : 1.0
Model kuantitas :
- Titik nol: 128.0
- skala: 0,0078125f




Kapan harus memohon?


Masukan : Jika data masukan dinormalisasi dalam pelatihan, data masukan inferensi perlu dinormalisasi.
Output : data keluaran tidak akan dinormalisasi secara umum.
Model float tidak memerlukan kuantisasi.
Model terkuantisasi mungkin memerlukan atau tidak memerlukan kuantisasi dalam pra/pasca pemrosesan. Itu tergantung pada tipe data tensor input/output.
- tensor float: tidak diperlukan kuantisasi sebelum/sesudah pemrosesan. Operasi kuantitas dan operasi dequant dimasukkan ke dalam grafik model.
- tensor int8/uint8: memerlukan kuantisasi dalam sebelum/pasca pemrosesan.


Rumus


normalized_input = (input - rata-rata) / std
Kuantisasi untuk input :
q = f / skala + titik nol
Dekuantisasi untuk keluaran :
f = (q - titik nol) * skala

Dimana 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 API MetadataExtractor [2] Melalui TFLite Tensor API [1] atau melalui MetadataExtractor API [2]
Apakah model float dan quant memiliki nilai yang sama? Ya, model float dan quant memiliki parameter Normalisasi yang sama Tidak, model float tidak memerlukan kuantisasi.
Apakah generator Kode TFLite atau pengikatan Android Studio ML secara otomatis menghasilkannya dalam pemrosesan data?
Ya

Ya

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

Saat memproses data gambar untuk model uint8, normalisasi dan kuantisasi terkadang dilewati. Hal ini boleh dilakukan bila nilai piksel berada dalam kisaran [0, 255]. Namun secara umum, Anda harus selalu memproses data sesuai dengan parameter normalisasi dan kuantisasi jika memungkinkan.

Pustaka Tugas TensorFlow Lite dapat menangani normalisasi untuk Anda jika Anda menyiapkan NormalizationOptions di metadata. Pemrosesan kuantisasi dan dekuantisasi selalu dikemas.

Contoh

Anda dapat menemukan contoh bagaimana metadata harus diisi untuk berbagai jenis model di sini:

Klasifikasi gambar

Unduh 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

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

Pelajari 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 masukan/keluaran

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

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

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

masukan gambar

Gambar adalah jenis masukan umum untuk pembelajaran mesin. Metadata TensorFlow Lite mendukung informasi seperti ruang warna dan informasi pra-pemrosesan seperti normalisasi. Dimensi gambar tidak memerlukan spesifikasi manual karena sudah disediakan oleh bentuk tensor masukan dan dapat disimpulkan secara otomatis.

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

Keluaran label

Label dapat dipetakan ke tensor keluaran 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]

Buat metadata Flatbuffer

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

Kemas metadata dan file terkait ke dalam model

Setelah metadata Flatbuffers dibuat, metadata dan file label 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, diperlukan untuk mengemas setidaknya file-file yang didokumentasikan dalam metadata. Dalam contoh ini, pengepakan file label adalah wajib.

Visualisasikan metadatanya

Anda dapat menggunakan Netron untuk memvisualisasikan metadata, atau Anda dapat 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 tampilan metadata melalui fitur Android Studio ML Binding .

Pembuatan versi metadata

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

Nomor versi Semantik

Skema metadata dibuat berdasarkan nomor versi Semantik , seperti MAJOR.MINOR.PATCH. Ini melacak perubahan skema sesuai dengan aturan di sini . Lihat riwayat bidang yang ditambahkan setelah versi 1.0.0 .

Identifikasi file Flatbuffers

Pembuatan versi semantik menjamin kompatibilitas jika mengikuti aturan, tetapi tidak berarti ketidakcocokan yang sebenarnya. Saat menaikkan angka UTAMA, bukan berarti kompatibilitas mundurnya rusak. Oleh karena itu, kami menggunakan identifikasi file Flatbuffers , file_identifier , untuk menunjukkan kompatibilitas sebenarnya dari skema metadata. Pengidentifikasi file panjangnya tepat 4 karakter. Ini ditetapkan pada skema metadata tertentu dan tidak dapat diubah oleh pengguna. Jika kompatibilitas skema metadata harus rusak karena alasan tertentu, file_identifier akan naik, misalnya, dari “M001” menjadi “M002”. File_identifier diperkirakan akan lebih jarang diubah dibandingkan metadata_version.

Versi pengurai metadata minimum yang diperlukan

Versi pengurai metadata minimum yang diperlukan adalah versi minimum pengurai metadata (kode yang dihasilkan Flatbuffers) yang dapat membaca metadata Flatbuffers secara penuh. Versi ini secara efektif merupakan nomor versi terbesar di antara versi semua bidang yang diisi dan versi terkecil yang kompatibel yang ditunjukkan oleh pengidentifikasi file. Versi pengurai metadata minimum yang diperlukan secara otomatis diisi oleh MetadataPopulator ketika metadata diisi ke dalam model TFLite. Lihat ekstraktor metadata untuk informasi selengkapnya tentang cara menggunakan versi parser metadata minimum yang diperlukan.

Baca metadata dari model

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

Baca metadata di Java

Untuk menggunakan pustaka Metadata Extractor di aplikasi Android Anda, sebaiknya gunakan AAR Metadata TensorFlow Lite yang dihosting di MavenCentral . Ini berisi kelas MetadataExtractor , serta pengikatan FlatBuffers Java untuk skema metadata dan skema model .

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

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

Untuk menggunakan snapshot malam, pastikan Anda telah menambahkan repositori snapshot Sonatype .

Anda dapat menginisialisasi objek MetadataExtractor dengan ByteBuffer yang menunjuk ke model:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer harus tetap tidak berubah selama masa pakai objek MetadataExtractor . Inisialisasi mungkin gagal jika pengidentifikasi file Flatbuffers dari metadata model tidak cocok dengan pengurai metadata. Lihat pembuatan versi metadata untuk informasi lebih lanjut.

Dengan pengidentifikasi file yang cocok, ekstraktor metadata akan berhasil membaca metadata yang dihasilkan dari semua skema masa lalu dan masa depan karena mekanisme kompatibilitas maju dan mundur Flatbuffer. Namun, bidang dari skema masa depan tidak dapat diekstraksi oleh ekstraktor metadata lama. Versi pengurai metadata minimum yang diperlukan menunjukkan versi minimum pengurai metadata yang dapat membaca metadata Flatbuffers secara penuh. Anda dapat menggunakan metode berikut untuk memverifikasi apakah kondisi versi parser minimum yang diperlukan terpenuhi:

public final boolean isMinimumParserVersionSatisfied();

Melewati model tanpa metadata diperbolehkan. Namun, memanggil metode yang membaca metadata akan menyebabkan kesalahan runtime. Anda dapat memeriksa apakah suatu 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 subgraf, Interpreter TFLite saat ini hanya mendukung satu subgraf. Oleh karena itu, MetadataExtractor menghilangkan indeks subgraf sebagai argumen masukan dalam metodenya.

Baca 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 perpustakaan Metadata Extractor.

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

public InputStream getAssociatedFile(String fileName);

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

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