مشاهده در TensorFlow.org | در Google Colab اجرا شود | مشاهده منبع در GitHub | دانلود دفترچه یادداشت | مدل TF Hub را ببینید |
اگرچه کوانتیزه کردن کامل عدد صحیح اندازه و تاخیر مدل را بهبود می بخشد، مدل کوانتیزه شده همیشه آنطور که انتظار می رود کار نخواهد کرد. معمولاً انتظار می رود کیفیت مدل (به عنوان مثال دقت، mAP، WER) کمی کمتر از مدل شناور اصلی باشد. با این حال، مواردی وجود دارد که کیفیت مدل می تواند کمتر از حد انتظار شما باشد یا نتایج کاملاً اشتباهی ایجاد کند.
هنگامی که این مشکل رخ می دهد، تشخیص علت اصلی خطای کوانتیزاسیون دشوار و دردناک است و رفع خطای کوانتیزاسیون حتی دشوارتر است. برای کمک به این روند بازرسی مدل، دیباگر تدریج می توان مورد استفاده برای شناسایی لایه های مشکل ساز است، و تعیین انتخابی می توانید آن لایه مشکل در شناور ترک به طوری که دقت مدل را می توان در هزینه های کاهش بهره مندی از کوانتیزاسیون بازیافت.
Quantization Debugger
دیباگر کوانتیزاسیون انجام تحلیل متریک کیفیت کوانتیزاسیون را در مدل موجود امکان پذیر می کند. اشکالزدای کوانتیزهسازی میتواند فرآیندها را برای اجرای مدل با مجموعه دادههای اشکالزدایی و جمعآوری معیارهای کیفیت کمی برای هر تانسور خودکار کند.
پیش نیازها
اگر از قبل یک خط لوله برای کمی کردن یک مدل دارید، تمام قطعات لازم برای اجرای دیباگر کوانتیزاسیون را دارید!
- مدل برای کمی کردن
- مجموعه داده نماینده
علاوه بر مدل و داده، باید از یک چارچوب پردازش داده (مثلاً پانداها، Google Sheets) برای تجزیه و تحلیل نتایج صادر شده استفاده کنید.
برپایی
این بخش کتابخانه ها، مدل 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
دیگ بخار و کمکی
MODEL_URI = 'https://tfhub.dev/google/imagenet/mobilenet_v3_small_100_224/classification/5'
def process_image(data):
data['image'] = tf.image.resize(data['image'], (224, 224)) / 255.0
return data
# Representative dataset
def representative_dataset(dataset):
def _data_gen():
for data in dataset.batch(1):
yield [data['image']]
return _data_gen
def eval_tflite(tflite_model, dataset):
"""Evaluates tensorflow lite classification model with the given dataset."""
interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()
input_idx = interpreter.get_input_details()[0]['index']
output_idx = interpreter.get_output_details()[0]['index']
results = []
for data in representative_dataset(dataset)():
interpreter.set_tensor(input_idx, data[0])
interpreter.invoke()
results.append(interpreter.get_tensor(output_idx).flatten())
results = np.array(results)
gt_labels = np.array(list(dataset.map(lambda data: data['label'] + 1)))
accuracy = (
np.sum(np.argsort(results, axis=1)[:, -5:] == gt_labels.reshape(-1, 1)) /
gt_labels.size)
print(f'Top-5 accuracy (quantized): {accuracy * 100:.2f}%')
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(224, 224, 3), batch_size=1),
hub.KerasLayer(MODEL_URI)
])
model.compile(
loss='sparse_categorical_crossentropy',
metrics='sparse_top_k_categorical_accuracy')
model.build([1, 224, 224, 3])
# Prepare dataset with 100 examples
ds = tfds.load('imagenet_v2', split='test[:1%]')
ds = ds.map(process_image)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.representative_dataset = representative_dataset(ds)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
quantized_model = converter.convert()
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']))
کوانتیزاسیون انتخابی
کوانتیزاسیون انتخابی از کمیت سازی برای برخی گره ها صرف نظر می کند، به طوری که محاسبه می تواند در حوزه ممیز شناور اصلی انجام شود. وقتی لایههای صحیح نادیده گرفته میشوند، میتوانیم انتظار بهبود کیفیت مدل را به قیمت افزایش تاخیر و اندازه مدل داشته باشیم.
با این حال، اگر قصد دارید مدلهای کوانتیزهشده را روی شتابدهندههای فقط عدد صحیح اجرا کنید (مثلاً DSP شش گوش، EdgeTPU)، کوانتیزاسیون انتخابی باعث تکه تکه شدن مدل میشود و منجر به تاخیر استنتاج کندتر میشود که عمدتاً ناشی از هزینه انتقال داده بین CPU و آن شتابدهندهها است. . برای جلوگیری از این، شما می توانید نظر در حال اجرا تدریج آموزش آگاه به نگه داشتن تمام لایه ها در عدد صحیح در حالی که حفظ دقت مدل.
گزینه تعیین دیباگر را می پذیرد 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%
با این تکنیک ها، ما می توانیم دقت مدل موبایل نت 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 API برای دسترسی به ویژگی های عمیق
from tensorflow.lite.python import convert
حالت تأیید کل مدل
رفتار پیشفرض برای تولید مدل اشکالزدایی، تأیید هر لایه است. در این حالت، ورودی برای جفت عملیات float و quantize از یک منبع است (عمل کوانتیزه قبلی). حالت دیگر، بررسی کامل مدل است که در آن مدلهای شناور و کوانتیز از هم جدا میشوند. این حالت برای مشاهده نحوه انتشار خطا در مدل مفید خواهد بود. برای فعال کردن، 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%