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}