summaryrefslogtreecommitdiff
path: root/training/test_viz_precision.py
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-13 23:40:30 +0100
committerskal <pascal.massimino@gmail.com>2026-02-13 23:40:30 +0100
commit25044d63057cdb134cc3930bb67b178cff1aebb4 (patch)
treebf00411b0af159ef090dc9cffbd8c6dd793f1cff /training/test_viz_precision.py
parent87a27bf022d7fba68e3a945ee29c854c6e1ae2d7 (diff)
CNN v2: Fix Layer 0 visualization scale (was 0.5, now 1.0)
Layer 0 output is clamped [0,1], does not need 0.5 dimming. Middle layers (ReLU) keep 0.5 scale for values >1. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'training/test_viz_precision.py')
-rwxr-xr-xtraining/test_viz_precision.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/training/test_viz_precision.py b/training/test_viz_precision.py
new file mode 100755
index 0000000..143f4ea
--- /dev/null
+++ b/training/test_viz_precision.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+"""Test WebGPU → Canvas → PNG precision loss
+
+Check if bgra8unorm → 2D canvas → PNG loses 2 LSBs.
+"""
+
+import numpy as np
+
+# Simulate WebGPU bgra8unorm conversion
+# Float [0, 1] → uint8 [0, 255]
+
+test_values = [
+ 1.0, # Perfect white
+ 0.9999, # Near-white
+ 254.5/255, # Exactly 254.5
+ 253.5/255, # Exactly 253.5
+]
+
+for val in test_values:
+ # WebGPU bgra8unorm: round(val * 255)
+ gpu_u8 = int(np.round(val * 255))
+
+ # Convert back to normalized
+ gpu_f32 = gpu_u8 / 255.0
+
+ # JavaScript canvas getImageData: uint8
+ canvas_u8 = int(np.round(gpu_f32 * 255))
+
+ print(f"Input: {val:.6f} → GPU u8: {gpu_u8} → Canvas: {canvas_u8}")
+ if canvas_u8 != 255:
+ print(f" ⚠️ Lost {255 - canvas_u8} LSBs")
+
+print("\nConclusion:")
+print("If WebGPU stores 1.0 as 255, canvas should read 255.")
+print("If user sees 253, likely:")
+print(" a) Not viewing CNN layer (viewing static features at scale=1.0)")
+print(" b) Value in texture is already 253/255 = 0.9921875")
+print(" c) F16 storage or unpacking issue")