本プロジェクトの ONNX 画像処理オペレーションに対する共通テスト設計方針をまとめる.
テスト入力は以下のプロジェクト共通テンソル規約に従う. ※一部例外をのぞく
| 項目 | 規約 |
|---|---|
| レイアウト | NCHW |
| データ型 | float32 |
| チャネル順 | RGB |
| 値域 | [0, 1] (入力・出力とも) |
テストでは出力が [0, 1] 範囲に収まることも検証対象とする.
- 推論はすべて ONNX Runtime 上で実行する — Python 側のグラフ構築ロジックではなく、エクスポート済み
.onnxモデルを検証対象とする - NumPy 参照実装との一致 を正解基準とする(ONNX Runtime の浮動小数点誤差は
atol=1e-5程度を許容) - OpenCV との比較 で業界標準の画像処理ライブラリと同等の結果が得られることを担保する
- テンソル規約の遵守 — 入力は [0, 1] float32 で与え、出力も [0, 1] 範囲であることを確認する
各オペレーションのテストは以下のカテゴリを網羅すること.
出力テンソルの形状が仕様どおりであることを確認する.
| 観点 | 内容 |
|---|---|
| 単一画像 | N=1 で期待形状が得られること |
| バッチ | N>1 で全バッチに対し正しい形状が得られること |
| 動的次元 | H, W に異なるサイズを与えても動作すること |
出力値の数値的正確性を検証する.
| 観点 | 内容 |
|---|---|
| 境界値入力 | 既知の入力(純色、全白、全黒など)に対し解析解と一致すること |
| ランダム入力 | NumPy 参照実装との比較で atol=1e-5 以内に収まること |
| エッジケース | 全ゼロ入力、極大値入力などで NaN/Inf が発生しないこと |
OpenCV の対応 API を正解基準として、ONNX モデルの出力が業界標準と同等であることを検証する.
ONNX モデルと OpenCV ではデータ形式が異なるため、比較前に変換が必要.
| 項目 | ONNX モデル | OpenCV |
|---|---|---|
| チャネル順 | RGB | BGR |
| レイアウト | NCHW | HWC |
| データ型 | float32 [0, 1] | uint8 [0, 255] |
- OpenCV は uint8 で内部計算するため四捨五入による量子化誤差が生じる
- ONNX モデルは float32 で計算後に uint8 に変換する
- この経路の違いにより uint8 で ±1 の差 が許容範囲
| 観点 | 内容 |
|---|---|
| ランダム画像 | 多様なピクセル値で全画素の差が ±1 以内であること |
| 純色入力 | 各チャネル単色 (赤/緑/青) で OpenCV と一致すること |
| グラデーション | 階調変化する画像で最大差が ±1 以内であること |
def _nchw_to_hwc_uint8(nchw: np.ndarray) -> np.ndarray:
"""NCHW float32 [0,1] → HWC uint8 [0,255] に変換する."""- 単一画像 (バッチの先頭) を取り出して OpenCV 入力形式に変換
- ONNX 出力との比較前に RGB→BGR 変換も行うこと
ONNX モデル自体の構造が正しいことを検証する(必要に応じて追加).
| 観点 | 内容 |
|---|---|
| checker 通過 | onnx.checker.check_model がエラーなく通ること |
| opset バージョン | 期待する opset version で構築されていること |
| 入出力名 | input_specs / output_specs と実モデルの入出力名が一致すること |
@pytest.fixture(scope="module", autouse=True)
def ensure_model():
"""モデルファイルが無ければ export_all.py を実行して生成する."""scope="module"— テストモジュールごとに1回だけ実行autouse=True— 明示的な指定なしで全テストに適用- モデルが既に存在すれば再生成をスキップ(高速化)
@pytest.fixture(scope="module")
def session():
"""ONNX Runtime の推論セッションを返す."""- モジュールスコープでセッションを共有し、テストごとのロード時間を削減
def _run(session, img: np.ndarray) -> np.ndarray:
"""セッションで推論を実行し、最初の出力を返す."""- 入力名はオペレーションの
input_specsに合わせる - 戻り値は最初の出力テンソル(単一出力の場合)
Test{OpName}OutputShape — 形状テスト
Test{OpName}Values — 値テスト (NumPy 参照実装との比較)
Test{OpName}VsOpenCV — OpenCV 比較テスト
Test{OpName}ModelIntegrity — モデル整合性テスト(任意)
tests/test_{op_name}.pyを作成- 上記4カテゴリのテストを実装(OpenCV 比較テスト含む)
ensure_modelfixture でモデルの自動生成を設定pytest tests/ -vで全テスト PASS を確認