إضافة البيانات الوصفية إلى نماذج TensorFlow Lite

توفر البيانات الوصفية TensorFlow Lite معيارًا لوصف النموذج. تعد البيانات الوصفية مصدرًا مهمًا للمعرفة حول ما يفعله النموذج ومعلومات الإدخال / الإخراج الخاصة به. تتكون البيانات الوصفية من كليهما

  • الأجزاء التي يمكن قراءتها من قبل الإنسان والتي تنقل أفضل الممارسات عند استخدام النموذج ، و
  • الأجزاء التي يمكن قراءتها آليًا والتي يمكن الاستفادة منها بواسطة مولدات الأكواد ، مثل منشئ أكواد TensorFlow Lite Android وميزة Android Studio ML Binding .

تمت تعبئة جميع نماذج الصور المنشورة على TensorFlow Hub ببيانات وصفية.

نموذج مع تنسيق البيانات الوصفية

النموذج_مع_البيانات الوصفية
الشكل 1. نموذج TFLite مع البيانات الوصفية والملفات المرتبطة.

يتم تعريف بيانات تعريف النموذج في metadata_schema.fbs ، ملف FlatBuffer . كما هو مبين في الشكل 1 ، يتم تخزينه في حقل البيانات الوصفية لمخطط نموذج TFLite ، تحت الاسم ، "TFLITE_METADATA" . قد تأتي بعض النماذج مع ملفات مرتبطة بها ، مثل ملفات تسمية التصنيف . يتم ربط هذه الملفات بنهاية ملف النموذج الأصلي كملف ZIP باستخدام وضع "إلحاق" ZipFile (وضع 'a' ). يمكن لمترجم TFLite أن يستهلك تنسيق الملف الجديد بنفس الطريقة كما كان من قبل. راجع حزم الملفات المرتبطة لمزيد من المعلومات.

راجع التعليمات أدناه حول كيفية تعبئة البيانات الوصفية وتصورها وقراءتها.

قم بإعداد أدوات البيانات الوصفية

قبل إضافة البيانات الوصفية إلى نموذجك ، ستحتاج إلى إعداد بيئة برمجة Python لتشغيل TensorFlow. يوجد دليل مفصل حول كيفية إعداد هذا هنا .

بعد إعداد بيئة برمجة Python ، ستحتاج إلى تثبيت أدوات إضافية:

pip install tflite-support

تدعم أدوات البيانات الوصفية TensorFlow Lite لغة Python 3.

إضافة البيانات الوصفية باستخدام Flatbuffers Python API

هناك ثلاثة أجزاء في البيانات الوصفية للنموذج في المخطط :

  1. معلومات النموذج - وصف عام للنموذج بالإضافة إلى عناصر مثل شروط الترخيص. انظر ModelMetadata .
  2. معلومات الإدخال - وصف المدخلات والمعالجة المسبقة المطلوبة مثل التطبيع. راجع SubGraphMetadata.input_tensor_metadata .
  3. معلومات الإخراج - وصف المخرجات والمعالجة اللاحقة المطلوبة مثل التعيين إلى الملصقات. راجع SubGraphMetadata.output_tensor_metadata .

نظرًا لأن TensorFlow Lite لا يدعم سوى الرسم البياني الفرعي الفردي في هذه المرحلة ، فإن منشئ كود TensorFlow Lite وميزة Android Studio ML Binding ستستخدم ModelMetadata.name و ModelMetadata.description ، بدلاً من SubGraphMetadata.name و SubGraphMetadata.description ، عند عرض البيانات الوصفية وإنشاء الكود.

أنواع الإدخال / الإخراج المعتمدة

