phanerozoic commited on
Commit
66f10f9
·
verified ·
1 Parent(s): bdf66bf

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. README.md +56 -0
  2. config.json +9 -0
  3. create_safetensors.py +40 -0
  4. model.py +57 -0
  5. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ ---
9
+
10
+ # threshold-xnor3
11
+
12
+ 3-input XNOR gate. Outputs 1 when an even number of inputs are 1 (0 or 2).
13
+
14
+ ## Architecture
15
+
16
+ Cascade: XNOR3(a,b,c) = XOR(XNOR(a,b), c)
17
+
18
+ ```
19
+ a,b ──► XNOR ──► XOR ──► output
20
+ c ──┘
21
+ ```
22
+
23
+ ## Parameters
24
+
25
+ | | |
26
+ |---|---|
27
+ | Neurons | 6 |
28
+ | Layers | 4 |
29
+ | Parameters | 18 |
30
+ | Magnitude | 19 |
31
+
32
+ ## Truth Table
33
+
34
+ | a | b | c | output |
35
+ |---|---|---|--------|
36
+ | 0 | 0 | 0 | 1 |
37
+ | 0 | 0 | 1 | 0 |
38
+ | 0 | 1 | 0 | 0 |
39
+ | 0 | 1 | 1 | 1 |
40
+ | 1 | 0 | 0 | 0 |
41
+ | 1 | 0 | 1 | 1 |
42
+ | 1 | 1 | 0 | 1 |
43
+ | 1 | 1 | 1 | 0 |
44
+
45
+ ## Usage
46
+
47
+ ```python
48
+ from safetensors.torch import load_file
49
+
50
+ w = load_file('model.safetensors')
51
+ # See model.py for forward pass
52
+ ```
53
+
54
+ ## License
55
+
56
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-xnor3",
3
+ "description": "3-input XNOR gate as threshold circuit",
4
+ "inputs": 3,
5
+ "outputs": 1,
6
+ "neurons": 6,
7
+ "layers": 4,
8
+ "parameters": 18
9
+ }
create_safetensors.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import save_file
3
+
4
+ # XNOR3 = XOR(XNOR(a,b), c)
5
+ # Using standard (non-optimized) weights
6
+
7
+ # XNOR(a,b): NOR + AND -> OR structure
8
+ # n1 (NOR): fires when both inputs 0
9
+ # n2 (AND): fires when both inputs 1
10
+ # out (OR): fires when either n1 or n2
11
+
12
+ # XOR(x,y): OR + NAND -> AND structure
13
+ # n1 (OR): fires when at least one input 1
14
+ # n2 (NAND): fires when not both inputs 1
15
+ # out (AND): fires when both n1 and n2
16
+
17
+ weights = {
18
+ # First XNOR: a XNOR b
19
+ 'xnor1.layer1.n1.weight': torch.tensor([-1.0, -1.0]), # NOR
20
+ 'xnor1.layer1.n1.bias': torch.tensor([0.0]),
21
+ 'xnor1.layer1.n2.weight': torch.tensor([1.0, 1.0]), # AND
22
+ 'xnor1.layer1.n2.bias': torch.tensor([-2.0]),
23
+ 'xnor1.layer2.weight': torch.tensor([1.0, 1.0]), # OR
24
+ 'xnor1.layer2.bias': torch.tensor([-1.0]),
25
+
26
+ # Second XOR: (a XNOR b) XOR c
27
+ 'xor2.layer1.n1.weight': torch.tensor([1.0, 1.0]), # OR
28
+ 'xor2.layer1.n1.bias': torch.tensor([-1.0]),
29
+ 'xor2.layer1.n2.weight': torch.tensor([-1.0, -1.0]), # NAND
30
+ 'xor2.layer1.n2.bias': torch.tensor([1.0]),
31
+ 'xor2.layer2.weight': torch.tensor([1.0, 1.0]), # AND
32
+ 'xor2.layer2.bias': torch.tensor([-2.0]),
33
+ }
34
+
35
+ save_file(weights, 'model.safetensors')
36
+
37
+ mag = sum(t.abs().sum().item() for t in weights.values())
38
+ print(f'Created model.safetensors')
39
+ print(f' magnitude: {mag:.0f}')
40
+ print(f' parameters: {sum(t.numel() for t in weights.values())}')
model.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Threshold Network for 3-input XNOR Gate
3
+
4
+ XNOR3(a,b,c) = 1 when even number of inputs are 1 (0 or 2)
5
+ Built as: XOR(XNOR(a,b), c)
6
+ """
7
+
8
+ import torch
9
+ from safetensors.torch import load_file
10
+
11
+
12
+ class ThresholdXNOR3:
13
+ def __init__(self, weights_dict):
14
+ self.w = weights_dict
15
+
16
+ def __call__(self, a, b, c):
17
+ # First XNOR: a XNOR b (1 when a=b)
18
+ inp1 = torch.tensor([float(a), float(b)])
19
+ n1 = int((inp1 * self.w['xnor1.layer1.n1.weight']).sum() + self.w['xnor1.layer1.n1.bias'] >= 0)
20
+ n2 = int((inp1 * self.w['xnor1.layer1.n2.weight']).sum() + self.w['xnor1.layer1.n2.bias'] >= 0)
21
+
22
+ h1 = torch.tensor([float(n1), float(n2)])
23
+ xnor_ab = int((h1 * self.w['xnor1.layer2.weight']).sum() + self.w['xnor1.layer2.bias'] >= 0)
24
+
25
+ # Second XOR: xnor_ab XOR c
26
+ inp2 = torch.tensor([float(xnor_ab), float(c)])
27
+ n3 = int((inp2 * self.w['xor2.layer1.n1.weight']).sum() + self.w['xor2.layer1.n1.bias'] >= 0)
28
+ n4 = int((inp2 * self.w['xor2.layer1.n2.weight']).sum() + self.w['xor2.layer1.n2.bias'] >= 0)
29
+
30
+ h2 = torch.tensor([float(n3), float(n4)])
31
+ out = int((h2 * self.w['xor2.layer2.weight']).sum() + self.w['xor2.layer2.bias'] >= 0)
32
+
33
+ return float(out)
34
+
35
+ @classmethod
36
+ def from_safetensors(cls, path="model.safetensors"):
37
+ return cls(load_file(path))
38
+
39
+
40
+ if __name__ == "__main__":
41
+ weights = load_file("model.safetensors")
42
+ model = ThresholdXNOR3(weights)
43
+
44
+ print("3-input XNOR Gate Truth Table:")
45
+ print("-" * 30)
46
+ correct = 0
47
+ for a in [0, 1]:
48
+ for b in [0, 1]:
49
+ for c in [0, 1]:
50
+ out = int(model(a, b, c))
51
+ # XNOR3 = even parity = NOT XOR3
52
+ expected = 1 - (a ^ b ^ c)
53
+ status = "OK" if out == expected else "FAIL"
54
+ if out == expected:
55
+ correct += 1
56
+ print(f"XNOR3({a}, {b}, {c}) = {out} [{status}]")
57
+ print(f"\nTotal: {correct}/8 correct")
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f789ee1eaf958fa522d3df45978f9ce232709a45029ad20cc38270c5016b47ea
3
+ size 960