programdemos/net-macro/net-macro.xtl

Three networks for one task (which of three spiral arms is a point on?), each described once, by one line: the Net macro library turns a spec, sizes and activations, into the loading of the weights and an ordinary function of NN calls before the program is compiled. xetal expand shows what it wrote.

source · imports nn: libs/NN/src/NN.xtl; net: libs/Net/src/Net.xtlm

The data, read from data/ (just net-train)

pts : Float

value · line 13

The test points, one per line: x, y and the arm (1, 2 or 3).

pts ← n̲umbers ⎕N̲GET "data/points.txt"
Used in: pts, xy, arm

pts : Float

value · line 14
pts ← o̲\ (((t̲ally pts) d̲iv 3) c̲at 3) r̲eshape pts

xy : Float

value · line 15
xy ← o̲\ 2 t̲ake pts

arm : Int

value · line 16
arm ← f̲loor 3 s̲elect pts

The networks: each described once

a1 : Float

value · line 23

From a spec the macro writes the loading of each dense layer's weights (data/a1.txt, ...: inputs + 1 by outputs, the bias last; the program stops, naming the layer, if a file holds the wrong count) and the forward function.

"u:l_inear a" ⁿᵉᵗm̲odel< "2 3 softmax"
ⁿᵉᵗm̲odel< expands to
a1 ← { v → 9 = t̲ally v ? 3 3 r̲eshape v◆ ⎕P̲ANIC "data/a1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 3 softmax\" (2 inputs and a bias, 3 outputs) needs 9" } n̲umbers ⎕N̲GET "data/a1.txt"
ᵘl̲inear ← { x → ⁿⁿs̲oftmax x ⁿⁿd̲ense a1 }
Used in: a1

ᵘl̲inear : Float -> Float

function · line 23

From a spec the macro writes the loading of each dense layer's weights (data/a1.txt, ...: inputs + 1 by outputs, the bias last; the program stops, naming the layer, if a file holds the wrong count) and the forward function.

"u:l_inear a" ⁿᵉᵗm̲odel< "2 3 softmax"
ⁿᵉᵗm̲odel< expands to
a1 ← { v → 9 = t̲ally v ? 3 3 r̲eshape v◆ ⎕P̲ANIC "data/a1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 3 softmax\" (2 inputs and a bias, 3 outputs) needs 9" } n̲umbers ⎕N̲GET "data/a1.txt"
ᵘl̲inear ← { x → ⁿⁿs̲oftmax x ⁿⁿd̲ense a1 }

b1 : Float

value · line 24
"u:s_mall b" ⁿᵉᵗm̲odel< "2 4 tanh 3 softmax"
ⁿᵉᵗm̲odel< expands to
b1 ← { v → 12 = t̲ally v ? 3 4 r̲eshape v◆ ⎕P̲ANIC "data/b1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 4 tanh 3 softmax\" (2 inputs and a bias, 4 outputs) needs 12" } n̲umbers ⎕N̲GET "data/b1.txt"
b2 ← { v → 15 = t̲ally v ? 5 3 r̲eshape v◆ ⎕P̲ANIC "data/b2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 4 tanh 3 softmax\" (4 inputs and a bias, 3 outputs) needs 15" } n̲umbers ⎕N̲GET "data/b2.txt"
ᵘs̲mall ← { x → ⁿⁿs̲oftmax (ⁿⁿt̲anh x ⁿⁿd̲ense b1) ⁿⁿd̲ense b2 }
Used in: b1

b2 : Float

value · line 24
"u:s_mall b" ⁿᵉᵗm̲odel< "2 4 tanh 3 softmax"
ⁿᵉᵗm̲odel< expands to
b1 ← { v → 12 = t̲ally v ? 3 4 r̲eshape v◆ ⎕P̲ANIC "data/b1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 4 tanh 3 softmax\" (2 inputs and a bias, 4 outputs) needs 12" } n̲umbers ⎕N̲GET "data/b1.txt"
b2 ← { v → 15 = t̲ally v ? 5 3 r̲eshape v◆ ⎕P̲ANIC "data/b2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 4 tanh 3 softmax\" (4 inputs and a bias, 3 outputs) needs 15" } n̲umbers ⎕N̲GET "data/b2.txt"
ᵘs̲mall ← { x → ⁿⁿs̲oftmax (ⁿⁿt̲anh x ⁿⁿd̲ense b1) ⁿⁿd̲ense b2 }
Used in: b1

ᵘs̲mall : Float -> Float

function · line 24
"u:s_mall b" ⁿᵉᵗm̲odel< "2 4 tanh 3 softmax"
ⁿᵉᵗm̲odel< expands to
b1 ← { v → 12 = t̲ally v ? 3 4 r̲eshape v◆ ⎕P̲ANIC "data/b1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 4 tanh 3 softmax\" (2 inputs and a bias, 4 outputs) needs 12" } n̲umbers ⎕N̲GET "data/b1.txt"
b2 ← { v → 15 = t̲ally v ? 5 3 r̲eshape v◆ ⎕P̲ANIC "data/b2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 4 tanh 3 softmax\" (4 inputs and a bias, 3 outputs) needs 15" } n̲umbers ⎕N̲GET "data/b2.txt"
ᵘs̲mall ← { x → ⁿⁿs̲oftmax (ⁿⁿt̲anh x ⁿⁿd̲ense b1) ⁿⁿd̲ense b2 }

c1 : Float