لم يتم تصميم البيانات الوصفية TensorFlow Lite للإدخال والإخراج مع وضع أنواع معينة من النماذج في الاعتبار ، ولكن بدلاً من ذلك يتم تصميم أنواع المدخلات والمخرجات. لا يهم ما يفعله النموذج وظيفيًا ، طالما أن أنواع المدخلات والمخرجات تتكون مما يلي أو مجموعة من العناصر التالية ، فهي مدعومة بواسطة بيانات تعريف TensorFlow Lite:

  • ميزة - الأرقام التي هي أعداد صحيحة أو عائمة 32.
  • صورة - تدعم البيانات الوصفية حاليًا صور RGB ودرجات الرمادي.
  • الصندوق المحيط - مربعات إحاطة مستطيلة الشكل. يدعم المخطط مجموعة متنوعة من أنظمة الترقيم .

حزم الملفات المرتبطة

قد تأتي نماذج TensorFlow Lite بملفات مرتبطة مختلفة. على سبيل المثال ، عادةً ما تحتوي نماذج اللغة الطبيعية على ملفات vocab التي تعين قطع الكلمات لمعرفات الكلمات ؛ قد تحتوي نماذج التصنيف على ملفات تسمية تشير إلى فئات الكائنات. بدون الملفات المرتبطة (إن وجدت) ، لن يعمل النموذج بشكل جيد.

يمكن الآن تجميع الملفات المرتبطة مع النموذج من خلال مكتبة Python للبيانات الوصفية. يتحول نموذج TensorFlow Lite الجديد إلى ملف مضغوط يحتوي على كل من النموذج والملفات المرتبطة به. يمكن تفريغها بأدوات مضغوطة شائعة. يستمر تنسيق النموذج الجديد هذا في استخدام نفس امتداد الملف ، .tflite . وهو متوافق مع إطار عمل TFLite والمترجم الفوري. راجع حزم البيانات الوصفية والملفات المرتبطة في النموذج لمزيد من التفاصيل.

يمكن تسجيل معلومات الملف المرتبطة في البيانات الوصفية. اعتمادًا على نوع الملف والمكان الذي تم إرفاق الملف به ( ModelMetadata و SubGraphMetadata و TensorMetadata ) ، قد يقوم منشئ رمز TensorFlow Lite Android بتطبيق المعالجة المسبقة / اللاحقة تلقائيًا على الكائن. راجع قسم <Codegen Usage> لكل نوع ملف مرتبط في المخطط لمزيد من التفاصيل.

معلمات التطبيع والتكميم

التطبيع هو أسلوب شائع للمعالجة المسبقة للبيانات في التعلم الآلي. الهدف من التسوية هو تغيير القيم إلى مقياس مشترك ، دون تشويه الاختلافات في نطاقات القيم.

تكميم النموذج هو تقنية تسمح بتقليل دقة تمثيل الأوزان واختياريا ، التنشيط لكل من التخزين والحساب.

من حيث المعالجة المسبقة والمعالجة اللاحقة ، يعتبر التطبيع والتكميم خطوتين مستقلتين. التفاصيل هنا.

تطبيع توضيح

مثال على قيم المعلمات لصورة الإدخال في MobileNet للنماذج العائمة والكمية ، على التوالي.
نموذج تعويم :
- متوسط: 127.5
- الأمراض المنقولة جنسياً: 127.5
النموذج الكمي :
- متوسط: 127.5
- الأمراض المنقولة جنسياً: 127.5
نموذج تعويم :
- نقطة الصفر: 0
- المقياس: 1.0
النموذج الكمي :
- نقطة الصفر: 128.0
- المقياس: 0.0078125f




متى تستدعي؟


المدخلات : إذا تم تطبيع بيانات الإدخال في التدريب ، فيجب تسوية بيانات الإدخال الخاصة بالاستدلال وفقًا لذلك.
المخرجات : لن يتم تطبيع بيانات المخرجات بشكل عام.
النماذج العائمة لا تحتاج إلى تكميم.
قد يحتاج النموذج الكمي وقد لا يحتاج إلى تكميم في المعالجة المسبقة / اللاحقة. يعتمد ذلك على نوع البيانات لموترات الإدخال / الإخراج.
- موتر عائم: لا حاجة إلى تكمية في المعالجة المسبقة / اللاحقة. يتم تحميص المرجع الكمي و dequant op في الرسم البياني للنموذج.
- موترات int8 / uint8: تحتاج إلى تكميم في المعالجة المسبقة / اللاحقة.


