क्वांटिज़ेशन डीबगर के साथ क्वांटिज़ेशन त्रुटियों का निरीक्षण करना

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें टीएफ हब मॉडल देखें

हालांकि पूर्ण-पूर्णांक परिमाणीकरण बेहतर मॉडल आकार और विलंबता प्रदान करता है, लेकिन परिमाणित मॉडल हमेशा अपेक्षा के अनुरूप काम नहीं करेगा। यह आमतौर पर मॉडल की गुणवत्ता (जैसे सटीकता, एमएपी, डब्ल्यूईआर) के लिए मूल फ्लोट मॉडल से थोड़ा कम होने की उम्मीद है। हालांकि, ऐसे मामले हैं जहां मॉडल की गुणवत्ता आपकी अपेक्षा से नीचे जा सकती है या पूरी तरह से गलत परिणाम उत्पन्न कर सकती है।

जब यह समस्या होती है, तो परिमाणीकरण त्रुटि के मूल कारण का पता लगाना मुश्किल और दर्दनाक होता है, और परिमाणीकरण त्रुटि को ठीक करना और भी कठिन होता है। इस मॉडल निरीक्षण प्रक्रिया में सहायता करने के लिए, परिमाणीकरण डिबगर समस्याग्रस्त परतों की पहचान के लिए इस्तेमाल किया जा सकता है, और इतना है कि मॉडल सटीकता परिमाणीकरण से घटाकर लाभ की कीमत पर बरामद किया जा सकता चयनात्मक परिमाणीकरण नाव में उन समस्याग्रस्त परतों छोड़ सकते हैं।

परिमाणीकरण डीबगर

क्वांटिज़ेशन डिबगर मौजूदा मॉडल में क्वांटिज़ेशन गुणवत्ता मीट्रिक विश्लेषण करना संभव बनाता है। क्वांटिज़ेशन डीबगर डिबग डेटासेट के साथ मॉडल चलाने के लिए प्रक्रियाओं को स्वचालित कर सकता है, और प्रत्येक टेंसर के लिए क्वांटिज़ेशन गुणवत्ता मीट्रिक एकत्र कर सकता है।

आवश्यक शर्तें

यदि आपके पास पहले से ही एक मॉडल को मापने के लिए एक पाइपलाइन है, तो आपके पास क्वांटिज़ेशन डीबगर चलाने के लिए सभी आवश्यक टुकड़े हैं!

  • मात्रा निर्धारित करने के लिए मॉडल
  • प्रतिनिधि डेटासेट

मॉडल और डेटा के अलावा, आपको निर्यात किए गए परिणामों का विश्लेषण करने के लिए डेटा प्रोसेसिंग फ्रेमवर्क (जैसे पांडा, Google शीट्स) का उपयोग करना होगा।

सेट अप

यह खंड पुस्तकालय, मोबाइलनेट 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

बॉयलरप्लेट्स और हेल्पर्स

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() , डिबगर एक ही सेशन स्थान के लिए नाव tensors और मात्रा निर्धारित tensors के बीच मतभेदों को लॉग इन करें, और उन्हें दिए गए मीट्रिक के साथ कार्रवाई करेंगे।

debugger.run()

संसाधित मीट्रिक के साथ पहुँचा जा सकता है QuantizationDebugger.layer_statistics , या साथ सीएसवी प्रारूप में किसी पाठ फ़ाइल में फेंक दिया जा सकता है 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) जब मात्रा निर्धारित वितरण मूल नाव वितरण के समान है एक अच्छा quantized मॉडल का संकेत है। मान जितना बड़ा होता है, परत के अच्छी तरह से परिमाणित न होने की संभावना अधिक होती है।

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']))

चयनात्मक परिमाणीकरण

चयनात्मक परिमाणीकरण कुछ नोड्स के लिए परिमाणीकरण को छोड़ देता है, ताकि गणना मूल फ़्लोटिंग-पॉइंट डोमेन में हो सके। जब सही परतों को छोड़ दिया जाता है, तो हम बढ़ी हुई विलंबता और मॉडल आकार की कीमत पर कुछ मॉडल गुणवत्ता पुनर्प्राप्ति की उम्मीद कर सकते हैं।

हालाँकि, यदि आप पूर्णांक-केवल त्वरक (जैसे हेक्सागोन डीएसपी, एजटीपीयू) पर परिमाणित मॉडल चलाने की योजना बना रहे हैं, तो चयनात्मक परिमाणीकरण मॉडल के विखंडन का कारण होगा और इसके परिणामस्वरूप धीमी गति से अनुमान विलंबता मुख्य रूप से सीपीयू और उन त्वरक के बीच डेटा स्थानांतरण लागत के कारण होगी। . इसे रोकने के लिए, आपके द्वारा चलाए जा विचार कर सकते हैं के बारे में पता प्रशिक्षण परिमाणीकरण जबकि मॉडल सटीकता संरक्षण पूर्णांक में सभी परतों रखने के लिए।

परिमाणीकरण डिबगर के विकल्प को स्वीकार करता है denylisted_nodes और denylisted_ops विशिष्ट परतें, या विशिष्ट ऑप्स के सभी उदाहरणों परिमाणीकरण लंघन के लिए विकल्प। का उपयोग करते हुए suspected_layers हम पिछले चरण से तैयार किया है, हम परिमाणीकरण डिबगर का प्रयोग कर एक चुनिंदा quantized मॉडल पाने के लिए कर सकते हैं।

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%

मूल फ्लोट मॉडल की तुलना में सटीकता अभी भी कम है, लेकिन हमने 111 परतों में से ~ 10 परतों के लिए परिमाणीकरण को छोड़ कर पूरे परिमाणित मॉडल से उल्लेखनीय सुधार किया है।

आप एक ही कक्षा में सभी ऑप्स की मात्रा निर्धारित नहीं करने का भी प्रयास कर सकते हैं। उदाहरण के लिए, सभी मतलब ऑप्स के लिए परिमाणीकरण को छोड़ने के लिए, आप पास कर सकते हैं 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 : नाव और मात्रा निर्धारित सेशन आउटपुट से प्रत्येक सेशन आउटपुट के लिए diff के आधार पर मीट्रिक की गणना।
  • layer_direct_compare_metrics : बल्कि केवल diff हो रही तुलना में, इस कच्चे नाव और मात्रा निर्धारित tensors, और इसके परिमाणीकरण मापदंडों के आधार पर मीट्रिक की गणना करेगा (पैमाने, शून्य दशमलव)
  • 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 API का उपयोग करना

from tensorflow.lite.python import convert

संपूर्ण मॉडल सत्यापन मोड

डिबग मॉडल पीढ़ी के लिए डिफ़ॉल्ट व्यवहार प्रति-परत सत्यापन है। इस मोड में, फ्लोट और मात्राबद्ध op जोड़ी के लिए इनपुट एक ही स्रोत (पिछला मात्राबद्ध ऑप) से होता है। एक अन्य मोड पूरे मॉडल का सत्यापन है, जहां फ्लोट और क्वांटिज़ मॉडल अलग हो जाते हैं। यह मोड यह देखने के लिए उपयोगी होगा कि मॉडल के नीचे त्रुटि को कैसे प्रचारित किया जा रहा है। सक्षम करने के लिए 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 पहले से ही कैलिब्रेटेड मॉडल से चयनात्मक मात्रा निर्धारित मॉडल पाने के लिए। यह विशेष रूप से तब उपयोगी होगा जब आप मॉडल को एक बार कैलिब्रेट करना चाहते हैं, और विभिन्न अस्वीकार सूची संयोजनों के साथ प्रयोग करना चाहते हैं।

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%