value · line 25
"u:d_eep c" ⁿᵉᵗm̲odel< "2 16 relu 16 relu 3 softmax"
ⁿᵉᵗm̲odel< expands to
c1 ← { v → 48 = t̲ally v ? 3 16 r̲eshape v◆ ⎕P̲ANIC "data/c1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 16 relu 16 relu 3 softmax\" (2 inputs and a bias, 16 outputs) needs 48" } n̲umbers ⎕N̲GET "data/c1.txt"
c2 ← { v → 272 = t̲ally v ? 17 16 r̲eshape v◆ ⎕P̲ANIC "data/c2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 16 outputs) needs 272" } n̲umbers ⎕N̲GET "data/c2.txt"
c3 ← { v → 51 = t̲ally v ? 17 3 r̲eshape v◆ ⎕P̲ANIC "data/c3.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 3 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 3 outputs) needs 51" } n̲umbers ⎕N̲GET "data/c3.txt"
ᵘd̲eep ← { x → ⁿⁿs̲oftmax (ⁿⁿr̲elu (ⁿⁿr̲elu x ⁿⁿd̲ense c1) ⁿⁿd̲ense c2) ⁿⁿd̲ense c3 }
Used in: c1

c2 : Float

value · line 25
"u:d_eep c" ⁿᵉᵗm̲odel< "2 16 relu 16 relu 3 softmax"
ⁿᵉᵗm̲odel< expands to
c1 ← { v → 48 = t̲ally v ? 3 16 r̲eshape v◆ ⎕P̲ANIC "data/c1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 16 relu 16 relu 3 softmax\" (2 inputs and a bias, 16 outputs) needs 48" } n̲umbers ⎕N̲GET "data/c1.txt"
c2 ← { v → 272 = t̲ally v ? 17 16 r̲eshape v◆ ⎕P̲ANIC "data/c2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 16 outputs) needs 272" } n̲umbers ⎕N̲GET "data/c2.txt"
c3 ← { v → 51 = t̲ally v ? 17 3 r̲eshape v◆ ⎕P̲ANIC "data/c3.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 3 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 3 outputs) needs 51" } n̲umbers ⎕N̲GET "data/c3.txt"
ᵘd̲eep ← { x → ⁿⁿs̲oftmax (ⁿⁿr̲elu (ⁿⁿr̲elu x ⁿⁿd̲ense c1) ⁿⁿd̲ense c2) ⁿⁿd̲ense c3 }
Used in: c1

c3 : Float

value · line 25
"u:d_eep c" ⁿᵉᵗm̲odel< "2 16 relu 16 relu 3 softmax"
ⁿᵉᵗm̲odel< expands to
c1 ← { v → 48 = t̲ally v ? 3 16 r̲eshape v◆ ⎕P̲ANIC "data/c1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 16 relu 16 relu 3 softmax\" (2 inputs and a bias, 16 outputs) needs 48" } n̲umbers ⎕N̲GET "data/c1.txt"
c2 ← { v → 272 = t̲ally v ? 17 16 r̲eshape v◆ ⎕P̲ANIC "data/c2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 16 outputs) needs 272" } n̲umbers ⎕N̲GET "data/c2.txt"
c3 ← { v → 51 = t̲ally v ? 17 3 r̲eshape v◆ ⎕P̲ANIC "data/c3.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 3 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 3 outputs) needs 51" } n̲umbers ⎕N̲GET "data/c3.txt"
ᵘd̲eep ← { x → ⁿⁿs̲oftmax (ⁿⁿr̲elu (ⁿⁿr̲elu x ⁿⁿd̲ense c1) ⁿⁿd̲ense c2) ⁿⁿd̲ense c3 }
Used in: c1

ᵘd̲eep : Float -> Float

function · line 25
"u:d_eep c" ⁿᵉᵗm̲odel< "2 16 relu 16 relu 3 softmax"
ⁿᵉᵗm̲odel< expands to
c1 ← { v → 48 = t̲ally v ? 3 16 r̲eshape v◆ ⎕P̲ANIC "data/c1.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 1 of \"2 16 relu 16 relu 3 softmax\" (2 inputs and a bias, 16 outputs) needs 48" } n̲umbers ⎕N̲GET "data/c1.txt"
c2 ← { v → 272 = t̲ally v ? 17 16 r̲eshape v◆ ⎕P̲ANIC "data/c2.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 2 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 16 outputs) needs 272" } n̲umbers ⎕N̲GET "data/c2.txt"
c3 ← { v → 51 = t̲ally v ? 17 3 r̲eshape v◆ ⎕P̲ANIC "data/c3.txt holds " c̲at (f̲ormat t̲ally v) c̲at " numbers; layer 3 of \"2 16 relu 16 relu 3 softmax\" (16 inputs and a bias, 3 outputs) needs 51" } n̲umbers ⎕N̲GET "data/c3.txt"
ᵘd̲eep ← { x → ⁿⁿs̲oftmax (ⁿⁿr̲elu (ⁿⁿr̲elu x ⁿⁿd̲ense c1) ⁿⁿd̲ense c2) ⁿⁿd̲ense c3 }

g : Int

value · line 35

What each decides over the square -1.1 .. 1.1 (a, b, c: the arms).

g ← 20
Used in: c, grid, ᵘa̲rms

c : Float

value · line 36
c ← -1.1 + 2.2 × (0.5 + f̲loat o̲ffsets g) ÷ f̲loat g
Used in: grid

grid : Float

value · line 37
grid ← o̲\ (2 c̲at g × g) r̲eshape (r̲avel (o̲ffsets g) 'r̲ight t̲able c) c̲at r̲avel (r̲ev c) 'l̲eft t̲able o̲ffsets g

ᵘa̲rms : Num a => a -> Char

function · line 38
ᵘa̲rms ← { y → (g c̲at g) r̲eshape (ⁿⁿa̲rgmax y) s̲elect "abc" }