معادلة


normalized_input = (المدخلات - يعني) / الأمراض المنقولة جنسيا
القياس الكمي للمدخلات :
ف = و / مقياس + نقطة الصفر
Dequantize للمخرجات :
f = (q - نقطة الصفر) * المقياس

أين هي المعلمات
يتم تعبئتها بواسطة منشئ النموذج وتخزينها في بيانات تعريف النموذج ، NormalizationOptions يتم تعبئتها تلقائيًا بواسطة محول TFLite ، وتخزينها في ملف نموذج tflite.
كيف تحصل على المعلمات؟ من خلال واجهة برمجة تطبيقات MetadataExtractor [2] من خلال TFLite Tensor API [1] أو من خلال MetadataExtractor API [2]
هل تشترك النماذج العائمة والكمية في نفس القيمة؟ نعم ، النماذج العائمة والكمية لها نفس معاملات التسوية لا ، النموذج العائم لا يحتاج إلى تكميم.
هل يقوم مُنشئ أكواد TFLite أو ربط Android Studio ML بإنشائه تلقائيًا في معالجة البيانات؟
نعم

نعم

[1] TensorFlow Lite Java API و TensorFlow Lite C ++ API .
[2] مكتبة مستخرج البيانات الوصفية

عند معالجة بيانات الصورة لنماذج uint8 ، يتم أحيانًا تخطي التطبيع والتكميم. من الجيد القيام بذلك عندما تكون قيم البكسل في النطاق [0 ، 255]. لكن بشكل عام ، يجب عليك دائمًا معالجة البيانات وفقًا لمعايير التطبيع والتكميم عند الاقتضاء.

يمكن لمكتبة المهام TensorFlow Lite التعامل مع التسوية نيابة عنك إذا قمت بإعداد NormalizationOptions في البيانات الوصفية. يتم دائمًا تغليف معالجة التكميم والتفريغ.

أمثلة

يمكنك العثور على أمثلة حول كيفية تعبئة البيانات الوصفية لأنواع مختلفة من النماذج هنا:

تصنيف الصورة

قم بتنزيل النص هنا ، والذي يملأ البيانات الوصفية في mobilenet_v1_0.75_160_quantized.tflite . قم بتشغيل البرنامج النصي مثل هذا:

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

لتعبئة البيانات الأولية لنماذج تصنيف الصور الأخرى ، أضف مواصفات النموذج مثل هذه في البرنامج النصي. ستسلط بقية هذا الدليل الضوء على بعض الأقسام الرئيسية في مثال تصنيف الصور لتوضيح العناصر الأساسية.

الغوص العميق في مثال تصنيف الصور

معلومات النموذج

تبدأ البيانات الوصفية بإنشاء معلومات نموذج جديد:

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

معلومات الإدخال / الإخراج

يوضح لك هذا القسم كيفية وصف مدخلات النموذج وتوقيع المخرجات. يمكن استخدام هذه البيانات الوصفية من قبل مولدات الكود الأوتوماتيكية لإنشاء كود المعالجة المسبقة واللاحقة. لإنشاء معلومات إدخال أو إخراج حول موتر:

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

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

إدخال الصورة

الصورة هي نوع إدخال شائع للتعلم الآلي. تدعم بيانات TensorFlow Lite الأولية معلومات مثل مساحة الألوان ومعلومات المعالجة المسبقة مثل التسوية. لا يتطلب أبعاد الصورة مواصفات يدوية حيث يتم توفيرها بالفعل من خلال شكل موتر الإدخال ويمكن استنتاجها تلقائيًا.

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

إخراج التسمية

يمكن تعيين التسمية إلى موتر الإخراج عبر ملف مرتبط باستخدام 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]

