nx_pose_cnn.nx source
↩ module page · 52 lines · 3388 B
1// nx_pose_cnn.nx -- T2 POSE FRONT-HALF: the sovereign software-f32 pose-CNN FORWARD PASS -- the heatmap PRODUCER
2// that was the one remaining gap sitting UNDER nx_pose_keypoints. It composes the gated f32 vision substrate
3// (nx_f32_conv2d_forward, itself only nx_f32_mul/nx_f32_add) into the real heatmap-pose-net SHAPE:
4// a 3x3 stride-1 pad-1 spatial-conv BACKBONE stage (the ResBlock-class feature extractor)
5// + a 1x1 conv HEAD that projects the feature channels into J per-joint confidence heatmaps,
6// each followed by a ReLU that makes every heatmap value NON-NEGATIVE.
7//
8// KEY INVARIANT (load-bearing, why this closes the loop with NO glue): IEEE-754 non-negative floats are
9// ORDER-ISOMORPHIC to their i64 bit-patterns -- for x,y >= +0.0, (x > y) as floats iff (bits(x) > bits(y)) as
10// integers. So a ReLU'd heatmap can be consumed DIRECTLY by the integer, weights-free back-half nx_pose_keypoints
11// (argmax + quarter-pixel subpixel + occlusion threshold) with NO f32->int conversion. The ReLU is REQUIRED: a
12// negative activation carries the sign bit, whose pattern sorts ABOVE any positive peak, so the integer argmax
13// would pick the wrong cell -- ReLU zeroing negatives to +0.0 is exactly what restores the isomorphism.
14//
15// This closes the pipeline image -> f32 conv backbone -> f32 1x1 head -> heatmaps -> integer keypoint back-half,
16// end-to-end and sovereignly, on hand-set weights. Only TRAINED WEIGHTS + a deeper backbone remain (the T3 arc);
17// the architecture + the arithmetic are proven here. NO libm, NO Q-scaling -- only nx_f32_conv2d/mul/add/gt.
18// license_tier: ORIGINAL
19import "nx_syscalls.nx"
20import "nx_f32.nx"
21import "nx_f32_conv2d.nx"
22
23// ReLU in place over n f32 values: negative / -0.0 / NaN -> +0.0 (bits 0). This is what makes the heatmap block
24// bit-order-isomorphic to the integers, so the downstream integer argmax in nx_pose_keypoints is correct. Without
25// it a negative activation's bit-pattern (sign bit set) sorts ABOVE a positive peak and argmax picks the wrong cell.
26func pose_cnn_relu(buf: *i64, n: i64) -> i64 {
27 var i: i64 = 0
28 while i < n {
29 if nx_f32_gt(buf[i], 0) == 0 { buf[i] = 0 } // v > +0.0 ? keep : clamp to +0.0
30 i = i + 1
31 }
32 return 0
33}
34
35// 3x3 stride-1 pad-1 spatial-conv BACKBONE stage (ResBlock-class feature extractor), C_in -> C_out, then ReLU.
36// inp is [1,C_in,H,W]; weight is f32 [C_out,C_in,3,3]; bias is f32 [C_out] or 0; out is [C_out,H,W] (H,W preserved).
37func pose_cnn_backbone3x3(inp: *i64, C_in: i64, H: i64, W: i64, weight: *i64, C_out: i64, bias: *i64, out: *i64) -> i64 {
38 let rc: i64 = nx_f32_conv2d_forward(inp, 1, C_in, H, W, weight, C_out, 3, 3, 1, 1, bias, out)
39 if rc != 0 { return rc }
40 pose_cnn_relu(out, C_out * H * W)
41 return 0
42}
43
44// 1x1 conv HEAD: project C_in feature channels -> J joint heatmaps (the actual last layer of a heatmap pose net),
45// then ReLU so the J*H*W block is non-negative and consumable by nx_pose_keypoints/pose_extract with no conversion.
46// feat is [1,C_in,H,W]; weight is f32 [J,C_in,1,1]; bias is f32 [J] or 0; out is [J,H,W].
47func pose_cnn_head1x1(feat: *i64, C_in: i64, H: i64, W: i64, weight: *i64, J: i64, bias: *i64, out: *i64) -> i64 {
48 let rc: i64 = nx_f32_conv2d_forward(feat, 1, C_in, H, W, weight, J, 1, 1, 1, 0, bias, out)
49 if rc != 0 { return rc }
50 pose_cnn_relu(out, J * H * W)
51 return 0
52}