// SPDX-License-Identifier: Apache-2.0 ; specs/widgets/nn-xor.t27 -- a 2-8-1 network learns XOR by backpropagation ; Source of truth for public/widgets/nn-xor/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs ; compiles this file, checks its constants, evaluates the tests below and writes the page; the page ; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of ; its own: every value it draws comes from public/widgets/nn-xor/logic.js -- the fn bodies of ; gHashTag/t27 specs/ml/pathway/mlp.t27 compiled to wasm, beside its copy logic.t27. ; Lesson 20 of the course neural-networks. ASCII only (L3), English only (LANG-EN). ; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. ; WHAT IT DOES: the reader drags the epochs from 0 to 2000. Every output is xor(epochs, 2 + c), the ; loss curve xor(e, 1) every 25 epochs and the first-epoch loss xor(e, 0): the spec trains its own ; 2-8-1 network from fixed initial weights at lr 0.05, from scratch on every call. ; WHAT IT DOES NOT CLAIM: the grid shows the four inputs the spec exposes, not a decision region ; over the plane: the spec has no fn for a point between the corners. ; phi^2 + 1/phi^2 = 3 | TRINITY module widget_nn_xor; pub const KIND : str = "widget-tool"; pub const ID : str = "nn-xor"; pub const TITLE : str = "XOR: a network learns what one neuron cannot"; pub const DESCRIPTION : str = "A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders."; pub const IMAGE_ALT : str = "XOR card after 2000 epochs: a 2 x 2 grid of the four cases, dark blue 0.000 on the diagonal and white 1.000 off it. Beside it a red loss curve on a log axis falls from 0.89 at epoch 1 to about 1e-13 at 2000. Tiles read first-epoch loss 0.8896, last 1.78e-13, outputs 0.00 1.00 1.00 0.00 against the targets 0 1 1 0."; pub const HOOK : str = "One neuron cannot draw XOR. Eight hidden units can: after 2000 epochs the outputs are 0, 1, 1, 0 to within 4e-7 and the loss is 1.8e-13."; pub const CATEGORY : str = "compiler"; pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/pathway/mlp.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 20 opens this widget"]; pub const READS_LOCAL_FILES : bool = false; pub const SENDS_NOTHING : bool = true; pub const K_CARD_WIDTH : u16 = 1200; pub const K_CARD_HEIGHT : u16 = 630; ; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) pub const K_EPOCHS_HI : u16 = 2000; pub const K_CURVE_STEP : u8 = 25; pub const K_LOG_LO : i8 = -14; pub const K_LOG_HI : u8 = 1; pub const K_LOG_TICKS : [5]i8 = [-12, -9, -6, -3, 0]; pub const K_EPOCH_TICKS : [5]u16 = [0, 500, 1000, 1500, 2000]; pub const K_CASES : [4]u8 = [0, 1, 1, 0]; pub const K_PRESET_EPOCHS : [4]u16 = [2000, 0, 100, 500]; pub const K_START_PRESET : u8 = 0; ; --- Words on screen ------------------------------------------------------------------------ pub const SAY_PRESETS_LABEL : str = "Start from"; pub const SAY_PRESET_NAMES : [4]str = ["Trained, 2000 epochs", "Untrained", "100 epochs", "500 epochs"]; pub const SAY_ASK : str = "Can a network learn something one neuron cannot?"; pub const SAY_EPOCHS : str = "epochs"; pub const SAY_A : str = "a ="; pub const SAY_B : str = "b ="; pub const SAY_CURVE_LABEL : str = "The training loss, log scale"; pub const SAY_GRID_LABEL : str = "The network's answer for each input (a, b)"; pub const SAY_LOG_NOTE : str = "log scale"; pub const SAY_FIRST_LOSS : str = "loss, epoch 1"; pub const SAY_LAST_LOSS : str = "loss, last epoch"; pub const SAY_UNTRAINED : str = "not trained"; pub const SAY_OUTPUTS : str = "outputs 00 01 10 11"; pub const SAY_TARGETS : str = "targets"; pub const SAY_NOTE : str = "XOR is 1 when exactly one input is 1. No straight line separates its 1s from its 0s, so one neuron fails; a hidden layer of ReLUs bends the space until one does."; pub const SAY_SOURCE : str = "Logic: t27 spec ml/pathway/mlp.t27, compiled"; test the_card_is_the_share_size { assert K_CARD_WIDTH == 1200; assert K_CARD_HEIGHT == 630; assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; } test the_curve_steps_divide_the_run { assert K_EPOCHS_HI % K_CURVE_STEP == 0; assert K_EPOCHS_HI / K_CURVE_STEP == 80; } test the_targets_are_xor { assert K_CASES[0] == 0; assert K_CASES[1] == 1; assert K_CASES[2] == 1; assert K_CASES[3] == 0; assert K_PRESET_EPOCHS[0] == K_EPOCHS_HI; }