code wiki / _hdl_build / nx_nn_train_gate.nx
nx_nn_train_gate.nx source
↩ module page · 44 lines · 2666 B
1// nx_nn_train_gate.nx -- proves sovereign fixed-point training (nx_nn_train): batch gradient descent on a linear layer,
2// starting from zero weights, learns a known target mapping -- the MSE loss collapses and the learned weights converge
3// to the target. This is the training pipeline the neural PLC / RVQ-codebook needs, all integer, no FPU/GPU/autograd.
4import "nx_syscalls.nx"
5import "nx_gate_emit_lib.nx"
6import "nx_nn_train.nx"
7
8func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
9
10func main() -> i64 {
11 g_puts("nx_nn_train gate (sovereign fixed-point gradient descent learns a target, MEASURED)\n" as *u8)
12 var pass: i64 = 0; var total: i64 = 0
13 let I: i64 = 2; let O: i64 = 1; let T: i64 = 4; let Q: i64 = 16 // weights in Q16 so sub-unit GD steps accumulate
14
15 // target mapping W* = [1.0, -0.5] in Q16
16 let Wt: *i64 = sys_mmap(2*8) as *i64; Wt[0]=65536; Wt[1]=0-32768
17 // training inputs X[T x I] (Q8) and targets Y = (W* . X) >> Q
18 let X: *i64 = sys_mmap(T*I*8) as *i64
19 let Y: *i64 = sys_mmap(T*O*8) as *i64
20 X[0]=256; X[1]=256; X[2]=512; X[3]=128; X[4]=128; X[5]=512; X[6]=384; X[7]=256
21 var t: i64 = 0
22 while t < T { let acc: i64 = Wt[0]*X[t*I] + Wt[1]*X[t*I+1]; Y[t] = acc >> Q; t = t + 1 }
23
24 // learn from ZERO weights
25 let W: *i64 = sys_mmap(2*8) as *i64; W[0]=0; W[1]=0
26 let grad: *i64 = sys_mmap(O*I*8) as *i64
27 let pred: *i64 = sys_mmap(O*8) as *i64
28
29 let loss0: i64 = nnt_loss(X, Y, T, W, I, O, Q)
30 var it: i64 = 0
31 while it < 15000 { nnt_step(X, Y, T, W, I, O, Q, 13, grad, pred); it = it + 1 } // update_shift 13 = the learning rate
32 let lossN: i64 = nnt_loss(X, Y, T, W, I, O, Q)
33
34 g_puts(" [measure] loss: start=" as *u8); g_pn(loss0); g_puts(" after 15000 GD steps=" as *u8); g_pn(lossN)
35 g_puts(" learned W=[" as *u8); g_pn(W[0]); g_puts("," as *u8); g_pn(W[1]); g_puts("] vs target [65536,-32768] (Q16; exact convergence is fixed-point-floor-limited)\n" as *u8)
36
37 pass = pass + g_check("training collapses the loss (>= 95% reduction = it learned the mapping)" as *u8, lossN * 20 <= loss0); total=total+1
38 pass = pass + g_check("weights converge substantially toward target with correct sign (>= 60% of the way)" as *u8, (W[0] >= 39322) & (W[1] <= 0-19661)); total=total+1
39 pass = pass + g_check("started genuinely untrained (start loss > 0)" as *u8, loss0 > 0); total=total+1
40
41 g_puts("---- nn_train gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
42 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
43 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
44}