code wiki / _hdl_build / nx_skintex_train_gate.nx

nx_skintex_train_gate.nx source

↩ module page · 339 lines · 14461 B

1// nx_skintex_train_gate.nx -- ★★P4 NEURAL RUNG 1: a TRAINED sovereign neural SKIN-TEXTURE model. A coordinate 2// MLP (Fourier features -> 40 ReLU -> rgb; the SIREN/FFN/Instant-NGP family, per the banked ntex_* frontier) 3// is trained by HAND-ROLLED INTEGER (Q12) backprop on a REAL 48x48 skin patch cropped from the Elara exemplar, 4// persisted as quantized integer weights, and re-rendered by integer-only inference -- the ENTIRE P4 pipeline 5// (data -> train -> persist -> integer inference -> render) proven end-to-end at a scale we win today. 6// Honest boundary: this is EXEMPLAR-FIT (a compressed, resolution-free representation of one patch), not yet a 7// GENERATIVE skin model -- that is R2 (latent-conditioned family / NCA stationary synthesis). 8// T1 training CONVERGES: final reconstruction error < 1/4 of the untrained error 9// T2 close reconstruction: final mean |err| per channel < 26/255 10// T3 PERSISTENCE: integer weights file -> reload -> re-render is BIT-IDENTICAL (the deploy path) 11// T4 RESOLUTION-FREE: renders at 4x coordinate density (192x192, smooth continuous zoom -- the coordinate-net 12// win over a stored bitmap) + PNG knowledge/nx_skintex.png (exemplar | reconstruction | 4x zoom) 13// license_tier: ORIGINAL expect_exit: 0 14import "nx_syscalls.nx" 15import "nx_itrig.nx" 16import "nx_jpeg_ascii.nx" 17import "nx_png.nx" 18 19func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 20func 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 } 21 22const PS: i64 = 48 // exemplar patch size 23const CX: i64 = 148 // crop origin in elara_face_hi.jpg: the LEFT EYE region -- real structure 24const CY: i64 = 244 // (iris/lashes/lid/skin) so the net learns actual image content, not noise 25const NFR: i64 = 6 // frequencies {1,2,4,8,16,24}: the eye has REAL high-freq structure (iris, 26const NF: i64 = 24 // lashes), so the high bands fit real edges (on a FLAT patch they lay plaid) 27const NH: i64 = 64 // hidden units 28const NO: i64 = 3 // rgb 29const NPX: i64 = 2304 // PS*PS 30const EPOCHS: i64 = 1000 31 32func lcg(st: *i64) -> i64 { var h: i64=st[0]; h=h*6364136223846793005+1442695040888963407; st[0]=h; return (h>>33)&2147483647 } 33 34// features for a coordinate at `scale` px per exemplar-texel (scale=1 train, 4 = 4x zoom render) 35func features(px: i64, py: i64, scale: i64, f: *i64) -> i64 { 36 let fr: *i64 = sys_mmap(8*8) as *i64 37 fr[0]=1; fr[1]=2; fr[2]=4; fr[3]=8; fr[4]=16; fr[5]=24 38 var k: i64 = 0 39 while k < NFR { 40 let ax: i64 = px * 25736 * fr[k] / (PS * scale) 41 let ay: i64 = py * 25736 * fr[k] / (PS * scale) 42 f[k*4] = it_sin4096(ax) 43 f[k*4+1] = it_cos4096(ax) 44 f[k*4+2] = it_sin4096(ay) 45 f[k*4+3] = it_cos4096(ay) 46 k = k + 1 47 } 48 return 0 49} 50 51// integer-only inference: Q12 weights, Q12 features -> rgb 0..255 packed 52func infer(W1: *i64, b1: *i64, W2: *i64, b2: *i64, f: *i64, h: *i64) -> i64 { 53 var j: i64 = 0 54 while j < NH { 55 var acc: i64 = b1[j] 56 var i: i64 = 0 57 while i < NF { acc = acc + W1[j*NF+i]*f[i]/4096; i = i + 1 } 58 if acc < 0 { acc = 0 } 59 if acc > 16384 { acc = 16384 } 60 h[j] = acc 61 j = j + 1 62 } 63 var outp: i64 = 0 64 var c: i64 = 0 65 while c < NO { 66 var acc: i64 = b2[c] 67 j = 0 68 while j < NH { acc = acc + W2[c*NH+j]*h[j]/4096; j = j + 1 } 69 var v: i64 = acc*255/4096 70 if v < 0 { v = 0 } 71 if v > 255 { v = 255 } 72 var sh: i64 = 0 73 if c == 1 { sh = 8 } 74 if c == 2 { sh = 16 } 75 outp = outp + (v << sh) 76 c = c + 1 77 } 78 return outp 79} 80 81func main() -> i64 { 82 hw("=== nx_skintex_train_gate -- P4 R1: a trained sovereign neural skin-texture model (integer end-to-end) ===\n" as *u8) 83 var fails: i64 = 0 84 85 // ---- data: crop a real skin patch from the Elara exemplar ---- 86 let szp: *i64 = sys_mmap(16) as *i64 87 let jpeg: *u8 = sys_read_file("knowledge/elara_face_hi.jpg" as *u8, szp) 88 if (jpeg as i64) == 0 { hw("no exemplar\n" as *u8); return 1 } 89 let rp: *i64 = sys_mmap(8) as *i64 90 let wp: *i64 = sys_mmap(8) as *i64 91 let hp: *i64 = sys_mmap(8) as *i64 92 if nx_jpeg_decode_rgb(jpeg, szp[0], rp, wp, hp) != NX_JPEG_ASCII_OK { hw("decode fail\n" as *u8); return 1 } 93 let rgb: *u8 = rp[0] as *u8 94 let tw: i64 = wp[0] 95 let tgtQ: *i64 = sys_mmap(NPX*3*8) as *i64 // targets in Q12 (4096 = 255) 96 let ex: *i64 = sys_mmap(NPX*8) as *i64 // exemplar packed (for the PNG) 97 var py: i64 = 0 98 while py < PS { 99 var px: i64 = 0 100 while px < PS { 101 let o: i64 = ((CY+py)*tw + CX+px)*3 102 let r: i64 = (rgb[o] as i64)&255 103 let g: i64 = (rgb[o+1] as i64)&255 104 let b: i64 = (rgb[o+2] as i64)&255 105 let pi: i64 = py*PS+px 106 tgtQ[pi*3] = r*4096/255 107 tgtQ[pi*3+1] = g*4096/255 108 tgtQ[pi*3+2] = b*4096/255 109 ex[pi] = r + g*256 + b*65536 110 px = px + 1 111 } 112 py = py + 1 113 } 114 115 // ---- precompute features for every training coordinate ---- 116 let FT: *i64 = sys_mmap(NPX*NF*8) as *i64 117 py = 0 118 while py < PS { 119 var px: i64 = 0 120 while px < PS { 121 let fp: *i64 = (FT as i64 + (py*PS+px)*NF*8) as *i64 122 features(px, py, 1, fp) 123 px = px + 1 124 } 125 py = py + 1 126 } 127 128 // ---- model (Q12) + mixed-bias init (the XOR lesson: mixed biases avoid dead ReLUs) ---- 129 let W1: *i64 = sys_mmap(NH*NF*8) as *i64 130 let B1: *i64 = sys_mmap(NH*8) as *i64 131 let W2: *i64 = sys_mmap(NO*NH*8) as *i64 132 let B2: *i64 = sys_mmap(NO*8) as *i64 133 let gW1: *i64 = sys_mmap(NH*NF*8) as *i64 134 let gB1: *i64 = sys_mmap(NH*8) as *i64 135 let gW2: *i64 = sys_mmap(NO*NH*8) as *i64 136 let gB2: *i64 = sys_mmap(NO*8) as *i64 137 // error-feedback accumulators: carry sub-truncation gradient signal across epochs (integer training 138 // otherwise STALLS once g*LR/(N*4096) rounds to 0 -- the classic quantized-GD fix) 139 let aW1: *i64 = sys_mmap(NH*NF*8) as *i64 140 let aB1: *i64 = sys_mmap(NH*8) as *i64 141 let aW2: *i64 = sys_mmap(NO*NH*8) as *i64 142 let aB2: *i64 = sys_mmap(NO*8) as *i64 143 let st: *i64 = sys_mmap(16) as *i64 144 st[0] = 20260709 145 // ★frequency-scaled init (the FFN lesson): high-band weights start SMALL (amp ~ 600/k), else the random 146 // init paints a 2px plaid that gradient descent can never unlearn (high-freq sinusoids have ~zero gradient 147 // against a smooth residual -> the plaid FREEZES in). Bands only grow where real edges demand them. 148 let bamp: *i64 = sys_mmap(8*8) as *i64 149 bamp[0]=600; bamp[1]=300; bamp[2]=150; bamp[3]=75; bamp[4]=38; bamp[5]=25 150 var q: i64 = 0 151 while q < NH*NF { 152 let band: i64 = (q % NF) / 4 153 let a: i64 = bamp[band] 154 W1[q] = lcg(st) % (2*a) - a 155 q = q + 1 156 } 157 q = 0 158 while q < NH { B1[q] = ((q % 2)*2 - 1) * 150; q = q + 1 } 159 q = 0 160 while q < NO*NH { W2[q] = lcg(st) % 800 - 400; q = q + 1 } 161 q = 0 162 while q < NO { B2[q] = 2048; q = q + 1 } 163 164 // ---- train: full-batch integer gradient descent ---- 165 let h: *i64 = sys_mmap(NH*8) as *i64 166 let dh: *i64 = sys_mmap(NH*8) as *i64 167 let dob: *i64 = sys_mmap(NO*8) as *i64 168 var err0: i64 = 0 169 var errN: i64 = 0 170 var ep: i64 = 0 171 while ep < EPOCHS { 172 q = 0 173 while q < NH*NF { gW1[q]=0; q=q+1 } 174 q = 0 175 while q < NH { gB1[q]=0; q=q+1 } 176 q = 0 177 while q < NO*NH { gW2[q]=0; q=q+1 } 178 q = 0 179 while q < NO { gB2[q]=0; q=q+1 } 180 var errsum: i64 = 0 181 var pi: i64 = 0 182 while pi < NPX { 183 let f: *i64 = (FT as i64 + pi*NF*8) as *i64 184 // forward 185 var j: i64 = 0 186 while j < NH { 187 var acc: i64 = B1[j] 188 var i2: i64 = 0 189 while i2 < NF { acc = acc + W1[j*NF+i2]*f[i2]/4096; i2 = i2 + 1 } 190 if acc < 0 { acc = 0 } 191 if acc > 16384 { acc = 16384 } 192 h[j] = acc 193 j = j + 1 194 } 195 var c: i64 = 0 196 while c < NO { 197 var acc: i64 = B2[c] 198 j = 0 199 while j < NH { acc = acc + W2[c*NH+j]*h[j]/4096; j = j + 1 } 200 var d: i64 = acc - tgtQ[pi*3+c] 201 if d > 8192 { d = 8192 } 202 if d < 0-8192 { d = 0-8192 } 203 dob[c] = d 204 var ad: i64 = d 205 if ad < 0 { ad = 0 - ad } 206 errsum = errsum + ad 207 c = c + 1 208 } 209 // backward 210 j = 0 211 while j < NH { 212 var dd: i64 = 0 213 c = 0 214 while c < NO { dd = dd + W2[c*NH+j]*dob[c]/4096; c = c + 1 } 215 if h[j] == 0 { dd = 0 } 216 dh[j] = dd 217 j = j + 1 218 } 219 c = 0 220 while c < NO { 221 let dc: i64 = dob[c] 222 j = 0 223 while j < NH { gW2[c*NH+j] = gW2[c*NH+j] + dc*h[j]/4096; j = j + 1 } 224 gB2[c] = gB2[c] + dc 225 c = c + 1 226 } 227 j = 0 228 while j < NH { 229 let dj: i64 = dh[j] 230 if dj != 0 { 231 var i2: i64 = 0 232 while i2 < NF { gW1[j*NF+i2] = gW1[j*NF+i2] + dj*f[i2]/4096; i2 = i2 + 1 } 233 gB1[j] = gB1[j] + dj 234 } 235 j = j + 1 236 } 237 pi = pi + 1 238 } 239 // update with ERROR FEEDBACK: acc += g*LR; step = acc/D; W -= step; acc -= step*D (D = NPX*4096) 240 var LR: i64 = 600 241 if ep >= 350 { LR = 300 } 242 let D: i64 = NPX*4096 243 q = 0 244 while q < NH*NF { aW1[q] = aW1[q] + gW1[q]*LR; let s2: i64 = aW1[q]/D; W1[q] = W1[q] - s2; aW1[q] = aW1[q] - s2*D; q = q + 1 } 245 q = 0 246 while q < NH { aB1[q] = aB1[q] + gB1[q]*LR; let s2: i64 = aB1[q]/D; B1[q] = B1[q] - s2; aB1[q] = aB1[q] - s2*D; q = q + 1 } 247 q = 0 248 while q < NO*NH { aW2[q] = aW2[q] + gW2[q]*LR; let s2: i64 = aW2[q]/D; W2[q] = W2[q] - s2; aW2[q] = aW2[q] - s2*D; q = q + 1 } 249 q = 0 250 while q < NO { aB2[q] = aB2[q] + gB2[q]*LR; let s2: i64 = aB2[q]/D; B2[q] = B2[q] - s2; aB2[q] = aB2[q] - s2*D; q = q + 1 } 251 let e255: i64 = errsum*255/(NPX*3*4096) 252 if ep == 0 { err0 = e255 } 253 errN = e255 254 if ep % 80 == 0 { hw(" epoch "); pn(ep); hw(" mean|err|="); pn(e255); hw("/255\n" as *u8) } 255 ep = ep + 1 256 } 257 hw(" trained: err "); pn(err0); hw(" -> "); pn(errN); hw(" /255 ("); pn(NH*NF+NH+NO*NH+NO); hw(" params, "); pn(EPOCHS); hw(" epochs, integer Q12)\n" as *u8) 258 259 var t1: i64 = 0 260 if errN*2 < err0 { t1 = 1 } 261 if t1 == 1 { hw("T1 PASS training converges (error < half of untrained on the structured target)\n" as *u8) } 262 else { fails=fails+1; hw("T1 FAIL no convergence\n" as *u8) } 263 var t2: i64 = 0 264 if errN < 20 { t2 = 1 } 265 if t2 == 1 { hw("T2 PASS close reconstruction of the real skin patch\n" as *u8) } 266 else { fails=fails+1; hw("T2 FAIL err="); pn(errN); hw("\n" as *u8) } 267 268 // ---- render reconstruction (integer inference) ---- 269 let rec: *i64 = sys_mmap(NPX*8) as *i64 270 let f2: *i64 = sys_mmap(NF*8) as *i64 271 py = 0 272 while py < PS { 273 var px: i64 = 0 274 while px < PS { features(px, py, 1, f2); rec[py*PS+px] = infer(W1, B1, W2, B2, f2, h); px = px + 1 } 275 py = py + 1 276 } 277 278 // ---- T3 persist quantized weights -> reload -> re-render must be bit-identical ---- 279 let NPARAM: i64 = NH*NF + NH + NO*NH + NO 280 let wf: i64 = sys_openat_wr("knowledge/skintex_w.bin\x00" as *u8, 0x1a4) 281 sys_write(wf, W1 as *u8, NH*NF*8) 282 sys_write(wf, B1 as *u8, NH*8) 283 sys_write(wf, W2 as *u8, NO*NH*8) 284 sys_write(wf, B2 as *u8, NO*8) 285 sys_close(wf) 286 let lsz: *i64 = sys_mmap(16) as *i64 287 let blob: *u8 = sys_read_file("knowledge/skintex_w.bin" as *u8, lsz) 288 var t3: i64 = 0 289 if lsz[0] == NPARAM*8 { 290 let L1p: *i64 = blob as *i64 291 let L2p: *i64 = (blob as i64 + NH*NF*8) as *i64 292 let L3p: *i64 = (blob as i64 + NH*NF*8 + NH*8) as *i64 293 let L4p: *i64 = (blob as i64 + NH*NF*8 + NH*8 + NO*NH*8) as *i64 294 var diff: i64 = 0 295 py = 0 296 while py < PS { 297 var px: i64 = 0 298 while px < PS { 299 features(px, py, 1, f2) 300 if infer(L1p, L2p, L3p, L4p, f2, h) != rec[py*PS+px] { diff = diff + 1 } 301 px = px + 1 302 } 303 py = py + 1 304 } 305 if diff == 0 { t3 = 1 } 306 } 307 if t3 == 1 { hw("T3 PASS integer weights persisted (skintex_w.bin) + reloaded render BIT-IDENTICAL\n" as *u8) } 308 else { fails=fails+1; hw("T3 FAIL persistence\n" as *u8) } 309 310 // ---- T4 resolution-free 4x zoom render + combo PNG ---- 311 let Z: i64 = PS*4 312 let zoom: *i64 = sys_mmap(Z*Z*8) as *i64 313 py = 0 314 while py < Z { 315 var px: i64 = 0 316 while px < Z { features(px, py, 4, f2); zoom[py*Z+px] = infer(W1, B1, W2, B2, f2, h); px = px + 1 } 317 py = py + 1 318 } 319 let GW: i64 = Z*3 320 let gal: *i64 = sys_mmap(GW*Z*8) as *i64 321 py = 0 322 while py < Z { 323 var px: i64 = 0 324 while px < Z { 325 gal[py*GW+px] = ex[(py/4)*PS + px/4] // exemplar (nearest x4) 326 gal[py*GW+Z+px] = rec[(py/4)*PS + px/4] // reconstruction (nearest x4) 327 gal[py*GW+Z*2+px] = zoom[py*Z+px] // native 4x (smooth) 328 px = px + 1 329 } 330 py = py + 1 331 } 332 write_png(gal, GW, Z, "knowledge/nx_skintex.png" as *u8) 333 hw("T4 PNG knowledge/nx_skintex.png (exemplar | reconstruction | native 4x zoom)\n" as *u8) 334 335 if fails == 0 { hw("SKINTEX-GATE 4/4 GREEN -- P4 R1: a TRAINED sovereign neural skin-texture model (coordinate-MLP, integer Q12 backprop on REAL skin, persisted, integer inference, resolution-free) -- the P4 pipeline proven end-to-end\n" as *u8); sys_exit(0); return 0 } 336 hw("SKINTEX-GATE RED fails="); pn(fails); hw("\n" as *u8) 337 sys_exit(1) 338 return 1 339}