سوالی دارید؟ در انجمن بازدید از انجمن TensorFlow با انجمن ارتباط برقرار کنید

افزودن فراداده به مدلهای TensorFlow Lite

متادیتای TensorFlow Lite استانداردی برای توصیف مدل ارائه می دهد. فراداده منبع مهمی از دانش در مورد آنچه مدل انجام می دهد و اطلاعات ورودی / خروجی آن است. فراداده از هر دو تشکیل شده است

تمام مدلهای تصویری منتشر شده در مدلهای میزبان TensorFlow Lite و TensorFlow Hub با فراداده جمع شده اند.

مدل با قالب فراداده

مدل_با_متاداده
شکل 1. مدل TFLite با فراداده و پرونده های مرتبط.

فراداده مدل در metadata_schema.fbs ، یک پرونده FlatBuffer تعریف شده است. همانطور که در شکل 1 نشان داده شده است ، در قسمت فراداده طرحواره مدل TFLite ، تحت نام "TFLITE_METADATA" . برخی از مدل ها ممکن است همراه با پرونده های مرتبط باشند ، مانند پرونده های برچسب طبقه بندی . این پرونده ها با استفاده از حالت "ضمیمه" ZipFile ( حالت 'a' ) به انتهای پرونده مدل اصلی به عنوان ZIP متصل می شوند. TFLite Interpreter می تواند قالب پرونده جدید را به همان روش قبلی مصرف کند. برای اطلاعات بیشتر به پرونده های مرتبط مراجعه کنید.

در مورد نحوه جمع کردن ، تجسم و خواندن فراداده ها به دستورالعمل زیر مراجعه کنید.

ابزارهای فراداده را تنظیم کنید

قبل از افزودن فراداده به مدل خود ، برای راه اندازی TensorFlow نیاز به تنظیم محیط برنامه نویسی پایتون دارید. در اینجا یک راهنمای دقیق برای نحوه تنظیم این مطلب وجود دارد .

پس از تنظیم محیط برنامه نویسی پایتون ، باید ابزار اضافی را نصب کنید:

pip install tflite-support

ابزار متاداده TensorFlow Lite از پایتون 3 پشتیبانی می کند.

افزودن فراداده با استفاده از Flatbuffers Python API

سه بخش فراداده مدل در طرح وجود دارد :

  1. اطلاعات مدل - توضیحات کلی مدل و همچنین مواردی مانند شرایط مجوز. به ModelMetadata مراجعه کنید.
  2. اطلاعات ورودی - شرح ورودی ها و پیش پردازش های مورد نیاز مانند عادی سازی. به SubGraphMetadata.input_tensor_metadata مراجعه کنید.
  3. اطلاعات خروجی - شرح خروجی و پردازش پس از آن مانند نقشه برداری برچسب ها مورد نیاز است. به SubGraphMetadata.output_tensor_metadata مراجعه کنید.

از آنجا که TensorFlow Lite در این مرحله فقط از یک SubGraphMetadata.name SubGraphMetadata.description ، هنگام نمایش متادیتا و تولید کد ، مولد کد SubGraphMetadata.description Lite و ویژگی Android Studio ML Binding از ModelMetadata.name و ModelMetadata.description ، به جای SubGraphMetadata.name و SubGraphMetadata.description استفاده می کنند.

انواع ورودی / خروجی پشتیبانی شده

متادیتای TensorFlow Lite برای ورودی و خروجی با توجه به انواع مدل خاصی در نظر گرفته نشده است بلکه انواع ورودی و خروجی آنها طراحی شده اند. مهم نیست که مدل عملکردی را انجام می دهد ، تا زمانی که انواع ورودی و خروجی متشکل از موارد زیر باشد یا ترکیبی از موارد زیر باشد ، توسط متادیتای TensorFlow Lite پشتیبانی می شود:

  • ویژگی - اعدادی که عدد صحیح بدون علامت یا float32 هستند.
  • تصویر - فراداده در حال حاضر از تصاویر RGB و در مقیاس خاکستری پشتیبانی می کند.
  • جعبه اتصال - جعبه های محدود به شکل مستطیل. این طرح از انواع طرح های شماره گذاری پشتیبانی می کند .

پرونده های مرتبط را بسته بندی کنید

