فحص أخطاء التكميم باستخدام مصحح التكميم

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر انظر نموذج TF Hub

على الرغم من أن تكميم الأعداد الصحيحة يوفر حجم نموذج محسن وزمن انتقال ، فإن النموذج الكمي لن يعمل دائمًا كما هو متوقع. من المتوقع عادةً أن تكون جودة النموذج (مثل الدقة ، الخريطة ، WER) أقل قليلاً من نموذج الطفو الأصلي. ومع ذلك ، هناك حالات يمكن أن تقل فيها جودة النموذج عن توقعاتك أو تؤدي إلى نتائج خاطئة تمامًا.

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

المصحح الكمي

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

المتطلبات الأساسية

إذا كان لديك بالفعل خط أنابيب لتقدير نموذج ما ، فلديك كل القطع اللازمة لتشغيل مصحح التكميم!

  • نموذج للقياس الكمي
  • مجموعة البيانات التمثيلية

بالإضافة إلى النموذج والبيانات ، سوف تحتاج إلى استخدام إطار عمل معالجة البيانات (مثل الباندا وجداول بيانات Google) لتحليل النتائج التي تم تصديرها.

يثبت

يقوم هذا القسم بإعداد المكتبات ونموذج MobileNet v3 ومجموعة بيانات الاختبار المكونة من 100 صورة.

# Quantization debugger is available from TensorFlow 2.7.0
pip uninstall -y tensorflow
pip install tf-nightly
pip install tensorflow_datasets --upgrade  # imagenet_v2 needs latest checksum
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow as tf
import tensorflow_datasets as tfds
import tensorflow_hub as hub

Boilerplates والمساعدين

2021-10-30 11:57:45.262002: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmp_3ry7zon/assets
INFO:tensorflow:Assets written to: /tmp/tmp_3ry7zon/assets
2021-10-30 11:57:52.134354: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 11:57:52.134407: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
test_ds = ds.map(lambda data: (data['image'], data['label'] + 1)).batch(16)
loss, acc = model.evaluate(test_ds)
print(f'Top-5 accuracy (float): {acc * 100:.2f}%')
7/7 [==============================] - 6s 33ms/step - loss: 88.6092 - sparse_top_k_categorical_accuracy: 11.7143
Top-5 accuracy (float): 1171.43%
eval_tflite(quantized_model, ds)
Top-5 accuracy (quantized): 51.00%

يمكننا أن نرى أن النموذج الأصلي يتمتع بدقة أعلى 5 أعلى بكثير لمجموعة البيانات الصغيرة الخاصة بنا ، في حين أن النموذج الكمي لديه خسارة كبيرة في الدقة.

الخطوة 1. إعداد المصحح

أسهل طريقة لاستخدام المصحح تكميم هي توفير tf.lite.TFLiteConverter أن كنت قد تستخدم لتكمم نموذج.

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset(ds)

# my_debug_dataset should have the same format as my_representative_dataset
debugger = tf.lite.experimental.QuantizationDebugger(
    converter=converter, debug_dataset=representative_dataset(ds))
INFO:tensorflow:Assets written to: /tmp/tmpoa_5gejn/assets
INFO:tensorflow:Assets written to: /tmp/tmpoa_5gejn/assets
2021-10-30 11:58:34.006052: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 11:58:34.006103: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0

الخطوة 2. تشغيل مصحح الأخطاء والحصول على النتائج

عند استدعاء QuantizationDebugger.run() ، المصحح سيتم تسجيل الاختلافات بين التنسورات تعويم والتنسورات الكم لنفس الموقع المرجع، ومعالجة لهم مقاييس معينة.

debugger.run()

ويمكن الوصول إلى مقاييس معالجتها مع QuantizationDebugger.layer_statistics ، أو يمكن ملقاة إلى ملف نصي في تنسيق CSV مع QuantizationDebugger.layer_statistics_dump() .

RESULTS_FILE = '/tmp/debugger_results.csv'
with open(RESULTS_FILE, 'w') as f:
  debugger.layer_statistics_dump(f)
head /tmp/debugger_results.csv

لكل صف في تفريغ، واسم المرجع والمؤشر يأتي أولا، تليها المعلمات تكميم والمقاييس خطأ (بما في ذلك مقاييس الخطأ المعرفة من قبل المستخدم ، إن وجدت). يمكن استخدام ملف CSV الناتج لاختيار الطبقات الإشكالية بمقاييس خطأ تكميم كبيرة.

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

layer_stats = pd.read_csv(RESULTS_FILE)
layer_stats.head()

الخطوة 3. تحليل البيانات

هناك طرق مختلفة لتحليل الناتج. أولاً ، دعنا نضيف بعض المقاييس المفيدة المشتقة من مخرجات مصحح الأخطاء. ( scale يعني عامل مقياس تكميم لكل موتر).

  • مجموعة ( 256 / scale )
  • RMSE / حجم ( sqrt(mean_squared_error) / scale )

و RMSE / scale يقترب من 1 / sqrt(12) (~ 0.289) عند الكم توزيع مشابه لتوزيع تعويم الأصلي، مما يشير إلى نموذج كمي جيدة. كلما كانت القيمة أكبر ، فمن الأرجح أن الطبقة لا يتم تكميمها جيدًا.

