code wiki / (root) / nx_pose_elm.nx

nx_pose_elm.nx source

↩ module page · 69 lines · 3194 B

1// nx_pose_elm.nx -- the NONLINEAR learner for pose-from-silhouette (roadmap R2 v1). The linear perceptron on raw 2// occupancy provably can't separate the hand regions (tried 9-region, delta, 3-band = all at chance). An EXTREME 3// LEARNING MACHINE fixes that WITHOUT fragile fixed-point backprop: a FIXED RANDOM projection h = relu(R*x + b) 4// lifts the occupancy into a high-dim nonlinear feature space where the classes ARE linearly separable, and only 5// the LINEAR OUTPUT is trained -- by the PROVEN perceptron rule (same one text2motion used). Random-features / 6// ELM is a real ML method (Rahimi-Recht random kitchen sinks; Huang ELM). Seeded LCG => deterministic. The 7// honest ceiling stays: coarse, our-render-silhouette domain; SOTA pose = a trained CNN. license_tier: ORIGINAL 8import "nx_syscalls.nx" 9const ELM_MAGIC_1103515245: i64 = 1103515245 10const ELM_MAGIC_12345: i64 = 12345 11 12const ELM_HSCALE: i64 = 256 // divides R*x before the bias, keeps h bounded 13 14func elm_lcg(st: *i64) -> i64 { st[0] = (st[0] * ELM_MAGIC_1103515245 + ELM_MAGIC_12345) & 0x7fffffff; return st[0] } 15// fill the FIXED random projection R[NH*NF] in [-4,4] and bias b[NH] in [-100,100] from a seed (deterministic). 16func elm_init(R: *i64, b: *i64, nh: i64, nf: i64, seed: i64) -> i64 { 17 let st: *i64 = sys_mmap(8) as *i64; st[0] = seed 18 var i: i64 = 0 19 while i < nh * nf { R[i] = (elm_lcg(st) % 9) - 4; i = i + 1 } 20 var j: i64 = 0 21 while j < nh { b[j] = (elm_lcg(st) % 201) - 100; j = j + 1 } 22 return 0 23} 24// project x[nf] -> h[nh] = relu( (R*x)/HSCALE + b ). 25func elm_project(R: *i64, b: *i64, x: *i64, nf: i64, nh: i64, h: *i64) -> i64 { 26 var j: i64 = 0 27 while j < nh { 28 var s: i64 = 0 29 var c: i64 = 0 30 while c < nf { s = s + R[j*nf+c] * x[c]; c = c + 1 } 31 s = s / ELM_HSCALE + b[j] 32 if s < 0 { s = 0 } 33 h[j] = s 34 j = j + 1 35 } 36 return 0 37} 38func elm_score(W: *i64, r: i64, h: *i64, nh: i64) -> i64 { var s: i64=0; var j: i64=0; while j<nh { s=s+W[r*nh+j]*h[j]; j=j+1 } return s } 39func elm_predict(W: *i64, h: *i64, nh: i64, nc: i64) -> i64 { 40 var best: i64 = 0; var bs: i64 = elm_score(W, 0, h, nh); var r: i64 = 1 41 while r < nc { let s: i64 = elm_score(W, r, h, nh); if s > bs { bs = s; best = r } r = r + 1 } 42 return best 43} 44// train the LINEAR OUTPUT W[nc*nh] on the projected features by the perceptron rule. hs = ns*nh. Returns last 45// epoch mistakes. 46func elm_train(W: *i64, hs: *i64, labels: *i64, ns: i64, nh: i64, nc: i64, epochs: i64) -> i64 { 47 var i: i64 = 0 48 while i < nc * nh { W[i] = 0; i = i + 1 } 49 var last: i64 = 0 50 var e: i64 = 0 51 while e < epochs { 52 var mist: i64 = 0 53 var n: i64 = 0 54 while n < ns { 55 let h: *i64 = (hs as i64 + n*nh*8) as *i64 56 let pred: i64 = elm_predict(W, h, nh, nc) 57 let lab: i64 = labels[n] 58 if pred != lab { 59 mist = mist + 1 60 var j: i64 = 0 61 while j < nh { W[lab*nh+j] = W[lab*nh+j] + h[j]; W[pred*nh+j] = W[pred*nh+j] - h[j]; j = j + 1 } 62 } 63 n = n + 1 64 } 65 last = mist 66 e = e + 1 67 } 68 return last 69}