TT Lab
はじめる
学ぶ 学習パス コース

AIダイエット失敗事件

この差は再現する差か — 精度低下の測り方

TT Labで続きを見る

目標

同じテストサンプルで、FP32のオリジナル・以前のデプロイ版・整数化した候補の3つを動かして、予測と出力値を残し、精度の差が再現される差かどうかを判断するツールacccmp.pyを作成します。区間・ペア比較・反転したサンプル・出力の差をそれぞれ測り、ベースラインを2つ置いて判定を下します。

なぜ重要なのか

「精度が0.3%落ちた」は、それ自体では判断の根拠になりません。サンプル400個で、精度1つの95%信頼区間は、幅が8パーセントポイントに近くなります。2つのモデルを別々に測って引き算した値では、これより小さい差を語れません。 語れるようにするのは、同じサンプルです。2つのモデルが同じ入力を見たなら、どちらも当てたサンプルと、どちらも外したサンプルは判定に使えず、片方だけが当てたサンプルだけが情報になります。その分かれた件数が実際の分母です。 ベースラインも1つではありません。FP32のオリジナルは、量子化でどれだけ削られたかに答え、以前のデプロイ版は、今動いているものより悪くなるかに答えます。2つの答えが逆の向きになることがあるので、両方を書きます。 そして、出力の差とタスクの指標は別のものです。最大絶対誤差が大きく出ても精度は変わらないことがあり、その逆もあります。判断の境界から遠いサンプルは、出力が揺れても答えが変わらないからです。 採点ツールは、皆さんが書いた数字を信じません。毎回違うシードとサンプル数で自分の予測表を用意して皆さんのツールを実際に実行し、同じ計算をやり直して照合します。ステップ1は、皆さんが残したシードでテスト入力を作り直して、皆さんのモデルを直接動かしてみます。

ステップ

  1. /root/acc/gen_eval.pyを作成して実行し、モデル3つを作ってください(出力先: /root/acc/preds.json、/root/acc/eval_seed.json)。
  2. /root/acc/acccmp.pyにsummaryを作成して、サンプル数と実行ごとの精度を出力させてください。
  3. intervalを追加して、精度1つの95%信頼区間を、Wilsonスコア区間で出力させてください。
  4. pairedを追加して、同じサンプルでの2x2の分かれた件数と、ペア比較の統計量を出力させてください。
  5. flipsを追加して、反転した予測だけを向きごとに数えさせてください。
  6. outputsを追加して、出力値の差(最大絶対誤差・平均絶対誤差・コサイン)を出力させてください。
  7. baselineを追加して、2つのベースラインをそれぞれ比べさせ、皆さんのデータの判定を書いてください(出力先: /root/acc/verdict.json)。
  8. /root/acc/accuracy_report.mdを4つのセクションで書いてください。

参考

3つのバージョンを同じサンプルで動かして予測を残す

/root/acc/gen_eval.pyを作成して実行し、/root/accの下にfp32.onnx・prev.onnx・int8.onnxと、/root/acc/preds.json、/root/acc/eval_seed.jsonを作ってください。テスト入力と正解ラベルは、参考のセクションのシードの規則にそのまま従います。

モデルは、onnx.helperでMatMul + Add + Reluをつなげて作ります。prev.onnxはquantize_dynamic、int8.onnxはquantize_staticにCalibrationDataReaderを渡して作ります。正解ラベルをFP32の出力から作りつつ、ノイズを加えるのは、精度が1.0だとどんな差も見えないからです。logitsはfloat()でそのまま書き、丸めないでください。

サンプル数と精度を1か所にまとめる

/root/acc/acccmp.pyにsummary <preds.json>を作成して、サンプル数と実行ごとの正解件数・精度をJSONで出力させてください。

合計から出さずに、サンプルごとに当たったかどうかを真偽のリストで残してください。あとのステップのペア比較と反転の集計は、すべてこのリストの上で行われます。実行名は並べ替えて入れます。

精度1つに区間を付ける

interval <preds.json> <run>を追加して、その実行の精度に、95%のWilsonスコア区間を付けて出力させてください。run・n・correct・accuracy・center・low・high・half_widthを入れます。

zは1.96に固定します。Wilson区間の中心は、サンプルの比率pではなく、0.5のほうに少し引き寄せられた値です。そのため、lowとhighは、pを真ん中にしません。精度が0や1でも幅が0にならないことが、この区間を使う理由です。

同じサンプルでペアにして比べる

paired <preds.json> <a> <b>を追加して、2x2の表(both_correct・only_a・only_b・both_wrong)と、delta・discordant・statistic・significantを出力させてください。

どちらも当てたサンプルと、どちらも外したサンプルは、2つのモデルを分けられません。判定の分母はnではなく、分かれた件数です。統計量は参考のセクションの式をそのまま使い、分かれた件数が0なら0.0とします。

反転した予測だけを向きごとに数える

flips <preds.json> <a> <b>を追加して、changed・to_wrong・to_right・changed_both_wrong・top_flipを出力させてください。

changedは、残り3つの合計です。この恒等式が合わなければ、どこかを2回数えたか、数え漏らしたのです。間違った答えが別の間違った答えに変わった件数は、精度に影響しませんが、ユーザーの目には答えが変わったと見えます。

出力の差とタスクの指標を分けて測る

outputs <preds.json> <a> <b>を追加して、max_abs_error・mean_abs_error・cos_min・cos_mean・argmax_changedを出力させてください。

出力が大きく動いたからといって、判断が変わるとは限りません。判断の境界から遠いサンプルは、出力が揺れても答えがそのままです。2つの値を1つの応答に入れて並べて見ると、その関係が目に入ります。

ベースラインを2つ置いて判定する

baseline <preds.json> <run>を追加して、残りの実行をそれぞれベースラインにして比べさせ、皆さんのデータの判定を、参考のセクションのキーで書いてください(出力先: /root/acc/verdict.json)。

オリジナルと以前のデプロイ版で、答えが逆の向きになることがあります。worstは、deltaが最も小さいベースラインで、同数なら名前が先のほうです。判定の規則は参考のセクションに固定されているので、そのまま写し、reasonには、なぜそうなったのかを1行で書いてください。

読む人が判断できるように書く

/root/acc/accuracy_report.mdを、## 무엇을 견주었나 ## 같은 표본에서 본 차이 ## 이 차이가 재현되는가 ## 판정과 한계の4つのセクションで書いてください(韓国語の見出しは、順に「何を比べたか」「同じサンプルで見た差」「この差は再現されるのか」「判定と限界」という意味です)。サンプル数・分かれた件数・判定が、数字と言葉で本文に入っている必要があります。

数字を書くときは、どこから出た数字なのかも一緒に書いてください。限界のセクションには、この判定が語らないことを書きます。このラボは、時間もメモリも測っておらず、1組のテストサンプルだけで見たものです。