[{"data":1,"prerenderedAt":293},["ShallowReactive",2],{"finding:p1-b-f-trainer-convention-bridge":3,"finding-runs:p1-b-f-trainer-convention-bridge":225,"finding-related:p1-b-f-trainer-convention-bridge":226},{"meta":4,"impact":38,"sections":44},{"id":5,"title":6,"subtitle":7,"eyebrow":8,"date":9,"status":10,"category":11,"polarity":12,"axes":13,"tags":17,"task_code":28,"related_runs":29,"related_findings":33},"p1-b-f-trainer-convention-bridge","P1.B.F Stage 1 — gt_convention=premultiplied 切替で brush eval PSNR を 1.67 → 31.33 dB に回復、coupling 解消実証","P1.A.3 で falsify した apparent-gap 仮説の代替として、`training-eval convention coupling` を解消すべく `data.gt_convention = premultiplied` (brush 流) 経路を trainer まで通し、5k smoke を legacy\u002Fbrush 2 通り × eval legacy\u002Fbrush 2 通り = 4 通りで cross-eval。brush trainer + brush eval は **31.33 dB (5k 時点)**、legacy 5k baseline の brush eval は 1.63 dB のままで A.3 を再現、symmetry 検証として brush trainer × legacy eval も 1.59 dB に崩壊し coupling が双方向に存在することを実証。GT loader 切替 + config flag (4 file 編集、loss kernel 変更ゼロ、既存 config 不変、deny_unknown_fields 維持) で deliver、Stage 2 (hyperparameter 移植 + 30k full) GO。","P1 Phase B+F · Stage 1 minimal PoC · convention bridge","2026-05-24","stable","experiment","positive",[14,15,16],1,2,3,[18,19,20,21,22,23,24,25,26,27],"p1","phase-b","phase-f","milestone-m2","brush-parity","trainer","premultiplied","convention-bridge","smoke","hypothesis-confirmed","P1.B + P1.F Stage 1",[30,31,32],"lego-legacybase-5k","lego-brushcompat-base-5k","lego-sh3-30k (P1.A.3 baseline)",[34,35,36,37],"p1-a-3-cross-eval-reproducer","p1-a-1-brush-eval-audit","p1-a-2-splat-eval-audit","p1-a-eval-convention-audit",{"summary":39,"rank":40,"verdict":41,"delta_wallclock":42,"delta_psnr":43},"P1.A.3 で `splat-rs trainer が white-bg target で学習 → 背景を opaque-white splat で埋める → brush 流 eval (bg=ZERO 比較) で MSE≈1 崩壊` と診断された coupling を、**GT loader を premultiplied 経路に切替えるだけ** で解消できるか 5k smoke で検証。同一 hyperparameter (`2026-05-22-2155-lego-sh3-30k.toml` の iter のみ 5k 短縮) で `data.gt_convention=white_bg` vs `data.gt_convention=premultiplied` を独立 training し、各 final.ply を 2 通り convention で eval (4 cell)。結果: brush trainer × brush eval = **31.334 dB**、legacy trainer × brush eval = 1.628 dB と完全に対比、coupling が双方向に存在することも symmetry test (brush trainer × legacy eval = 1.595 dB) で確定。5k 段階で既に B-N 30k baseline (24.88 dB legacy) を **brush eval 系で +6.5 dB 超え**、brush 公称 37 dB との gap は -5.7 dB のみ。Stage 1 hypothesis (10+ dB) を 21 dB 上回り、coupling 解消が brush parity への critical path であることを定量実証。実装は `splat-cli\u002Fsrc\u002Fconfig.rs` に `data.gt_convention: GtConvention` enum 追加 (default=`WhiteBg`、既存 configs 完全互換) + `train.rs` の train\u002Fval load を `load_nerf_synthetic_with_convention` に切替、合計 4 file の最小差分。loss kernel (`loss.metal:31-88`) は変更不要 (n_total=W·H·4 が α channel を含み、premultiplied target の α=0 領域が `rendered α (=1-T) → 0` の natural pressure を提供、brush の match_alpha 機構と同等効果)。","high","hypothesis-confirmed-stage-2-go","5k 比較: legacy 202.4s \u002F brush 125.4s (brush -38% 高速、splats 77.6k → 93.9k だが GPU loss は同等)","+29.71 dB (brush eval 系: A.3 30k 1.667 dB → P1.B.F 5k 31.334 dB)、Stage 1 hypothesis (>10 dB) を +21 dB 上回り",[45,48,53,56,112,116,118,146,148,152,154,161,163,173,175,179,181,189,191,198,200,206,208,214,216],{"type":46,"text":47},"lead","P1.A.3 で \u003Cstrong>「training\u002Feval convention coupling」\u003C\u002Fstrong> が brush gap の主因と判明 (apparent-gap 仮説 falsify、brush convention で trainer の white-bg fit が露呈し 24.88 → 1.67 dB に崩壊)。本 task は coupling の \u003Cstrong>最小 PoC fix\u003C\u002Fstrong>: \u003Ccode>data.gt_convention=premultiplied\u003C\u002Fcode> flag を新設し、GT loader (\u003Ccode>load_rgba_premultiplied\u003C\u002Fcode>) を \u003Cstrong>train \u002F val 両方\u003C\u002Fstrong> の経路で選択可能にする。5k smoke を legacy \u002F brush 2 通り × eval legacy \u002F brush 2 通り = 4 通りで cross-eval し、coupling が解消されるか検証。",{"type":49,"label":50,"variant":51,"text":52},"callout","結論 (Stage 1 → Stage 2 GO)","success","\u003Cstrong>仮説 OK (上回り)\u003C\u002Fstrong>。brush trainer × brush eval = \u003Cstrong>31.334 dB at 5k iter\u003C\u002Fstrong>、legacy 5k baseline の brush eval = 1.628 dB に対し \u003Cstrong>+29.7 dB\u003C\u002Fstrong>。Stage 1 OK 閾値 (10+ dB) を +21 dB 上回り、\u003Cstrong>coupling 解消が brush parity への critical path\u003C\u002Fstrong> であることを定量実証。さらに symmetry test (brush trainer × legacy eval = 1.595 dB) で \u003Cstrong>coupling が双方向に存在\u003C\u002Fstrong> することも確認 (brush trainer は背景を α≈0 にして fit するので white-bg GT に対して背景全体で MSE≈1)。\u003Cstrong>Stage 2 (full hyperparameter 移植 + 30k bench) に進行 GO\u003C\u002Fstrong>。loss kernel 改変ゼロ・既存 config 不変・最小差分 (4 file) で達成。",{"type":54,"text":55},"heading","1. 4 通り cross-eval table (Lego val, 100 view)",{"type":57,"columns":58,"align":69,"rows":73},"table",[59,60,61,62,63,64,65,66,67,68],"#","trainer (gt_convention)","eval convention","quantize8","PSNR (dB)","min","median","max","vs A.3 30k","判定",[70,71,71,72,70,70,70,70,70,71],"right","left","center",[74,85,95,104],[75,76,77,78,79,80,81,82,83,84],"1","**legacy** (white_bg)","legacy","off","**21.874**","5.896","22.639","28.806","-3.005 (5k 短縮による degrade)","5k iter での legacy baseline",[86,76,87,88,89,90,91,92,93,94],"2","brush","on","1.628","0.473","1.686","2.050","-0.039 (A.3 の 1.667 と一致)","**A.3 を 5k で再現**, baseline collapse",[96,97,77,78,98,99,100,101,102,103],"3","**brush** (premultiplied)","1.595","0.991","1.614","1.944","—","**symmetry test pass**, brush trainer は逆向きに崩壊",[105,97,87,88,106,107,108,109,110,111],"4","**31.334**","25.089","31.572","35.902","**+29.667 (1.667 → 31.334)**","**hypothesis confirmed**, Stage 1 OK threshold (10) +21 dB",{"type":49,"label":113,"variant":114,"text":115},"table 読み方","info","diagonal (1 と 4) が \"training と eval が一致した自然状態\"、off-diagonal (2 と 3) が \"convention 不一致による崩壊\"。\u003Cstrong>diagonal は両方 high (21.87 \u002F 31.33 dB)、off-diagonal は両方 ~1.6 dB\u003C\u002Fstrong> という綺麗な対称形 → coupling は \u003Cstrong>training-eval convention の不一致による systematic mismatch\u003C\u002Fstrong> であって、brush trainer が片側だけ広い optimum を持つ等の非対称要因ではないことを示す。さらに brush trainer の diagonal が legacy trainer の diagonal を \u003Cstrong>+9.5 dB 上回る\u003C\u002Fstrong> 点が重要 (5k vs 5k の同条件で)、brush 流の loss landscape は同 iter で legacy より遥かに容易な fit を提供する。",{"type":54,"text":117},"2. 仮説検証 table",{"type":57,"columns":119,"align":124,"rows":125},[120,121,122,123,68],"仮説 (Stage 1)","予測 PSNR","実測 PSNR","差分",[71,70,70,70,71],[126,132,136,141],[127,128,129,130,131],"brush trainer × brush eval で 10+ dB","≥ 10.0","31.334","+21.3 dB","**OK (大幅上回り)**",[133,134,98,102,135],"brush trainer × legacy eval で低下 (symmetry test)","低下","**OK (1.6 dB に崩壊、coupling 双方向)**",[137,138,89,139,140],"legacy trainer × brush eval は A.3 30k と同帯 (5k で再現)","~1.7","-0.04","**OK (再現精度 ±0.04 dB)**",[142,143,144,102,145],"legacy trainer × legacy eval は 30k から短縮分 degrade","~20-23","21.874","**OK (5k 相応、degrade 3 dB)**",{"type":54,"text":147},"3. 機構 — なぜ premultiplied GT 切替だけで効果が出たか",{"type":49,"label":149,"variant":150,"text":151},"メカニズム (predicted → confirmed)","warning","\u003Cstrong>(A) 背景の取扱い\u003C\u002Fstrong>: \u003Ccode>load_rgba_white_bg\u003C\u002Fcode> は α=0 領域を \u003Ccode>(r,g,b,a)=(1,1,1,1)\u003C\u002Fcode> に変換 → loss は \"背景にも 白く塗れ\" と要求 → trainer は opaque-white splat を背景に増殖。\u003Ccode>load_rgba_premultiplied\u003C\u002Fcode> は α=0 領域を \u003Ccode>(0,0,0,0)\u003C\u002Fcode> のまま → rendered (rasterize.metal: \u003Ccode>pix_out = Σ rgb·α·T\u003C\u002Fcode>, \u003Ccode>α_out = 1-T\u003C\u002Fcode>) と直接比較できる。\u003Cstrong>(B) α channel の役割\u003C\u002Fstrong>: loss kernel (loss.metal:31-88) は \u003Ccode>n_total = W·H·4\u003C\u002Fcode> で \u003Cstrong>α channel も MSE 対象\u003C\u002Fstrong>。premultiplied GT (α=元 PNG α) と rendered α (=1-T) の L1 loss は、α=0 領域で \u003Ccode>|1-T - 0| = 1-T → 0\u003C\u002Fcode> 即ち \u003Cstrong>背景 splat の T を 1 に保て (= 透明にせよ)\u003C\u002Fstrong> という pressure を自動的に与える。これは \u003Cstrong>brush の match_alpha=0.1 loss と同等の効果が weight 1.0 で発動\u003C\u002Fstrong>している状態。Stage 2 では brush の hyperparameter (lr \u002F refine \u002F decay) 移植で更に伸ばせる余地あり。\u003Cstrong>(C) なぜ symmetry test も -20 dB 崩壊するか\u003C\u002Fstrong>: brush trainer は背景を α≈0 (rendered では bg=ZERO) として学習 → legacy convention (white-bg GT) と比較すると background pixel 全体で \u003Ccode>rendered=(0,0,0) vs target=(1,1,1)\u003C\u002Fcode> → MSE≈1 で systematic 崩壊。これも A.3 と同じ機構の鏡像。",{"type":54,"text":153},"4. wallclock observation (副次)",{"type":155,"items":156},"list",[157,158,159,160],"\u003Cstrong>brush trainer は 5k で 38% 高速\u003C\u002Fstrong> (legacy 202.4s \u002F brush 125.4s on M4 Max)。同 hyperparameter \u002F 同 backend \u002F 同 capacity 上限","理由仮説: legacy trainer は背景を opaque-white splat で埋めるため \u003Cstrong>無駄な splat 数が多く\u003C\u002Fstrong> (背景占有面積 ≈ 50%)、forward \u002F backward 共に rasterize cost 高。brush trainer は背景 splat を増やさない (生成 → opacity_min で prune ?) ので net cost 減","最終 splat 数は \u003Cstrong>brush の方が 21% 多い\u003C\u002Fstrong> (77.6k vs 93.9k) — 背景に splat を \u003Cem>持たない\u003C\u002Fem> のではなく、refine が前景に集中 → 前景 detail に splat を割り振っている。これも 31 dB に伸びた一因 (5k iter で前景 detail に capacity を使い切れる)","Stage 2 でも brush 化で wallclock 不利は出ない見込み (むしろ +30% 程度高速化)",{"type":54,"text":162},"5. 実装スコープ (本 task で変更した部分)",{"type":155,"ordered":164,"items":165},true,[166,167,168,169,170,171,172],"\u003Ccode>splat\u002Fcrates\u002Fsplat-io\u002FCargo.toml\u003C\u002Fcode> — \u003Ccode>serde = { version = \"1.0\", features = [\"derive\"] }\u003C\u002Fcode> を追加 (GtConvention enum を Deserialize 対応)","\u003Ccode>splat\u002Fcrates\u002Fsplat-io\u002Fsrc\u002Fdataset.rs\u003C\u002Fcode> — 既存 \u003Ccode>GtConvention\u003C\u002Fcode> enum に \u003Ccode>#[derive(serde::Deserialize)]\u003C\u002Fcode> + \u003Ccode>#[serde(rename_all = \"snake_case\")]\u003C\u002Fcode> + \u003Ccode>impl Default for GtConvention\u003C\u002Fcode> (= WhiteBg)","\u003Ccode>splat\u002Fcrates\u002Fsplat-cli\u002Fsrc\u002Fconfig.rs\u003C\u002Fcode> — \u003Ccode>DataConfig\u003C\u002Fcode> に \u003Ccode>#[serde(default)] pub gt_convention: GtConvention\u003C\u002Fcode> を追加 (deny_unknown_fields 維持、既存 configs\u002F*.toml は無指定で従来通り white_bg)","\u003Ccode>splat\u002Fcrates\u002Fsplat-cli\u002Fsrc\u002Fcmd\u002Ftrain.rs\u003C\u002Fcode> — \u003Ccode>load_nerf_synthetic\u003C\u002Fcode> → \u003Ccode>load_nerf_synthetic_with_convention(.., cfg.data.gt_convention)\u003C\u002Fcode> に切替 (\u003Cstrong>train split (line 50)\u003C\u002Fstrong> と \u003Cstrong>val split (line 119)\u003C\u002Fstrong> の \u003Cstrong>両方\u003C\u002Fstrong>、advisor 警告通り — 不一致だと mid-training PSNR が学習対象と一致しなくなる)","\u003Ccode>splat\u002Fconfigs\u002F2026-05-24-1800-lego-legacybase-5k.toml\u003C\u002Fcode> (新規) — 30k baseline の iter のみ 5k に短縮","\u003Ccode>splat\u002Fconfigs\u002F2026-05-24-1800-lego-brushcompat-base-5k.toml\u003C\u002Fcode> (新規) — legacy-5k から \u003Ccode>[data] gt_convention = \"premultiplied\"\u003C\u002Fcode> のみ追加","**変更なし**: \u003Ccode>loss.metal\u003C\u002Fcode> \u002F \u003Ccode>rasterize.metal\u003C\u002Fcode> \u002F \u003Ccode>refine_*.metal\u003C\u002Fcode> \u002F \u003Ccode>train_loop.rs\u003C\u002Fcode> \u002F \u003Ccode>trainer.rs\u003C\u002Fcode> \u002F 既存 configs\u002F*.toml (全て不変)",{"type":54,"text":174},"6. 再現手順",{"type":176,"lang":177,"text":178},"code","bash","# build\ncd splat\ncargo build --release -p splat-cli\n\n# schema compat check (既存 30k config が parse できることを確認)\n.\u002Ftarget\u002Frelease\u002Fsplat check --config configs\u002F2026-05-22-2155-lego-sh3-30k.toml\n.\u002Ftarget\u002Frelease\u002Fsplat check --config configs\u002F2026-05-24-1800-lego-legacybase-5k.toml\n.\u002Ftarget\u002Frelease\u002Fsplat check --config configs\u002F2026-05-24-1800-lego-brushcompat-base-5k.toml\n\n# legacy 5k (gt_convention = white_bg, default)\n.\u002Ftarget\u002Frelease\u002Fsplat train --config configs\u002F2026-05-24-1800-lego-legacybase-5k.toml\n# → mid-training mean val: 21.874 dB \u002F wallclock 202.4s \u002F 77603 splats\n\n# brush 互換 5k (gt_convention = premultiplied)\n.\u002Ftarget\u002Frelease\u002Fsplat train --config configs\u002F2026-05-24-1800-lego-brushcompat-base-5k.toml\n# → mid-training mean val: 31.308 dB \u002F wallclock 125.4s \u002F 93948 splats\n# (mid-training PSNR は train.rs:182 の `compute_psnr` (RGB only、raw f32) で計算。\n#  eval cell 4 の 31.334 との 0.026 dB 差は `splat eval --quantize-8bit` の\n#  (*255).round()\u002F255 roundtrip 効果。α channel の MSE への寄与は無い。)\n\n# 4 cell cross-eval\nDS=\u002FUsers\u002Fotkrickey\u002Fdev\u002F3dgs-workspace\u002Fdatasets\u002Fnerf_synthetic\u002Flego\nLEGACY=runs\u002Flego-legacybase-5k\u002Ffinal.ply\nBRUSH=runs\u002Flego-brushcompat-base-5k\u002Ffinal.ply\n\n.\u002Ftarget\u002Frelease\u002Fsplat eval --ply $LEGACY --dataset $DS --split val --convention legacy\n# → 21.874 dB (cell 1)\n.\u002Ftarget\u002Frelease\u002Fsplat eval --ply $LEGACY --dataset $DS --split val --convention brush --quantize-8bit\n# → 1.628 dB (cell 2 — A.3 1.667 dB 再現)\n.\u002Ftarget\u002Frelease\u002Fsplat eval --ply $BRUSH  --dataset $DS --split val --convention legacy\n# → 1.595 dB (cell 3 — symmetry test)\n.\u002Ftarget\u002Frelease\u002Fsplat eval --ply $BRUSH  --dataset $DS --split val --convention brush --quantize-8bit\n# → 31.334 dB (cell 4 — hypothesis confirmed)\n",{"type":54,"text":180},"7. Stage 2 (P1.B.F full) への申し送り",{"type":155,"ordered":164,"items":182},[183,184,185,186,187,188],"\u003Cstrong>30k full bench\u003C\u002Fstrong>: 同 config を iter=30000 で実行、brush 公称 37.40 dB との比較。Stage 1 で 5k → 31.33 dB なので、30k での到達点を見て M3 生命線 (30+ dB) と brush parity (37 dB) のどちらに着地するか決める","\u003Cstrong>brush hyperparameter 移植\u003C\u002Fstrong> (Stage 2 の中核): brush の lr \u002F refine schedule \u002F decay 設定 (特に opacity_reset_every \u002F split_scale_factor \u002F lr_means decay の終端) を移植。Stage 1 では splat-rs 既定 hyperparameter のまま 5k で 31.33 dB が出たので、brush hyperparameter の効果は \"30k 収束時の +5-6 dB\" 程度と予想 (37 dB 到達への critical path)","\u003Cstrong>α channel weight の検討\u003C\u002Fstrong> (任意): 現状は loss.metal が 4ch を等価重みで MSE。brush は \u003Ccode>match_alpha = 0.1\u003C\u002Fcode> で α channel を 1\u002F10 重みに。Stage 2 で 30k bench した後、α 重み調整の sensitivity sweep を 1-2 点だけ追加検討 (Stage 1 で OK 出たので priority は低い)","\u003Cstrong>scale-invariance lesson 適用\u003C\u002Fstrong>: \u003Ccode>h_a_regression_findings\u003C\u002Fcode> の Adam scale-invariance 議論を踏まえ、α channel を含めた loss scale が AdamConfig.eps と整合するか確認。eps=1e-8 で 4ch MSE = 1e-2 帯なら問題ない見込みだが、30k 収束終盤 (loss ≪ 1e-3) で eps が効き始める可能性、watch 対象","\u003Cstrong>render quality 目視確認\u003C\u002Fstrong>: \u003Ccode>runs\u002Flego-brushcompat-base-5k\u002Fview_*.png\u003C\u002Fcode> + \u003Ccode>gt_*.png\u003C\u002Fcode> — premultiplied で gt は背景透明、view は背景 RGB=0 (黒) として render される (PNG 化で α channel は保持されない場合は \"黒背景\" に見える)。これは bug ではなく仕様","\u003Cstrong>30k bench config 起草\u003C\u002Fstrong>: \u003Ccode>configs\u002F2026-05-24-???-lego-brushcompat-30k.toml\u003C\u002Fcode> として iter=30000 に拡張、parent_config を本 Stage 1 brushcompat に",{"type":54,"text":190},"8. 想定外 \u002F 観察事項",{"type":155,"items":192},[193,194,195,196,197],"\u003Cstrong>5k で既に 31 dB\u003C\u002Fstrong> は事前予想 (Stage 1 expected_psnr=12) を 19 dB 上回った。coupling 解消の効果が事前想定より遥かに大きい — brush parity への critical path に位置することを再確認","\u003Cstrong>brush trainer × legacy eval = 1.595 dB\u003C\u002Fstrong> は legacy trainer × brush eval = 1.628 dB と \u003Cstrong>ほぼ完全に対称\u003C\u002Fstrong> (差 0.03 dB)。これは coupling が training と eval の純粋な convention 不一致 (どちらが \"正しい\" でもない、ペアが一致するか否か) であることを実証","\u003Cstrong>brush trainer の wallclock 38% 短縮\u003C\u002Fstrong> は副次効果として歓迎。30k では絶対時間 (202.4 × 6 ≈ 20 min → 125.4 × 6 ≈ 12 min) で 8 分節約、bench loop の cycle time が大幅改善","\u003Cstrong>gt_NN.png が premultiplied で書かれる\u003C\u002Fstrong> 件は advisor 予告通り、bug 報告すべきではない (transparent BG が 8bit PNG に書かれる際に α channel が消えると \"黒背景\" 表示になる、これは PNG quirk)","\u003Cstrong>train.rs:182 の compute_psnr (legacy 形、RGB only \u002F raw f32)\u003C\u002Fstrong> は未変更のまま使われている。premultiplied 経路でも RGB only MSE (`for c in 0..3`) なので α channel は MSE に効かない。mid-training mean val 31.308 と eval cell 4 の 31.334 の 0.026 dB 差は `--quantize-8bit` (pred を 8bit roundtrip) の効果のみで、最終 4-way 表は \u003Ccode>splat eval\u003C\u002Fcode> 経由なので本数字は informational に留まる (advisor 推奨通り)",{"type":54,"text":199},"9. 不明点 \u002F 未確認 (main agent 判断用、本 task では深掘り不要)",{"type":155,"items":201},[202,203,204,205],"\u003Cstrong>brush trainer 30k での絶対値\u003C\u002Fstrong>: Stage 2 で実測必要。Stage 1 trend (5k で 31.33 dB) から線形外挿すれば 30k で 35-37 dB 帯だが、refine が 1500 iter で停止 → splat 数 plateau なので終盤の伸びは限定的、35-36 dB 着地が現実的予想","\u003Cstrong>test split 再 DL\u003C\u002Fstrong>: A.3 で未取得、Stage 2 30k bench と並行で brush 既定の test split 200 view (RGB) を再取得して novel-view PSNR でも比較できると論文に強い","\u003Cstrong>α channel saturate\u003C\u002Fstrong>: brush 5k trainer の min PSNR view (25.09 dB) が legacy の min (5.90 dB) より遥かに高く、view 間の variance も小さい (max-min = 10.8 vs 22.9 dB)。これは brush 流が view 依存性を健全に扱っていることを示唆、Stage 2 で test split 比較で更に強い証拠化可能","\u003Cstrong>Stage 1 brush trainer の SSIM 値\u003C\u002Fstrong>: result.toml には PSNR のみ記録、SSIM は別途算出が必要 (現状 trainer 内で SSIM grad は使うが値は loss_history 内に複合)。Stage 2 で SSIM\u002FLPIPS も含めた fuller comparison が望ましい",{"type":54,"text":207},"10. M2 gate impact (audit doc \u002F plan-gap.vue update 材料)",{"type":155,"items":209},[210,211,212,213],"P1.A audit master doc \u003Ccode>p1-a-eval-convention-audit\u003C\u002Fcode> の §6 表に \u003Cstrong>本 Stage 1 4-way 行を追加\u003C\u002Fstrong>、A.3 falsify hypothesis (\"eval だけ揃えても無理\") の \u003Cstrong>裏返しの解 (\"trainer 側で揃えれば即解\")\u003C\u002Fstrong> を確定","\u003Cstrong>M2 (brush loss 化) gate\u003C\u002Fstrong>: 本 finding で Stage 1 closure。loss kernel 改変ゼロで coupling 解消できたので、当初予定の \"loss kernel α 重み付け追加\" は Stage 2 で sensitivity 試験対象に降格、critical path から除外","\u003Cstrong>M3 生命線 (30 dB)\u003C\u002Fstrong> は brush eval 系で \u003Cstrong>5k で既達\u003C\u002Fstrong> (31.33 dB)、ただし brush trainer の legacy eval は 1.60 dB なので、生命線評価をどの convention で測るか方針確定が必要 (推奨: brush 流に統一、卒論 D.3 章で coupling を主要 finding として展開、自実装 PSNR は brush 流で揃える)","\u003Cstrong>plan-gap.vue\u003C\u002Fstrong>: P1.B.F Stage 1 → done mark、Stage 2 (full hyperparameter 移植 + 30k) を critical path 最上位に",{"type":54,"text":215},"関連",{"type":155,"items":217},[218,219,220,221,222,223,224],"P1.A.3 (本 Stage 1 が解いた問題): \u003Ccode>p1-a-3-cross-eval-reproducer\u003C\u002Fcode>","P1.A.1 brush eval audit (premultiply 数式): \u003Ccode>p1-a-1-brush-eval-audit\u003C\u002Fcode>","P1.A.2 splat-rs eval audit: \u003Ccode>p1-a-2-splat-eval-audit\u003C\u002Fcode>","P1.A audit master: \u003Ccode>p1-a-eval-convention-audit\u003C\u002Fcode>","brush vs splat 37 dB gap analysis: \u003Ccode>brush-vs-splat-37dB-gap-analysis\u003C\u002Fcode>","Adam scale-invariance lesson (Stage 2 で α weight tuning する際の参考): \u003Ccode>h_a_regression_findings\u003C\u002Fcode> + memory \u003Ccode>h_a_regression_findings.md\u003C\u002Fcode>","MCMC noise calibration lesson (hyperparameter scale sensitivity の事例、Stage 2 hyperparameter 移植時に類似 trap 警戒): \u003Ccode>mcmc-noise-calibration\u003C\u002Fcode>",[],[227,248,263,280],{"id":35,"title":228,"date":9,"status":10,"polarity":229,"category":230,"axes":231,"tags":232,"task_code":239,"related_runs":240,"delta_psnr":243,"delta_wallclock":244,"rank":40,"verdict":245,"impact_summary":246,"detail_path":247},"P1.A.1 brush eval audit — 数式定式化 + diff 観点 12 項目","neutral","audit",[14,15],[18,233,87,230,234,235,236,237,24,238],"a-1","psnr","ssim","eval","alpha","convention","P1.A.1",[241,242],"brush-lego-sh3-30k (37.40 dB report)","splat-rs-lego-sh3-30k (24.879 dB)","N\u002FA (apparent gap mechanism の特定が主目的)","N\u002FA (audit task)","audit-complete","brush eval は (1) AlphaMode::Transparent で GT を α premultiply、(2) bg=Vec3::ZERO の黒背景に render、(3) composite_bg=None で premultiplied 同士を直接比較、(4) 8-bit roundtrip 後に MSE = mean((pred−gt)²) over H·W·3、(5) PSNR = 10·log10(1\u002FMSE)。これは NeRF Synthetic (RGBA で α=0 の透明領域が支配的) において **透明領域は pred=gt=0 で完全一致** となり、MSE 分母に 0 寄与が大量に入る → conventional 「白背景に composite してから PSNR」より高く出る。splat-rs 側の eval 規約を A.2 で確認し、A.3 で「同 convention 下での真の gap」を測定する必要あり。","\u002Ffindings\u002Fp1-a-1-brush-eval-audit\u002F",{"id":36,"title":249,"date":9,"status":10,"polarity":229,"category":230,"axes":250,"tags":251,"task_code":256,"related_runs":257,"delta_psnr":259,"delta_wallclock":260,"rank":40,"verdict":229,"impact_summary":261,"detail_path":262},"P1.A.2 splat-rs eval audit — val split 100view・α 除外・rendered 黒背景の RGB-only PSNR",[14,16],[252,22,236,253,254,230,255],"phase-1","psnr-formula","convention-diff","self-trainer","P1.A.2",[258],"lego-sh3-30k","N\u002FA (本タスクでは PSNR を変えない、audit 結果のみ提示)","N\u002FA (audit のみ)","splat-rs trainer の eval は (1) val split 100 view・brush は test split 200 view、(2) PSNR は RGB のみ・α 除外、(3) rendered は raw f32 (clamp \u002F quantize なし)・brush 標準は u8 quant 後、(4) rendered は bg 合成なしで Σαi·Ti·ci のみ・target は white-bg pre-composite — の 4 つの diff 軸を持つ。training loss は 4ch (α 含む) で動くため、α 通り collapse が暗黙の white-bg 効果を作るが、convergence は不完全。P1.A.3 で 7 項目の切り分け reproducer を作り apparent gap (推定 −3〜−6 dB) を分離する。","\u002Ffindings\u002Fp1-a-2-splat-eval-audit\u002F",{"id":34,"title":264,"date":9,"status":10,"polarity":265,"category":11,"axes":266,"tags":267,"task_code":272,"related_runs":273,"delta_psnr":275,"delta_wallclock":276,"rank":40,"verdict":277,"impact_summary":278,"detail_path":279},"P1.A.3 cross-eval reproducer — brush convention で 24.879 → 1.67 dB に崩壊、主仮説 falsify","negative",[14,15,16],[18,268,269,22,236,238,234,24,270,271],"phase-a","milestone-m1","reproducer","falsified-hypothesis","P1.A.3 + P1.A.4",[274],"lego-sh3-30k (splat-rs 24.879 dB legacy\u002Fval)","-23.21 dB (brush convention 化で 24.879 → 1.667)","N\u002FA (eval only)","hypothesis-falsified-stronger-finding","splat-rs `final.ply` (24.879 dB legacy\u002Fval baseline) を brush 準拠 convention (premultiplied GT + bg=ZERO 比較 + 8-bit roundtrip) で再評価すると **1.67 dB に崩壊**。audit §6 が予測した +3〜+5 dB 底上げと逆方向に -23 dB。原因は trainer が white-bg target で学習されており、背景領域を opaque-white splat で埋めるよう収束した結果、brush 流の bg=ZERO 比較では背景 pixel 全体で MSE≈1 が systematic に乗る。`view_00.png` 目視確認 (背景は白い不透明領域) で機構を確定。**training と eval の convention は coupling しており、eval pipeline だけ揃える apparent-gap 仮説は不成立**。卒研 P1.M2\u002FM3 に向けては「training loss も brush 化 (RGBA 4ch L1 を α=0 領域で背景に penalty を吹かさない構造)」が必須要件。8-bit quantize 単体の impact はほぼ無視可能 (legacy 24.879 → 24.879、brush 1.605 → 1.667、+0.06 dB)。","\u002Ffindings\u002Fp1-a-3-cross-eval-reproducer\u002F",{"id":37,"title":281,"date":9,"status":10,"polarity":229,"category":230,"axes":282,"tags":283,"task_code":286,"related_runs":287,"delta_psnr":289,"delta_wallclock":244,"rank":40,"verdict":290,"impact_summary":291,"detail_path":292},"P1.A eval convention audit (統合) — 7 軸の diff 確定、apparent gap 推定 -3〜-6 dB",[14,15,16],[18,268,269,22,236,238,234,24,237,284,230,285],"split","synthesis","P1.A (M1)",[288,241],"lego-sh3-30k (splat-rs 24.879 dB)","推定 -3〜-6 dB (apparent gap 縮小、A.3 で実測予定)","audit-complete-gate-passed","両 trainer の eval pipeline を file:line で完全 audit、PSNR formula 本体 (MAX=1 \u002F log10 \u002F RGB only \u002F per-view mean) は同等だが、(1) test split (200 view) vs val split (100 view)、(2) background composite convention の **完全逆方向**、(3) 8-bit roundtrip 有無、(4) α-mask 経路、(5) clamp\u002Fquantize 等 7 軸で diff を確認。最大の発見は brush の premultiplied-α + bg=ZERO eval が NeRF Synthetic の透明領域で構造的に PSNR を +3 dB 以上嵩上げする一方、splat-rs は target に white pre-composite \u002F rendered に bg 合成なしの mismatch で convergence 残差が MSE に直接残る。apparent gap の推定 -3〜-6 dB を A.3 reproducer で実証予定、残り -6〜-9 dB が真の algorithmic gap。","\u002Ffindings\u002Fp1-a-eval-convention-audit\u002F",1782449788647]