إنشاء البيانات الوصفية Flatbuffers

يجمع الكود التالي معلومات النموذج مع معلومات الإدخال والإخراج:

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

قم بحزم البيانات الوصفية والملفات المرتبطة بها في النموذج

بمجرد إنشاء البيانات الوصفية Flatbuffers ، تتم كتابة البيانات الوصفية وملف التسمية في ملف TFLite عبر التابع 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()

يمكنك حزم العديد من الملفات المرتبطة كما تريد في النموذج من خلال load_associated_files . ومع ذلك ، يجب أن تحزم على الأقل تلك الملفات الموثقة في البيانات الوصفية. في هذا المثال ، يعد تعبئة ملف الملصق أمرًا إلزاميًا.

تصور البيانات الوصفية

يمكنك استخدام Netron لتصور البيانات الوصفية الخاصة بك ، أو يمكنك قراءة البيانات الوصفية من نموذج TensorFlow Lite إلى تنسيق json باستخدام 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 أيضًا عرض البيانات الوصفية من خلال ميزة Android Studio ML Binding .

إصدار البيانات الوصفية

يتم إصدار مخطط البيانات الوصفية بواسطة رقم الإصدار الدلالي ، الذي يتتبع التغييرات في ملف المخطط ، ومن خلال تعريف ملف Flatbuffers ، مما يشير إلى توافق الإصدار الحقيقي.

رقم الإصدار الدلالي

يتم إصدار مخطط البيانات الوصفية بواسطة رقم الإصدار الدلالي ، مثل MAJOR.MINOR.PATCH. يتتبع تغييرات المخطط وفقًا للقواعد هنا . انظر محفوظات الحقول المضافة بعد الإصدار 1.0.0 .

تحديد ملف Flatbuffers

يضمن الإصدار الدلالي التوافق في حالة اتباع القواعد ، لكنه لا يعني عدم التوافق الحقيقي. عند تصغير الرقم الرئيسي ، لا يعني ذلك بالضرورة أن التوافق مع الإصدارات السابقة معطل. لذلك ، نستخدم تعريف ملف Flatbuffers ، file_identifier ، للإشارة إلى التوافق الحقيقي لمخطط البيانات الوصفية. يبلغ طول معرف الملف 4 أحرف بالضبط. تم إصلاحه على مخطط بيانات وصفية معين ولا يخضع للتغيير من قبل المستخدمين. إذا كان لابد من كسر التوافق مع الإصدارات السابقة لمخطط البيانات الوصفية لسبب ما ، فإن معرّف الملف سوف يرتفع ، على سبيل المثال ، من "M001" إلى "M002". من المتوقع تغيير معرّف الملف بمعدل أقل بكثير من إصدار البيانات الوصفية.

الحد الأدنى المطلوب من إصدار المحلل اللغوي للبيانات الوصفية

الحد الأدنى من إصدار محلل البيانات الوصفية الضروري هو الإصدار الأدنى من محلل البيانات الوصفية (رمز Flatbuffers الذي تم إنشاؤه) الذي يمكنه قراءة البيانات الوصفية Flatbuffers بالكامل. يعد الإصدار فعليًا أكبر رقم إصدار بين إصدارات جميع الحقول التي تم ملؤها وأصغر إصدار متوافق يشار إليه بواسطة معرف الملف. يتم ملء الإصدار الأدنى الضروري من محلل البيانات الوصفية تلقائيًا بواسطة MetadataPopulator عند تعبئة البيانات الوصفية في نموذج TFLite. راجع مستخرج البيانات الوصفية لمزيد من المعلومات حول كيفية استخدام الحد الأدنى الضروري من إصدار محلل البيانات الوصفية.

اقرأ البيانات الوصفية من النماذج

تعد مكتبة Metadata Extractor أداة ملائمة لقراءة البيانات الوصفية والملفات المرتبطة بها من نماذج عبر أنظمة أساسية مختلفة (راجع إصدار Java ونسخة C ++ ). يمكنك إنشاء أداة استخراج البيانات الوصفية الخاصة بك بلغات أخرى باستخدام مكتبة Flatbuffers.

