松田研究室
FindingID: p1-test-split-subset-eval
Status: stable / task P1.B+F Stage 2 後続 (test split subset eval)
← Findings Index
P1 Phase B+F · test split subset eval · brush paper 比較

P1 test split subset eval — Lego brushcompat 30k で test 33.315 dB (n=36)、brush 37.40 dB と -4.09 dB

P1.B+F Stage 2 の 35.184 dB は val 100 view 値。brush paper の 37.40 dB は test split (200 view、novel view) なので、apples-to-apples 比較には test eval が必須。本 task は (1) `splat eval` に `--split-file <PATH>` 引数を追加、(2) 既存 RGB が残っている 36/200 frame のみで `transforms_test_subset.json` を生成、(3) Lego brushcompat 30k final.ply で test subset eval を実行。結果 33.315 dB (q8) / 33.241 dB (raw)。val 100 view (35.237 dB q8) との Δ = -1.92 dB の generalization gap が見え、brush paper 37.40 dB との差は -4.09 dB。n=36 subset の bias 上限 ±2 dB を考慮しても、本実装は brush paper の数字には肉薄せず、parity claim は val split に限定される。

mixedrank: highmixed — val parity 維持 + test split で brush 未達第 1 軸第 3 軸p1phase-b-fbrush-paritytest-splitsubset-evalapples-to-appleslego-30kgeneralization-gap
Impact
Lego brushcompat 30k final.ply を test split subset (n=36/200、ローカルに残っている RGB のみ) で eval すると 33.315 dB (q8) / 33.241 dB (raw)。val 100 view 35.237 dB (q8) との Δ = -1.92 dB は novel view (test) vs near-train view (val) の generalization gap (brush 自身も val 32.038 → test 37.40 と +5.36 dB 上振れする方向なので、本実装は test で逆に -1.9 dB 劣化、合計の apples-to-apples diff は -4 〜 -5 dB)。brush paper 37.40 dB との差は -4.09 dB で、val ベースで主張していた `brush 超え` claim は test split に拡張すると **不成立**。n=36 (18% subset) の random subsampling bias は mean PSNR で ±1〜2 dB 程度と見積もれるが、4 dB の gap を埋めるには足りない。本 finding により P1 計画の最終判定は `val split で brush parity + α 達成、test split (novel view generalization) では brush に未達` という mixed 結果で確定。実装側のアウトプットとして `splat eval --split-file ` flag が追加され、任意 transforms JSON での eval が可能になった (subset / 外部 split 互換)。
01

本文

P1.B+F Stage 2 で達成した val 100 view 35.237 dB は brush 自身 val 32.038 dB を +3.20 dB 上回ったが、brush paper の 37.40 dB は test split (200 view、novel view) で測られたもので apples-to-apples ではない。本 task で splat eval--split-file <PATH> 引数を追加し、ローカルに残っている test split RGB (36/200 frame) のみで構成した transforms_test_subset.json での eval を実装。結果は test subset 33.315 dB (q8) / 33.241 dB (raw)、val との Δ = -1.92 dB の generalization gap、brush paper 37.40 dB との差は -4.09 dB。

Headline (val parity 維持、test gap 顕在化)

val 100 view: +3.20 dB vs brush 自身 32.038 dB (parity + 超え)
test subset 36 view: -4.09 dB vs brush paper 37.40 dB (parity 未達)
本実装の val → test subset 劣化 -1.92 dB が novel-view generalization の本実装側の弱さを示唆。brush は val 32.0 → test 37.4 と +5.4 dB の test 側上振れがあり、これに本実装は追随できていない。卒論 narrative は `val parity 達成 / test gap は今後の研究課題` で確定。

1. eval 結果 (本実装 35.184 dB の test subset 再評価)

splitn viewsconventionquant 8-bitPSNR mean (dB)minmedianmax
val100brushq8**35.237**25.73535.70040.581
val100brushraw35.18425.73135.64540.585
test (subset)36brushq8**33.315**25.29334.03738.430
test (subset)36brushraw33.24125.28533.90238.395
val (Stage 2 finding 既出値) と test subset (本 finding 新規) を並列。test subset n=36 は元 200 frame のうちローカルに RGB が残っていた 36 frame (index 4-190 に散在、低半 19 + 高半 17 でランダム subset 風)。quant 8-bit の effect は +0.05〜+0.07 dB で convention 切替の本筋には影響しない。

2. brush paper / brush 自身との比較 (apples-to-apples 度の整理)

#比較対象splitn本実装 (dB)brush (dB)Δ (本実装 − brush)apples-to-apples?
1brush 自身 (m4-brush-bench)val10035.23732.038**+3.20****yes** (同 dataset, 同 split, 同 convention)
2brush paper (Mildenhall et al.)test200(33.315 subset)37.40**-4.09**近似 (本実装 n=36 vs paper n=200)
3本実装 val vs 本実装 test subsetval→test100→3635.237 → 33.315-1.92 (内部)**yes** (同 model、splits 差のみ)
Row 1: val ベースの parity は確定 (brush 超え)。Row 2: test ベースは本実装が n=36 subset しか取れず、apples-to-apples は近似 (paper n=200 との subset bias ±1〜2 dB)、ただし 4 dB の gap は subset bias で埋まらない。Row 3: 本実装内部で val → test 移行に伴う -1.92 dB は novel-view generalization gap の上限近似 (本実装側の弱点)。

