wai-rs: validate jpegai_icci against the reference decoder (ground truth, 2.4e-07) #26
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/jpegai-icci-validation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Drives the merged
IcciPathwith ground truth captured from the ISO reference decoder running on real test256.bin — its ownprocess_dwt444_2outputs (48-ch network input + plane subbands), the selected models weights, and itsprocess_compoutput.Result: max|Δ| = 2.4e-07 (float epsilon). First validation of eICCI against real chain data rather than my reading of the source. Confirms the full plane path:
conv_first + BN-fold + ReLU → ResBlocks(rect [1,3]/[3,1], folded BN, scaled residual) → conv_last → out·scale + subbands → IDWT2.Two traps this pinned down, both of which had produced false confirmations earlier:
forward— which is exactly whatpost_filters/model_*.onnxexports. It callsprocess_dwt444_2once, thenprocess_compper plane. Weights must come from the referencestate_dict(unfolded, complete); the ONNX initializers are pre-folded and lackBNY,scaleU/scaleV, and the per-blockscale.model_selectionis 1-based (0 = plane not filtered), so[6,3,3]→active[5]/active[2]— confirmed by hooking the reference.Also verified against the same ground truth: joint-UV path (shared trunk →
conv_last_u/conv_last_vwith distinct scales) at U 1.62e-07 / V 1.65e-07, and the two-level Haar DWT reproducing Y16/U16/V16 and the 48-ch concat exactly (0.0).Adds a calibration test driving the merged IcciPath with ground truth captured from the ISO reference decoder running on the real test256.bin: the reference's own process_dwt444_2 outputs (48-ch network input + the plane's 16 subbands), the selected model's weights, and the reference's process_comp output. Result: max|Δ| = 2.4e-07 (float epsilon). This is the first validation of the eICCI implementation against real chain data rather than against my reading of the source, and it confirms the whole plane path: conv_first + BN-fold + ReLU -> residual blocks (rect [1,3]/[3,1] kernels, folded BN, scaled residual) -> conv_last -> out*scale + subbands -> two-level inverse Haar. Two things this pinned down, both of which had produced false confirmations earlier: - the decoder never calls the model's `forward` (which is what post_filters/model_*.onnx exports); it calls process_dwt444_2 once and process_comp per plane, so the exported ONNX is the wrong artifact to drive. Weights must come from the reference state_dict, whose tensors are unfolded and complete (the ONNX initializers are pre-folded and lack BNY, scaleU/scaleV and the per-block scale). - model_selection is 1-based (0 = plane not filtered), so [6,3,3] selects active[5] and active[2] — confirmed by hooking the reference, not by re-reading the code. Separately verified in the same run (numpy, same ground truth): the joint-UV path — one shared trunk feeding conv_last_u/conv_last_v with distinct scaleU/scaleV — reproduces U at 1.62e-07 and V at 1.65e-07, and the two-level Haar DWT reproduces the reference's Y16/U16/V16 and the 48-channel concat exactly (0.0). Co-Authored-By: Claude Opus 4.8 <[email protected]>