layer_stats['range'] = 255.0 * layer_stats['scale']
layer_stats['rmse/scale'] = layer_stats.apply(
    lambda row: np.sqrt(row['mean_squared_error']) / row['scale'], axis=1)
layer_stats[['op_name', 'range', 'rmse/scale']].head()
plt.figure(figsize=(15, 5))
ax1 = plt.subplot(121)
ax1.bar(np.arange(len(layer_stats)), layer_stats['range'])
ax1.set_ylabel('range')
ax2 = plt.subplot(122)
ax2.bar(np.arange(len(layer_stats)), layer_stats['rmse/scale'])
ax2.set_ylabel('rmse/scale')
plt.show()

بي إن جي

هناك العديد من الطبقات مع نطاقات واسعة، وبعض الطبقات التي تعاني من ارتفاع RMSE/scale القيم. دعنا نحصل على الطبقات ذات مقاييس الخطأ العالية.

layer_stats[layer_stats['rmse/scale'] > 0.7][[
    'op_name', 'range', 'rmse/scale', 'tensor_name'
]]

باستخدام هذه الطبقات ، يمكنك تجربة التكميم الانتقائي لمعرفة ما إذا لم يكن تكميم تلك الطبقات يحسن جودة النموذج.

suspected_layers = list(
    layer_stats[layer_stats['rmse/scale'] > 0.7]['tensor_name'])

بالإضافة إلى ذلك ، فإن تخطي التكميم للطبقات القليلة الأولى يساعد أيضًا في تحسين جودة النموذج الكمي.

suspected_layers.extend(list(layer_stats[:5]['tensor_name']))

التكميم الانتقائي

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

ومع ذلك ، إذا كنت تخطط لتشغيل نماذج كمية على مسرعات عدد صحيح فقط (على سبيل المثال Hexagon DSP ، EdgeTPU) ، فإن التكميم الانتقائي قد يتسبب في تجزئة النموذج وسيؤدي إلى زمن انتقال استنتاج أبطأ ناتجًا بشكل أساسي عن تكلفة نقل البيانات بين وحدة المعالجة المركزية وتلك المسرعات . لمنع هذا، يمكنك أن تنظر تشغيل تكميم التدريب علم للحفاظ على جميع الطبقات في عدد صحيح مع الحفاظ على دقة النموذج.

الخيار تكميم المصحح يقبل denylisted_nodes و denylisted_ops خيارات لتخطي تكميم للطبقات محددة، أو كافة مثيلات التقاط محددة. باستخدام suspected_layers نحن على استعداد من الخطوة السابقة، يمكننا استخدام تكميم المصحح للحصول على نموذج كمي انتقائي.

debug_options = tf.lite.experimental.QuantizationDebugOptions(
    denylisted_nodes=suspected_layers)
debugger = tf.lite.experimental.QuantizationDebugger(
    converter=converter,
    debug_dataset=representative_dataset(ds),
    debug_options=debug_options)
INFO:tensorflow:Assets written to: /tmp/tmpqqc57uli/assets
INFO:tensorflow:Assets written to: /tmp/tmpqqc57uli/assets
2021-10-30 11:59:13.603355: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 11:59:13.603400: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
selective_quantized_model = debugger.get_nondebug_quantized_model()
eval_tflite(selective_quantized_model, ds)
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
Top-5 accuracy (quantized): 64.00%

لا تزال الدقة أقل مقارنةً بنموذج الطفو الأصلي ، لكن لدينا تحسنًا ملحوظًا من النموذج الكمي بأكمله عن طريق تخطي التكميم لحوالي 10 طبقات من أصل 111 طبقة.

يمكنك أيضًا محاولة عدم قياس جميع العمليات في نفس الفصل. على سبيل المثال، لتخطي تكميم للجميع التقاط متوسط، يمكنك تمرير MEAN إلى denylisted_ops .

debug_options = tf.lite.experimental.QuantizationDebugOptions(
    denylisted_ops=['MEAN'])
debugger = tf.lite.experimental.QuantizationDebugger(
    converter=converter,
    debug_dataset=representative_dataset(ds),
    debug_options=debug_options)
INFO:tensorflow:Assets written to: /tmp/tmpxltlornb/assets
INFO:tensorflow:Assets written to: /tmp/tmpxltlornb/assets
2021-10-30 11:59:44.677473: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 11:59:44.677519: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
selective_quantized_model = debugger.get_nondebug_quantized_model()
eval_tflite(selective_quantized_model, ds)
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
Top-5 accuracy (quantized): 54.00%

باستخدام هذه التقنيات ، نحن قادرون على تحسين دقة نموذج MobileNet V3 الكمي. بعد ذلك سنستكشف التقنيات المتقدمة لتحسين دقة النموذج بشكل أكبر.

الاستخدامات المتقدمة

مع الميزات التالية ، يمكنك تخصيص خط أنابيب التصحيح الخاص بك.

