Quantization Debugger ile Quantization Hatalarını İnceleme

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir TF Hub modeline bakın

Tam tamsayı niceleme, gelişmiş model boyutu ve gecikme süresi sağlamasına rağmen, nicelenmiş model her zaman beklendiği gibi çalışmayacaktır. Genellikle model kalitesinin (örn. doğruluk, mAP, WER) orijinal şamandıra modelinden biraz daha düşük olması beklenir. Ancak model kalitesinin beklentinizin altına düşebileceği veya tamamen yanlış sonuçlar doğurabileceği durumlar vardır.

Bu sorun meydana geldiğinde, niceleme hatasının temel nedenini tespit etmek zor ve acı vericidir ve niceleme hatasını düzeltmek daha da zordur. Bu model, denetim işlemini yardımcı olmak için, niceleme ayıklayıcı sorunlu katmanları tespit etmek için kullanılabilir, ve model doğruluğu niceleme indirgenmiş yarar pahasına elde edilebilir, böylece, seçici nicemleme float problemli katmanları bırakabilir.

Niceleme Hata Ayıklayıcısı

Niceleme hata ayıklayıcısı, mevcut modelde nicemleme kalitesi metrik analizi yapmayı mümkün kılar. Niceleme hata ayıklayıcısı, bir hata ayıklama veri kümesiyle model çalıştırma ve her tensör için niceleme kalite metrikleri toplama işlemlerini otomatikleştirebilir.

Önkoşullar

Bir modeli nicelemek için zaten bir işlem hattınız varsa, niceleme hata ayıklayıcısını çalıştırmak için gerekli tüm parçalara sahipsiniz!

  • kuantize edilecek model
  • Temsili veri seti

Model ve verilere ek olarak, dışa aktarılan sonuçları analiz etmek için bir veri işleme çerçevesi (örneğin pandalar, Google E-Tablolar) kullanmanız gerekecektir.

Kurmak

Bu bölüm kütüphaneleri, MobileNet v3 modelini ve 100 imajlık test veri setini hazırlar.

# 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

Kazan plakaları ve yardımcıları

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%

Küçük veri kümemiz için orijinal modelin çok daha yüksek ilk 5 doğruluğuna sahip olduğunu görebiliriz, nicemlenmiş model ise önemli bir doğruluk kaybına sahiptir.

Adım 1. Hata ayıklayıcı hazırlığı

Nicemleme debugger kullanımı kolay yolu sağlamaktır tf.lite.TFLiteConverter modelini miktarlarını belirlemek için kullanıyoruz söyledi.

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

Adım 2. Hata ayıklayıcıyı çalıştırma ve sonuçları alma

Aradığınızda QuantizationDebugger.run() , ayıklayıcı aynı op konumu için şamandıra tensörleri ve nicelenmiş tensörlerle arasındaki farklılıkları log ve verilen ölçümler ile bunları işleyecek.

debugger.run()

İşlenmiş metrikleri ile erişilebilir QuantizationDebugger.layer_statistics veya CSV formatında bir metin dosyasına terk edilebilir 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

Çöplükte her satır için op adı ve dizin (dahil niceleme parametreleri ve hata metrikleri ardından önce gelir kullanıcı tanımlı hata metrikleri varsa). Ortaya çıkan CSV dosyası, büyük nicemleme hatası ölçümleriyle sorunlu katmanları seçmek için kullanılabilir.

Pandalar veya diğer veri işleme kitaplıkları ile, ayrıntılı katman başına hata ölçümlerini inceleyebiliriz.

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

Adım 3. Veri analizi

Sonucu analiz etmenin çeşitli yolları vardır. İlk olarak, hata ayıklayıcının çıktılarından türetilen bazı yararlı ölçümleri ekleyelim. ( scale her tensörü için nicemleme ölçek faktörünü ifade eder.)

  • Sınıf ( 256 / scale )
  • RMSE / ölçeği ( sqrt(mean_squared_error) / scale )

RMSE / scale yakın olan 1 / sqrt(12) iyi bir nicemlenmiş modeli gösteren, (~ 0.289) nicelenmiş dağılımı orijinal float dağılımı benzerdir. Değer ne kadar büyükse, katmanın iyi nicelleştirilmemesi daha olasıdır.

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

png

Birçok geniş aralıkları ile katmanları ve yüksek olan bazı katmanları vardır RMSE/scale değerlerini. Hata metrikleri yüksek olan katmanları alalım.

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

Bu katmanlarla, bu katmanları nicelememenin model kalitesini iyileştirip iyileştirmediğini görmek için seçici nicelemeyi deneyebilirsiniz.

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