مدل های TensorFlow Lite ممکن است همراه با پرونده های مختلف مرتبط باشند. به عنوان مثال ، مدل های زبان طبیعی معمولاً دارای پرونده های vocab هستند که قطعات کلمات را به شناسه های کلمه ترسیم می کنند. مدل های طبقه بندی ممکن است دارای پرونده های برچسبی باشند که دسته های شی را نشان می دهند. بدون پرونده های مرتبط (در صورت وجود) ، یک مدل عملکرد خوبی نخواهد داشت.

پرونده های مرتبط اکنون می توانند از طریق کتابخانه فراداده Python با مدل همراه شوند. مدل جدید TensorFlow Lite به یک فایل فشرده تبدیل می شود که هم شامل مدل و هم پرونده های مرتبط است. بسته بندی آن با ابزارهای معمول zip امکان پذیر است. این قالب مدل جدید همچنان از پسوند پرونده مشابه .tflite . با چارچوب TFLite و مترجم موجود سازگار است. برای جزئیات بیشتر به mtadata و فایلهای مرتبط با آن در مدل مراجعه کنید.

اطلاعات پرونده مرتبط را می توان در فراداده ثبت کرد. بسته به نوع فایل و محلی که فایل به آن متصل است (به عنوان مثال ModelMetadata ، SubGraphMetadata و TensorMetadata ) ، تولید کننده کد Android TensorMetadata Lite ممکن است پردازش مربوطه قبل و بعد مربوطه را به طور خودکار بر روی شی اعمال کند. برای جزئیات بیشتر به بخش <استفاده از Codegen> هر نوع پرونده مرتبط در طرح مراجعه کنید.

پارامترهای نرمال سازی و کوانتیزاسیون

نرمال سازی یک روش معمول پیش پردازش داده ها در یادگیری ماشین است. هدف از نرمال سازی ، تغییر مقادیر به مقیاس مشترک ، بدون ایجاد اختلاف در محدوده مقادیر است.

کمی سازی مدل روشی است که اجازه می دهد نمایش دقیق وزنه ها و به صورت اختیاری فعال سازی برای ذخیره سازی و محاسبه را کاهش دهد.

از نظر پیش پردازش و پردازش پس از آن ، عادی سازی و کمی سازی دو مرحله مستقل هستند. در اینجا جزئیات

عادی سازی کمی سازی

نمونه ای از مقادیر پارامتر تصویر ورودی در MobileNet به ترتیب برای مدل های شناور و کوانتومی.
مدل شناور :
- میانگین: 127.5
- std: 127.5
مدل کمی :
- میانگین: 127.5
- std: 127.5
مدل شناور :
- نقطه صفر: 0
- مقیاس: 1.0
مدل کمی :
- نقطه صفر: 128.0
- مقیاس: 0.0078125f




چه موقع استناد کنیم؟


ورودی ها : اگر داده های ورودی در آموزش عادی شوند ، داده های ورودی استنتاج باید بر این اساس نرمال شوند.
خروجی ها : داده های خروجی به طور کلی عادی نمی شوند.
مدل های شناور به مقداردهی احتیاج ندارند.
مدل كوانتيزه شده ممكن است در پردازش قبل و بعد از آن نياز به كوانتيزاسيون داشته باشد. این به نوع داده سنجشگرهای ورودی / خروجی بستگی دارد.
- شناورهای شناور: بدون نیاز به مقداردهی در پردازش قبل و بعد از ارسال ، op opant و dequant op در نمودار مدل پخته می شوند.
- int8 / uint8 tensors: در پردازش قبل / بعد نیاز به مقداردهی دارید.


فرمول


normalized_input = (ورودی - میانگین) / std
اندازه گیری برای ورودی ها :
q = f / مقیاس + نقطه صفر
كاهش مقدار برای خروجی ها :
مقیاس f = (q - zeroPoint) *

پارامترها کجا هستند
توسط سازنده مدل پر شده و به عنوان NormalizationOptions در فراداده مدل ذخیره می شود به طور خودکار توسط مبدل TFLite پر شده و در پرونده مدل tflite ذخیره می شود.
چگونه پارامترها را بدست آوریم؟ از طریق API 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] باشد ، انجام این کار خوب است. اما به طور کلی ، همیشه باید داده ها را با توجه به پارامترهای نرمال سازی و کوانتیزاسیون در صورت کاربرد پردازش کنید.

اگر NormalizationOptions در فراداده تنظیم کنید ، TensorFlow Lite Task Library می تواند نرمال سازی را برای شما انجام دهد. کمی سازی و پردازش مقدارزدایی همیشه بهم پیوسته است.

