code wiki / _hdl_build / nx_poseelm_gate.nx

nx_poseelm_gate.nx source

↩ module page · 158 lines · 7579 B

1// nx_poseelm_gate.nx -- R2 v1: does a NONLINEAR learner (ELM = fixed random ReLU projection + trained linear 2// output) crack pose-from-silhouette where the linear perceptron failed? Render arm poses -> occupancy -> 3// project -> perceptron on the projected features -> HELD-OUT generalization (9 hand regions). vs untrained at 4// chance. If trained >> untrained on held-out, R2 v1 works (coarse, our-render domain). expect_exit:0 ORIGINAL 5import "nx_syscalls.nx" 6import "nx_figure_render.nx" 7import "nx_pose_elm.nx" 8 9func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 10func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 } 11func pdg(d: i64) -> i64 { return d * 12868 / 180 } 12func clamp3(v: i64) -> i64 { if v < 0 { return 0 } if v > 2 { return 2 } return v } 13 14const PW: i64 = 64 15const PH: i64 = 48 16const GW: i64 = 8 17const GH: i64 = 6 18const GC: i64 = 16 // contour columns 19const NCELL: i64 = 32 // per column: top-height + thickness (the arm shows in the UPPER CONTOUR) 20const NH: i64 = 64 // random hidden features 21const NR: i64 = 3 // hand HEIGHT bins (low/mid/high) -- well-posed + balanced; the contour top-height encodes it 22const NTR: i64 = 30 23const NHO: i64 = 9 24const NALL: i64 = 39 25 26// UPPER-CONTOUR feature: per column band, the top-point HEIGHT (PH - topmost foreground row) + the column 27// thickness, scaled ~0..256. A raised arm shows as a tall top-height in its columns -- the arm signal the 28// full-body occupancy drowned. 29func pe_contour(zb: *i64, feat: *i64) -> i64 { 30 var cx: i64 = 0 31 while cx < GC { 32 let x0: i64 = cx*PW/GC; let x1: i64 = (cx+1)*PW/GC 33 var top: i64 = PH; var bot: i64 = 0 - 1 34 var x: i64 = x0 35 while x < x1 { 36 var y: i64 = 0 37 while y < PH { if zb[y*PW+x] > (0-1900000000) { if y < top { top = y } if bot < y { bot = y } } y = y + 1 } 38 x = x + 1 39 } 40 var th: i64 = 0; var bh: i64 = 0 41 if bot >= 0 { th = (PH - top) * 5; bh = (bot - top) * 5 } 42 feat[cx*2] = th; feat[cx*2+1] = bh 43 cx = cx + 1 44 } 45 return 0 46} 47func pe_sample(sk: i64, fb: *i64, zb: *i64, pitch: i64, elbow: i64, occ: *i64, wxy: *i64) -> i64 { 48 sk_pose(sk, RG_SHR, 0, pdg(pitch)); sk_pose(sk, RG_ELR, pdg(elbow), 0) 49 sk_update(sk) 50 rig_draw(sk, fb, zb, PW, PH, pdg(15), 70) 51 pe_contour(zb, occ) 52 let bw: *i64 = sk_bone(sk, RG_WRR); wxy[0]=bw[15]; wxy[1]=bw[16] 53 return 0 54} 55 56func main() -> i64 { 57 hw("=== nx_poseelm_gate -- R2 v1: nonlinear (ELM) pose-from-silhouette ===\n" as *u8) 58 let sk: i64 = sys_mmap(sk_bytes()) as i64 59 let fb: *i64 = sys_mmap(PW * PH * 8) as *i64 60 let zb: *i64 = sys_mmap(PW * PH * 8) as *i64 61 let occs: *i64 = sys_mmap(NALL * NCELL * 8) as *i64 62 let wx: *i64 = sys_mmap(NALL * 8) as *i64 63 let wy: *i64 = sys_mmap(NALL * 8) as *i64 64 let trp: *i64 = sys_mmap(6 * 8) as *i64 65 trp[0]=0-70; trp[1]=0-40; trp[2]=0-10; trp[3]=20; trp[4]=50; trp[5]=80 66 let tre: *i64 = sys_mmap(5 * 8) as *i64 67 tre[0]=0; tre[1]=25; tre[2]=50; tre[3]=75; tre[4]=100 68 let hop: *i64 = sys_mmap(3 * 8) as *i64 69 hop[0]=0-55; hop[1]=5; hop[2]=65 70 let hoe: *i64 = sys_mmap(3 * 8) as *i64 71 hoe[0]=12; hoe[1]=37; hoe[2]=62 72 rig_build(sk) 73 let wxy: *i64 = sys_mmap(2 * 8) as *i64 74 var idx: i64 = 0 75 var pi: i64 = 0 76 while pi < 6 { 77 var ei: i64 = 0 78 while ei < 5 { 79 let occp: *i64 = (occs as i64 + idx * NCELL * 8) as *i64 80 pe_sample(sk, fb, zb, trp[pi], tre[ei], occp, wxy) 81 wx[idx]=wxy[0]; wy[idx]=wxy[1]; idx=idx+1 82 ei = ei + 1 83 } 84 pi = pi + 1 85 } 86 pi = 0 87 while pi < 3 { 88 var ei: i64 = 0 89 while ei < 3 { 90 let occp: *i64 = (occs as i64 + idx * NCELL * 8) as *i64 91 pe_sample(sk, fb, zb, hop[pi], hoe[ei], occp, wxy) 92 wx[idx]=wxy[0]; wy[idx]=wxy[1]; idx=idx+1 93 ei = ei + 1 94 } 95 pi = pi + 1 96 } 97 // region labels (3x3 over wrist x,y) 98 var xmin: i64=wx[0]; var xmax: i64=wx[0]; var ymin: i64=wy[0]; var ymax: i64=wy[0] 99 var i: i64 = 1 100 while i < NALL { 101 if wx[i]<xmin{xmin=wx[i]} if wx[i]>xmax{xmax=wx[i]} if wy[i]<ymin{ymin=wy[i]} if wy[i]>ymax{ymax=wy[i]} 102 i = i + 1 103 } 104 let labels: *i64 = sys_mmap(NALL * 8) as *i64 105 i = 0 106 while i < NALL { 107 labels[i] = clamp3(3*(wy[i]-ymin)/(ymax-ymin+1)) // hand-height bin (low/mid/high) 108 i = i + 1 109 } 110 // DIAGNOSTIC: label distribution (degenerate labels would cap any model at the majority baseline) 111 let hist: *i64 = sys_mmap(NR * 8) as *i64 112 var hi: i64 = 0; while hi < NR { hist[hi]=0; hi=hi+1 } 113 i = 0; while i < NALL { hist[labels[i]] = hist[labels[i]] + 1; i = i + 1 } 114 hw(" label histogram (9 regions):"); hi = 0; while hi < NR { hw(" "); pn(hist[hi]); hi = hi + 1 } hw("\n" as *u8) 115 var ho_hist: *i64 = sys_mmap(NR * 8) as *i64 116 hi = 0; while hi < NR { ho_hist[hi]=0; hi=hi+1 } 117 i = NTR; while i < NALL { ho_hist[labels[i]] = ho_hist[labels[i]] + 1; i = i + 1 } 118 hw(" held-out histogram:"); hi = 0; while hi < NR { hw(" "); pn(ho_hist[hi]); hi = hi + 1 } hw("\n" as *u8) 119 120 // ELM project every sample 121 let R: *i64 = sys_mmap(NH * NCELL * 8) as *i64 122 let bb: *i64 = sys_mmap(NH * 8) as *i64 123 elm_init(R, bb, NH, NCELL, 20260706) 124 let hs: *i64 = sys_mmap(NALL * NH * 8) as *i64 125 i = 0 126 while i < NALL { 127 let occp: *i64 = (occs as i64 + i*NCELL*8) as *i64 128 let hp: *i64 = (hs as i64 + i*NH*8) as *i64 129 elm_project(R, bb, occp, NCELL, NH, hp) 130 i = i + 1 131 } 132 // train the linear output on the projected features 133 let W: *i64 = sys_mmap(NR * NH * 8) as *i64 134 let mist: i64 = elm_train(W, hs, labels, NTR, NH, NR, 80) 135 hw(" ELM (NH="); pn(NH); hw(" random features) trained on "); pn(NTR); hw(" poses, mistakes="); pn(mist); hw("\n" as *u8) 136 // held-out: trained vs untrained 137 let W0: *i64 = sys_mmap(NR * NH * 8) as *i64 138 var z: i64 = 0; while z < NR*NH { W0[z]=0; z=z+1 } 139 var corr: i64 = 0; var corr0: i64 = 0 140 i = NTR 141 while i < NALL { 142 let hp: *i64 = (hs as i64 + i*NH*8) as *i64 143 if elm_predict(W, hp, NH, NR) == labels[i] { corr = corr + 1 } 144 if elm_predict(W0, hp, NH, NR) == labels[i] { corr0 = corr0 + 1 } 145 i = i + 1 146 } 147 hw(" HELD-OUT (9 regions): TRAINED "); pn(corr); hw("/"); pn(NHO); hw(" vs UNTRAINED "); pn(corr0); hw("/"); pn(NHO); hw("\n" as *u8) 148 149 var fails: i64 = 0 150 if corr > corr0 { 151 if corr * 100 >= NHO * 55 { hw("R2-ELM PASS -- nonlinear learner GENERALIZES (trained "); pn(corr); hw("/"); pn(NHO); hw(" >> untrained "); pn(corr0); hw("; random features cracked what linear couldn't)\n" as *u8) } 152 else { fails = fails + 1; hw("R2-ELM WEAK -- trained "); pn(corr); hw("/"); pn(NHO); hw(" (beats untrained "); pn(corr0); hw(" but < 55%; honest: coarse)\n" as *u8) } 153 } else { fails = fails + 1; hw("R2-ELM FAIL -- not > untrained ("); pn(corr); hw(" vs "); pn(corr0); hw(")\n" as *u8) } 154 155 if fails == 0 { hw("POSEELM-GATE GREEN -- R2 v1 nonlinear pose-from-silhouette generalizes (ELM; coarse, our-render domain)\n" as *u8); sys_exit(0); return 0 } 156 hw("POSEELM-GATE RED (R2 still hard -- honest; see numbers above)\n" as *u8) 157 sys_exit(1); return 1 158}