ヘルプKaggleにTensorFlowグレートバリアリーフを保護チャレンジに参加

量子化デバッガを使用した量子化エラーの検査

TensorFlow.orgで表示GoogleColabで実行GitHubでソースを表示 ノートブックをダウンロードTFハブモデルを参照してください

フル整数の量子化によりモデルのサイズとレイテンシが改善されますが、量子化されたモデルは常に期待どおりに機能するとは限りません。通常、モデルの品質(精度、mAP、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

ボイラープレートとヘルパー

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

ダンプの行ごとに、OP名とインデックスが(を含む量子化パラメータと誤差メトリック、続いて最初に来るユーザー定義エラーメトリックもしあれば)。結果の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()

png

多くの広い範囲を持つ層、および高い持っているいくつかの層があります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など)で量子化モデルを実行することを計画している場合、選択的な量子化はモデルの断片化を引き起こし、主にCPUとそれらのアクセラレータ間のデータ転送コストが原因で推論レイテンシが遅くなります。これを防ぐには、実行することを検討することができ、量子化を意識トレーニングをモデルの精度を維持しながら、整数内のすべてのレイヤーを維持します。

量子化デバッガのオプションが受け入れdenylisted_nodesしてdenylisted_ops特定の層、または特定の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%

精度は元のフロートモデルと比較してまだ低いですが、111層のうち約10層の量子化をスキップすることにより、量子化モデル全体から顕著な改善が見られます。

同じクラスのすべての操作を量子化しないようにすることもできます。たとえば、すべての平均OPSのための量子化をスキップするには、渡すことができ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%

これらの手法により、量子化されたMobileNetV3モデルの精度を向上させることができます。次に、モデルの精度をさらに向上させるための高度な手法について説明します。

高度な使用法

次の機能を使用して、デバッグパイプラインをさらにカスタマイズできます。

カスタムメトリック

デフォルトでは、量子化デバッガーは、float-quantの差ごとに、テンソルサイズ、標準偏差、平均誤差、最大絶対誤差、および平均二乗誤差の5つのメトリックを出力します。オプションに渡すことで、カスタムメトリックをさらに追加できます。メトリックごとに、結果は単精度浮動小数点値である必要があり、結果のメトリックはすべての例のメトリックの平均になります。

  • layer_debug_metrics :フロートと量子化された演算出力から各オペアンプ出力の差分に基づいてメトリックを計算します。
  • layer_direct_compare_metrics :むしろ、唯一の差分を取得するよりも、これは生のフロートと量子化されたテンソルに基づいてメトリックを計算し、その量子化パラメータ(スケール、ゼロ点)
  • model_debug_metrics場合にのみ使用float_model_(path|content)デバッガに渡されます。 opレベルのメトリックに加えて、最終レイヤーの出力は、元のフロートモデルからの参照出力と比較されます。
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_quantizeAPIを使用して詳細な機能にアクセスする

from tensorflow.lite.python import convert

モデル全体の検証モード

デバッグモデル生成のデフォルトの動作は、レイヤーごとの検証です。このモードでは、floatとquantize opのペアの入力は同じソース(以前の量子化されたop)からのものです。もう1つのモードは、モデル全体の検証です。このモードでは、フロートモデルとクオンタイズモデルが分離されます。このモードは、エラーがモデルにどのように伝播しているかを観察するのに役立ちます。有効にするには、 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すでに較正されたモデルから選択量子化されたモデルを取得します。これは、モデルを1回キャリブレーションし、さまざまな拒否リストの組み合わせを試してみたい場合に特に便利です。

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%