CharlesCNorton commited on
Commit
ca9ffed
·
0 Parent(s):

Exactly 1 of 3 threshold circuit, magnitude 12

Browse files
Files changed (5) hide show
  1. README.md +73 -0
  2. config.json +9 -0
  3. create_safetensors.py +34 -0
  4. model.py +19 -0
  5. model.safetensors +0 -0
README.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ ---
9
+
10
+ # threshold-exactly1outof3
11
+
12
+ Exactly 1 of 3 inputs high.
13
+
14
+ ## Function
15
+
16
+ exactly1outof3(a, b, c) = 1 if (a + b + c) == 1, else 0
17
+
18
+ ## Truth Table
19
+
20
+ | a | b | c | sum | out |
21
+ |---|---|---|-----|-----|
22
+ | 0 | 0 | 0 | 0 | 0 |
23
+ | 0 | 0 | 1 | 1 | 1 |
24
+ | 0 | 1 | 0 | 1 | 1 |
25
+ | 0 | 1 | 1 | 2 | 0 |
26
+ | 1 | 0 | 0 | 1 | 1 |
27
+ | 1 | 0 | 1 | 2 | 0 |
28
+ | 1 | 1 | 0 | 2 | 0 |
29
+ | 1 | 1 | 1 | 3 | 0 |
30
+
31
+ ## Architecture
32
+
33
+ Two layers (not linearly separable):
34
+
35
+ **Layer 1:**
36
+ - N1: weights [1, 1, 1], bias -1 (fires when sum >= 1)
37
+ - N2: weights [-1, -1, -1], bias 1 (fires when sum <= 1)
38
+
39
+ **Layer 2:**
40
+ - AND: weights [1, 1], bias -2 (fires when both N1 and N2 fire)
41
+
42
+ ## Parameters
43
+
44
+ | | |
45
+ |---|---|
46
+ | Inputs | 3 |
47
+ | Outputs | 1 |
48
+ | Neurons | 3 |
49
+ | Layers | 2 |
50
+ | Parameters | 11 |
51
+ | Magnitude | 12 |
52
+
53
+ ## Usage
54
+
55
+ ```python
56
+ from safetensors.torch import load_file
57
+ import torch
58
+
59
+ w = load_file('model.safetensors')
60
+
61
+ def exactly1of3(a, b, c):
62
+ inp = torch.tensor([float(a), float(b), float(c)])
63
+ l1 = (inp @ w['layer1.weight'].T + w['layer1.bias'] >= 0).float()
64
+ out = (l1 @ w['layer2.weight'].T + w['layer2.bias'] >= 0).float()
65
+ return int(out.item())
66
+
67
+ print(exactly1of3(0, 0, 1)) # 1 (sum=1)
68
+ print(exactly1of3(0, 1, 1)) # 0 (sum=2)
69
+ ```
70
+
71
+ ## License
72
+
73
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-exactly1outof3",
3
+ "description": "Exactly 1 of 3 inputs high",
4
+ "inputs": 3,
5
+ "outputs": 1,
6
+ "neurons": 3,
7
+ "layers": 2,
8
+ "parameters": 11
9
+ }
create_safetensors.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import save_file
3
+
4
+ # Layer 1: N1 (sum >= 1), N2 (sum <= 1)
5
+ # Layer 2: AND(N1, N2)
6
+ weights = {
7
+ 'layer1.weight': torch.tensor([
8
+ [1.0, 1.0, 1.0], # N1: sum >= 1
9
+ [-1.0, -1.0, -1.0] # N2: sum <= 1
10
+ ], dtype=torch.float32),
11
+ 'layer1.bias': torch.tensor([-1.0, 1.0], dtype=torch.float32),
12
+ 'layer2.weight': torch.tensor([[1.0, 1.0]], dtype=torch.float32),
13
+ 'layer2.bias': torch.tensor([-2.0], dtype=torch.float32)
14
+ }
15
+ save_file(weights, 'model.safetensors')
16
+
17
+ def test(a, b, c):
18
+ inp = torch.tensor([float(a), float(b), float(c)])
19
+ l1 = (inp @ weights['layer1.weight'].T + weights['layer1.bias'] >= 0).float()
20
+ out = (l1 @ weights['layer2.weight'].T + weights['layer2.bias'] >= 0).float()
21
+ return int(out.item())
22
+
23
+ print("Verifying exactly1outof3...")
24
+ errors = 0
25
+ for i in range(8):
26
+ a, b, c = (i >> 2) & 1, (i >> 1) & 1, i & 1
27
+ result = test(a, b, c)
28
+ expected = 1 if (a + b + c) == 1 else 0
29
+ if result != expected:
30
+ errors += 1
31
+ print(f"ERROR: {a}{b}{c} -> {result}, expected {expected}")
32
+ if errors == 0:
33
+ print("All 8 test cases passed!")
34
+ print(f"Magnitude: {sum(t.abs().sum().item() for t in weights.values()):.0f}")
model.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import load_file
3
+
4
+ def load_model(path='model.safetensors'):
5
+ return load_file(path)
6
+
7
+ def exactly1of3(a, b, c, weights):
8
+ """Returns 1 if exactly 1 of 3 inputs is high"""
9
+ inp = torch.tensor([float(a), float(b), float(c)])
10
+ l1 = (inp @ weights['layer1.weight'].T + weights['layer1.bias'] >= 0).float()
11
+ out = (l1 @ weights['layer2.weight'].T + weights['layer2.bias'] >= 0).float()
12
+ return int(out.item())
13
+
14
+ if __name__ == '__main__':
15
+ w = load_model()
16
+ print('exactly1outof3 truth table:')
17
+ for i in range(8):
18
+ a, b, c = (i >> 2) & 1, (i >> 1) & 1, i & 1
19
+ print(f' {a}{b}{c} -> {exactly1of3(a, b, c, w)}')
model.safetensors ADDED
Binary file (324 Bytes). View file