المقاييس المخصصة

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

  • layer_debug_metrics : حساب متري على أساس فرق لكل مخرجات المرجع من تعويم والمخرجات المرجع الكم.
  • layer_direct_compare_metrics : بدلا من الحصول على فرق فقط، وهذا سوف حساب متري على أساس تعويم الخام والتنسورات الكم، والمعلمات تكميم بها (الحجم، نقطة الصفر)
  • model_debug_metrics : تستخدم فقط عندما float_model_(path|content) يتم تمريرها إلى المصحح. بالإضافة إلى مقاييس مستوى المرجع ، تتم مقارنة إخراج الطبقة النهائية بالإخراج المرجعي من نموذج الطفو الأصلي.
debug_options = tf.lite.experimental.QuantizationDebugOptions(
    layer_debug_metrics={
        'mean_abs_error': (lambda diff: np.mean(np.abs(diff)))
    },
    layer_direct_compare_metrics={
        'correlation':
            lambda f, q, s, zp: (np.corrcoef(f.flatten(),
                                             (q.flatten() - zp) / s)[0, 1])
    },
    model_debug_metrics={
        'argmax_accuracy': (lambda f, q: np.mean(np.argmax(f) == np.argmax(q)))
    })

debugger = tf.lite.experimental.QuantizationDebugger(
    converter=converter,
    debug_dataset=representative_dataset(ds),
    debug_options=debug_options)
INFO:tensorflow:Assets written to: /tmp/tmpm7cb9qcd/assets
INFO:tensorflow:Assets written to: /tmp/tmpm7cb9qcd/assets
2021-10-30 12:00:18.502193: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 12:00:18.502238: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
INFO:tensorflow:Assets written to: /tmp/tmpzkg3ny_8/assets
INFO:tensorflow:Assets written to: /tmp/tmpzkg3ny_8/assets
2021-10-30 12:00:28.401195: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 12:00:28.401241: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
debugger.run()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/numpy/lib/function_base.py:2691: RuntimeWarning: invalid value encountered in true_divide
  c /= stddev[:, None]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/numpy/lib/function_base.py:2692: RuntimeWarning: invalid value encountered in true_divide
  c /= stddev[None, :]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/lite/tools/optimize/debugging/python/debugger.py:382: RuntimeWarning: Mean of empty slice
  metrics[metric_name] = np.nanmean(metrics[metric_name])
CUSTOM_RESULTS_FILE = '/tmp/debugger_results.csv'
with open(CUSTOM_RESULTS_FILE, 'w') as f:
  debugger.layer_statistics_dump(f)

custom_layer_stats = pd.read_csv(CUSTOM_RESULTS_FILE)
custom_layer_stats[['op_name', 'mean_abs_error', 'correlation']].tail()

نتيجة model_debug_metrics يمكن أن ينظر إليه بمعزل عن debugger.model_statistics .

debugger.model_statistics
{'argmax_accuracy': 0.36}

استخدام واجهة برمجة تطبيقات mlir_quantize (داخليًا) للوصول إلى الميزات المتعمقة

from tensorflow.lite.python import convert

نموذج التحقق الكامل من الوضع

السلوك الافتراضي لإنشاء نموذج التصحيح هو التحقق لكل طبقة. في هذا الوضع ، يكون الإدخال الخاص بزوج التعويم والتكميم من نفس المصدر (المرجع السابق المحدد). طريقة أخرى هي التحقق من النموذج الكامل ، حيث يتم فصل نموذجي الطفو والتكميم. سيكون هذا الوضع مفيدًا في ملاحظة كيفية انتشار الخطأ أسفل النموذج. لتمكين، enable_whole_model_verify=True ل convert.mlir_quantize أثناء إنشاء نموذج التصحيح يدويا.

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.representative_dataset = representative_dataset(ds)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter._experimental_calibrate_only = True
calibrated_model = converter.convert()
INFO:tensorflow:Assets written to: /tmp/tmp2oa0sp06/assets
INFO:tensorflow:Assets written to: /tmp/tmp2oa0sp06/assets
2021-10-30 12:01:33.233118: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-10-30 12:01:33.233171: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
# Note that enable_numeric_verify and enable_whole_model_verify are set.
quantized_model = convert.mlir_quantize(
    calibrated_model,
    enable_numeric_verify=True,
    enable_whole_model_verify=True)
debugger = tf.lite.experimental.QuantizationDebugger(
    quant_debug_model_content=quantized_model,
    debug_dataset=representative_dataset(ds))
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0

التكميم الانتقائي من نموذج معاير بالفعل

يمكنك الاتصال مباشرة convert.mlir_quantize للحصول على نموذج كمي انتقائي من نموذج معايرة بالفعل. سيكون هذا مفيدًا بشكل خاص عندما تريد معايرة النموذج مرة واحدة ، وتجربة مجموعات مختلفة من denylist.

selective_quantized_model = convert.mlir_quantize(
    calibrated_model, denylisted_nodes=suspected_layers)
eval_tflite(selective_quantized_model, ds)
fully_quantize: 0, inference_type: 6, input_inference_type: 0, output_inference_type: 0
Top-5 accuracy (quantized): 64.00%