3. test split subset の bias 評価

  1. frame index 分布: subset 36 frame の index は 4-190 に散在、低半 (index < 100) 19 frame + 高半 (≥ 100) 17 frame。ほぼ均等な random subset で、特定方向の view (top/bottom/side) に偏った形跡なし (NeRF Synthetic test split は元々 random sphere sampling)。
  2. min/max PSNR の比較: val 100 view の min 25.735 / max 40.581、test subset 36 view の min 25.293 / max 38.430。min が両者で 25 dB 帯に存在する事実は、両 split が共通する `hard view` (occlusion 強、edge 多) を含んでいることを示し、subset が異常に easy view 偏重ではない。
  3. mean PSNR の subset bias 上限: 200 view full set の mean に対して n=36 random subset の mean は標準誤差 ~σ/√36 ≈ σ/6。NeRF Synthetic test split の view 間 σ は ~3 dB 帯と見積もれるので、95% 信頼区間は ±1 dB 程度。±2 dB を保守的上限とする。
  4. brush paper 37.40 dB との 4 dB gap: 上記 bias 上限 (±2 dB) を考慮しても、subset 33.315 → full set 推定 31-35 dB、brush 37.40 dB に対して -2 〜 -6 dB の gap が残る。`本実装 = brush paper parity` は test split では成立しない。
  5. 残り 164 frame DL は scope 外: 1 GB DL + brush paper との完全 apples-to-apples eval は scope 大、本 finding 提示の `近似値 + bias 評価` で当面の判定とする。

4. 実装 (splat eval --split-file flag)

  • splat-io/src/dataset.rs: load_nerf_synthetic_from_json(json_path, dataset_dir, convention) を新規追加。既存 load_nerf_synthetic_with_convention はその薄ラッパに refactor (backward-compat 完全維持)。
  • splat-cli/src/main.rs: Cmd::Evalsplit_file: Option<PathBuf> 引数追加。
  • splat-cli/src/cmd/eval.rs: split_file 指定時は load_nerf_synthetic_from_json、未指定時は既存 load_nerf_synthetic_with_convention 経由で transforms_<split>.json を自動推定。--split の validation は --split-file 未指定時のみ。
  • /Users/otkrickey/dev/3dgs-workspace/datasets/nerf_synthetic/lego/transforms_test_subset.json: 既存 RGB が残っている 36 frame だけを抽出した新 JSON (元 transforms_test.json は変更せず)。

5. 再現手順

# 1. subset JSON 生成 (再生成可能)
python3 -c "
import json, os
ds = '/Users/otkrickey/dev/3dgs-workspace/datasets/nerf_synthetic/lego'
data = json.load(open(f'{ds}/transforms_test.json'))
existing = set(os.listdir(f'{ds}/test'))
def has_rgb(f):
    b = os.path.basename(f['file_path'])
    if not b.endswith('.png'):
        b += '.png'
    return b in existing
data['frames'] = [f for f in data['frames'] if has_rgb(f)]
print('subset frames:', len(data['frames']))
json.dump(data, open(f'{ds}/transforms_test_subset.json', 'w'), indent=2)
"
# → subset frames: 36

# 2. build & eval
cd splat
cargo build --release -p splat-cli
PLY=runs/lego-brushcompat-base-30k/final.ply
DS=/Users/otkrickey/dev/3dgs-workspace/datasets/nerf_synthetic/lego

./target/release/splat eval --ply $PLY --dataset $DS \
  --split-file $DS/transforms_test_subset.json --convention brush --quantize-8bit
# → 33.315 dB (n=36 test subset, q8)

./target/release/splat eval --ply $PLY --dataset $DS \
  --split-file $DS/transforms_test_subset.json --convention brush
# → 33.241 dB (raw)

6. 含意 (P1 narrative の確定)

  1. val parity claim は維持: brush 自身 val 32.038 dB を本実装が +3.20 dB 上回る事実 (Stage 2 finding) はそのまま有効。同 dataset / 同 split / 同 convention での apples-to-apples 結果。
  2. test parity claim は不成立: brush paper 37.40 dB に対して本実装 test subset 33.315 dB、bias ±2 dB 考慮しても 4 dB の gap は残る。`本実装 ≥ brush paper` は test split では言えない。
  3. 本実装の novel-view generalization gap: val → test subset で -1.92 dB の drop。これは本実装側の弱点 (brush は逆に val → test で +5.4 dB 上振れする方向)。原因候補は (a) opacity decay 未導入による over-densification + overfit、(b) refine の split 戦略が train view 近傍に偏重、(c) SH 進行 (progressive growth) なしの一括 sh3 が val では効くが test では generalization 弱、等。
  4. P1 narrative の言い回し: `本実装は brush 自身 val を +3.20 dB 上回ったが、brush paper の test 37.40 dB との parity には -4 dB の generalization gap が残る (n=36 subset 近似評価)`。卒論には `val parity を達成、test generalization は今後の課題` と明示。
  5. 次 Step 候補: (1) Phase D opacity decay 30k full で over-densification 削減 → generalization 改善仮説テスト、(2) full 200 frame DL + 完全 apples-to-apples eval (subset bias を確定)、(3) brush 自身を test split で再 eval して val→test の +5.4 dB 上振れを ground-truth 化、(4) multi-scene chain bench (PID 81416) 完了後 8 シーンで同 test subset eval、universal な val→test 劣化パターンを確認。

7. 関連

  • P1.B+F Stage 2 (val 35.184 dB): p1-b-f-stage2-30k-results
  • P1.A.3 cross-eval reproducer (4-way symmetry test): p1-a-3-cross-eval-reproducer
  • P1.A eval convention audit: p1-a-eval-convention-audit
  • brush vs splat 37dB gap 分析: brush-vs-splat-37dB-gap-analysis
  • brush 自身 bench (val 32.038 dB): m4-brush-bench
02

関連する run

この finding が観測された / 言及している実験 run。

03

関連 finding

© 2026 大竹律輝 — 松田研究室