مثال ها

شما می توانید نمونه هایی از نحوه جمع آوری فراداده را برای انواع مختلف مدل ها در اینجا بیابید:

طبقه بندی تصویر

اسکریپت را که متادیتا را در 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 می توان از طریق یک فایل مرتبط ، برچسب را به یک 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 می توانید هر تعداد پرونده مرتبط را که می خواهید در مدل قرار 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" متلاشی می شود. انتظار می رود File_identifier خیلی کمتر از تغییر داده_متاد تغییر کند.

حداقل نسخه تجزیه کننده فوق داده

حداقل نسخه تجزیه کننده فراداده لازم حداقل نسخه تجزیه کننده فراداده (کد تولید شده توسط Flatbuffers) است که می تواند متادادها را به طور کامل بخواند. نسخه در واقع بزرگترین شماره نسخه در بین نسخه های تمام قسمتهای پرجمعیت و کوچکترین نسخه سازگار است که توسط شناسه پرونده نشان داده شده است. حداقل نسخه تجزیه کننده فراداده موردنیاز هنگامی که متادیتا در یک مدل TFLite جمع می شود ، به طور خودکار توسط MetadataPopulator جمع می شود. برای اطلاعات بیشتر در مورد چگونگی استفاده از حداقل نسخه تجزیه کننده فراداده ، به استخراج فراداده مراجعه کنید.

فراداده های مدل ها را بخوانید

کتابخانه Metadata Extractor ابزاری مناسب برای خواندن فراداده ها و پرونده های مرتبط از یک مدل در سیستم عامل های مختلف است (به نسخه جاوا و نسخه ++ C مراجعه کنید ). با استفاده از کتابخانه Flatbuffers می توانید ابزار استخراج فراداده خود را به زبان های دیگر بسازید.

فراداده ها را در جاوا بخوانید

برای استفاده از کتابخانه Metadata Extractor در برنامه Android خود ، ما توصیه می کنیم از TensorFlow Lite Metadata AAR که در MavenCentral میزبانی می شود استفاده کنید . این شامل کلاس MetadataExtractor و همچنین اتصالات جاوا FlatBuffers برای طرح متاداده و طرح مدل است .

این را می توانید در وابستگی های build.gradle خود به شرح زیر مشخص کنید:

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

برای استفاده از عکس های فوری شبانه ، مطمئن شوید که مخزن عکس فوری Sonatype را اضافه کرده اید .

می توانید یک شی MetadataExtractor را با ByteBuffer که به مدل نشان می دهد مقداردهی اولیه کنید:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer باید برای کل عمر شی MetadataExtractor بدون تغییر باقی بماند. اگر شناسه پرونده Flatbuffers فراداده مدل با مشخصات تجزیه متادیتا مطابقت نداشته باشد ، ممکن است تنظیم اولیه انجام نشود. برای اطلاعات بیشتر به نسخه فراداده مراجعه کنید.

با شناسه های پرونده تطبیق داده ، استخراج متادیتا با موفقیت مکانیزم سازگاری به جلو و عقب Flatbuffers متادیتای تولید شده از تمام طرح های گذشته و آینده را می خواند. با این وجود ، زمینه های طرح های آینده توسط استخراج کنندگان قدیمی فراداده قابل استخراج نیستند. حداقل نسخه تجزیه کننده فراداده حداقل نسخه تجزیه کننده فراداده را نشان می دهد که می تواند متادادها را به طور کامل بخواند. برای بررسی اینکه حداقل شرط لازم نسخه تجزیه کننده وجود دارد ، می توانید از روش زیر استفاده کنید:

public final boolean isMinimumParserVersionSatisfied();

عبور در یک مدل بدون فراداده مجاز است. با این حال ، فراخوانی روش هایی که از فراداده خوانده می شوند باعث خطاهای زمان اجرا می شوند. با فراخوانی روش hasMetadata می توانید بررسی کنید که آیا مدل فراداده دارد یا 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 Interpreter در حال حاضر فقط از یک زیرنویس پشتیبانی می کند. بنابراین ، 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 بخوانید.

در جاوا ، نام فایل را به روش MetadataExtractor.getAssociatedFile :

public InputStream getAssociatedFile(String fileName);

به طور مشابه ، در C ++ ، این را می توان با روش ModelMetadataExtractor::GetAssociatedFile :

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