Bunlara ek olarak, ilk birkaç katman için nicelemeyi atlamak, nicelenmiş modelin kalitesini iyileştirmeye de yardımcı olur.

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

seçici niceleme

Seçici niceleme, hesaplamanın orijinal kayan nokta alanında gerçekleşebilmesi için bazı düğümler için nicelemeyi atlar. Doğru katmanlar atlandığında, artan gecikme süresi ve model boyutu pahasına model kalitesinde bir miktar iyileşme bekleyebiliriz.

Ancak, nicelenmiş modelleri yalnızca tamsayı hızlandırıcılarda (örneğin Hexagon DSP, EdgeTPU) çalıştırmayı planlıyorsanız, seçici niceleme modelin parçalanmasına neden olur ve esas olarak CPU ile bu hızlandırıcılar arasındaki veri aktarım maliyetinden kaynaklanan daha yavaş çıkarım gecikmesine neden olur. . Bunu önlemek için, çalıştırmakta düşünebilirsiniz nicemleme farkında eğitim modeli doğruluğunu koruyarak tamsayı tüm katmanları tutmak.

Kuantalama Ayıklayıcı'nın seçeneği kabul denylisted_nodes ve denylisted_ops belirli katmanları veya belirli ops tüm örneklerini nicelemesini atlama için seçenekler. Kullanma suspected_layers önceki adımda hazırlanmış, bir seçici nicemlenmiş bir model elde etmek için niceleme hata ayıklayıcı kullanabilir.

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%

Doğruluk, orijinal şamandıra modeline kıyasla hala daha düşüktür, ancak nicemlemeyi 111 katmandan ~10 katman için atlayarak, nicelleştirilmiş modelin tamamından kayda değer bir gelişme elde ettik.

Aynı sınıftaki tüm operasyonları nicelememeyi de deneyebilirsiniz. Örneğin, tüm ortalama operasyonlar için nicelemesini atlamak, sen iletebilirsiniz MEAN için 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%

Bu tekniklerle, nicelenmiş MobileNet V3 model doğruluğunu iyileştirebiliyoruz. Ardından, model doğruluğunu daha da artırmak için gelişmiş teknikleri keşfedeceğiz.

Gelişmiş kullanımlar

Aşağıdaki özelliklerle, hata ayıklama işlem hattınızı daha da özelleştirebilirsiniz.

Özel metrikler

Varsayılan olarak, niceleme hata ayıklayıcısı, her bir kayan noktalı nicelik farkı için beş ölçüm yayar: tensör boyutu, standart sapma, ortalama hata, maksimum mutlak hata ve ortalama kare hatası. Seçeneklere geçirerek daha fazla özel metrik ekleyebilirsiniz. Her metrik için sonuç, tek bir kayan noktalı değer olmalıdır ve elde edilen metrik, tüm örneklerden alınan metriklerin ortalaması olacaktır.

  • layer_debug_metrics : şamandıra ve nicelenmiş op çıkışları her operasyon çıkışları için fark göre metrik hesaplanır.
  • layer_direct_compare_metrics : yerine yalnızca diff almak yerine, bu ham şamandıra ve nicelenmiş tansörler, ve nicemleme parametrelere dayalı metrik hesaplar (ölçek, sıfır noktası)
  • model_debug_metrics : Yalnızca kullanılan float_model_(path|content) ayıklayıcıya geçirilir. İşlem düzeyindeki metriklere ek olarak, son katman çıktısı, orijinal kayan nokta modelinden alınan referans çıktısıyla karşılaştırılır.
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()

Sonucu model_debug_metrics ayrı görülebilir debugger.model_statistics .

debugger.model_statistics
{'argmax_accuracy': 0.36}

Derinlemesine özelliklere erişmek için (dahili) mlir_quantize API'sini kullanma

from tensorflow.lite.python import convert

Tüm model doğrulama modu

Hata ayıklama modeli oluşturma için varsayılan davranış, katman başına doğrulamadır. Bu modda, kayan nokta ve nicemleme op çifti için giriş aynı kaynaktandır (önceki nicelenmiş op). Diğer bir mod, kayan ve nicel modellerin ayrıldığı tam model doğrulamadır. Bu mod, hatanın modelde nasıl yayıldığını gözlemlemek için faydalı olacaktır. , Etkinleştirmek için enable_whole_model_verify=True için convert.mlir_quantize elle ayıklama modeli oluşturulurken.

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

Halihazırda kalibre edilmiş bir modelden seçici niceleme

Doğrudan arayabilir convert.mlir_quantize zaten kalibre modelden seçici nicelenmiş modeli almak için. Bu, özellikle modeli bir kez kalibre etmek ve çeşitli reddetme listesi kombinasyonlarını denemek istediğinizde faydalı olacaktır.

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%