اقرأ البيانات الوصفية في Java

لاستخدام مكتبة Metadata Extractor في تطبيق Android الخاص بك ، نوصي باستخدام TensorFlow Lite Metadata AAR المستضاف في MavenCentral . يحتوي على فئة MetadataExtractor ، بالإضافة إلى روابط FlatBuffers Java لمخطط البيانات الوصفية ومخطط النموذج .

يمكنك تحديد ذلك في تبعيات build.gradle على النحو التالي:

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

لاستخدام اللقطات الليلية ، تأكد من إضافة مستودع لقطات Sonatype .

يمكنك تهيئة كائن MetadataExtractor باستخدام ByteBuffer الذي يشير إلى النموذج:

public MetadataExtractor(ByteBuffer buffer);

يجب أن يظل ByteBuffer تغيير طوال العمر الافتراضي لكائن MetadataExtractor . قد تفشل التهيئة إذا كان معرف ملف Flatbuffers لبيانات تعريف النموذج لا يتطابق مع معرف محلل البيانات الوصفية. انظر إصدارات البيانات الوصفية لمزيد من المعلومات.

من خلال مطابقة معرفات الملفات ، سيقوم مستخرج البيانات الوصفية بقراءة البيانات الوصفية التي تم إنشاؤها من جميع المخططات السابقة والمستقبلية بنجاح بسبب آلية توافق Flatbuffers للأمام والخلف. ومع ذلك ، لا يمكن استخراج الحقول من المخططات المستقبلية بواسطة أدوات استخراج البيانات الوصفية القديمة. يشير الحد الأدنى من إصدار المحلل اللغوي الضروري للبيانات الوصفية إلى الإصدار الأدنى من محلل البيانات الوصفية الذي يمكنه قراءة البيانات الوصفية Flatbuffers بالكامل. يمكنك استخدام الطريقة التالية للتحقق من استيفاء شرط إصدار المحلل اللغوي الأدنى الضروري:

public final boolean isMinimumParserVersionSatisfied();

يُسمح بتمرير نموذج بدون بيانات وصفية. ومع ذلك ، فإن استدعاء الطرق التي تقرأ من البيانات الوصفية سيؤدي إلى حدوث أخطاء في وقت التشغيل. يمكنك التحقق مما إذا كان النموذج يحتوي على بيانات وصفية عن طريق استدعاء التابع hasMetadata :

public boolean hasMetadata();

يوفر MetadataExtractor وظائف ملائمة لك للحصول على البيانات الوصفية لموترات الإدخال / الإخراج. علي سبيل المثال،

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 يدعم العديد من الرسوم البيانية الفرعية ، إلا أن مترجم TFLite يدعم حاليًا رسمًا بيانيًا فرعيًا واحدًا فقط. لذلك ، يحذف MetadataExtractor فهرس الرسم البياني الفرعي كوسيطة إدخال في طرقه.

اقرأ الملفات المرتبطة من النماذج

نموذج TensorFlow Lite مع البيانات الوصفية والملفات المرتبطة هو في الأساس ملف مضغوط يمكن فك حزمه باستخدام أدوات zip الشائعة للحصول على الملفات المرتبطة. على سبيل المثال ، يمكنك فك ضغط mobilenet_v1_0.75_160_quantized واستخراج ملف التسمية في النموذج على النحو التالي:

$ 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

يمكنك أيضًا قراءة الملفات المرتبطة من خلال مكتبة Metadata Extractor.

في Java ، مرِّر اسم الملف إلى طريقة MetadataExtractor.getAssociatedFile :

public InputStream getAssociatedFile(String fileName);

وبالمثل ، في C ++ ، يمكن القيام بذلك باستخدام الطريقة ModelMetadataExtractor::GetAssociatedFile :

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