phanerozoic commited on
Commit
7feeb56
·
verified ·
1 Parent(s): 43ac45e

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. README.md +160 -0
  2. config.json +9 -0
  3. create_safetensors.py +71 -0
  4. model.py +24 -0
  5. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ - encoding
9
+ - decoder
10
+ ---
11
+
12
+ # threshold-binary-to-onehot
13
+
14
+ 2-to-4 binary-to-one-hot encoder. Converts a 2-bit binary value to a 4-bit one-hot representation. The inverse of the one-hot decoder.
15
+
16
+ ## Circuit
17
+
18
+ ```
19
+ a1 a0
20
+ │ │
21
+ ├─────────┤
22
+ │ │
23
+ ┌───┴───┐ ┌───┴───┐
24
+ │ │ │ │
25
+ ▼ ▼ ▼ ▼
26
+ ┌───┐ ┌───┐ ┌───┐ ┌───┐
27
+ │y0 │ │y1 │ │y2 │ │y3 │
28
+ │NOR│ │AND│ │AND│ │AND│
29
+ │ │ │¬a1│ │a1 │ │a1 │
30
+ │ │ │ a0│ │¬a0│ │a0 │
31
+ └───┘ └───┘ └───┘ └───┘
32
+ │ │ │ │
33
+ ▼ ▼ ▼ ▼
34
+ y0 y1 y2 y3
35
+ (00) (01) (10) (11)
36
+ ```
37
+
38
+ ## Function
39
+
40
+ ```
41
+ binary_to_onehot(a1, a0) -> (y0, y1, y2, y3)
42
+ ```
43
+
44
+ Exactly one output is high, corresponding to the binary input value.
45
+
46
+ ## Truth Table
47
+
48
+ | a1 | a0 | Value | y0 | y1 | y2 | y3 |
49
+ |:--:|:--:|:-----:|:--:|:--:|:--:|:--:|
50
+ | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
51
+ | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
52
+ | 1 | 0 | 2 | 0 | 0 | 1 | 0 |
53
+ | 1 | 1 | 3 | 0 | 0 | 0 | 1 |
54
+
55
+ Output encoding: `y[i] = 1` iff input value equals `i`.
56
+
57
+ ## Mechanism
58
+
59
+ Each output neuron detects a specific binary pattern:
60
+
61
+ | Output | Pattern | Weights [a1, a0] | Bias | Logic |
62
+ |--------|---------|------------------|------|-------|
63
+ | y0 | 00 | [-1, -1] | 0 | NOR(a1, a0) |
64
+ | y1 | 01 | [-1, +1] | -1 | ¬a1 AND a0 |
65
+ | y2 | 10 | [+1, -1] | -1 | a1 AND ¬a0 |
66
+ | y3 | 11 | [+1, +1] | -2 | a1 AND a0 |
67
+
68
+ **Analysis:**
69
+
70
+ - **y0 (value 0):** Fires when both inputs are 0. Negative weights ensure any 1 prevents firing.
71
+ - **y1 (value 1):** Fires when a1=0 and a0=1. The -1 on a1 inhibits, +1 on a0 excites.
72
+ - **y2 (value 2):** Fires when a1=1 and a0=0. The +1 on a1 excites, -1 on a0 inhibits.
73
+ - **y3 (value 3):** Fires when both are 1. Both positive weights must overcome bias -2.
74
+
75
+ ## Architecture
76
+
77
+ Single-layer implementation with 4 parallel neurons:
78
+
79
+ | Neuron | Weights | Bias | Detects |
80
+ |--------|---------|------|---------|
81
+ | y0 | [-1, -1] | 0 | Binary 00 |
82
+ | y1 | [-1, +1] | -1 | Binary 01 |
83
+ | y2 | [+1, -1] | -1 | Binary 10 |
84
+ | y3 | [+1, +1] | -2 | Binary 11 |
85
+
86
+ ## Parameters
87
+
88
+ | | |
89
+ |---|---|
90
+ | Inputs | 2 (a1, a0) |
91
+ | Outputs | 4 (y0, y1, y2, y3) |
92
+ | Neurons | 4 |
93
+ | Layers | 1 |
94
+ | Parameters | 12 |
95
+ | Magnitude | 12 |
96
+
97
+ ## Relationship to One-Hot Decoder
98
+
99
+ This circuit is the **inverse** of `threshold-onehot-decoder`:
100
+
101
+ ```
102
+ Binary [a1, a0] ──► binary-to-onehot ──► One-hot [y0, y1, y2, y3]
103
+ One-hot [y0, y1, y2, y3] ──► onehot-decoder ──► Binary [a1, a0]
104
+ ```
105
+
106
+ Together they form a codec pair for binary ↔ one-hot conversion.
107
+
108
+ ## Usage
109
+
110
+ ```python
111
+ from safetensors.torch import load_file
112
+ import torch
113
+
114
+ w = load_file('model.safetensors')
115
+
116
+ def binary_to_onehot(a1, a0):
117
+ inp = torch.tensor([float(a1), float(a0)])
118
+ y0 = int((inp @ w['y0.weight'].T + w['y0.bias'] >= 0).item())
119
+ y1 = int((inp @ w['y1.weight'].T + w['y1.bias'] >= 0).item())
120
+ y2 = int((inp @ w['y2.weight'].T + w['y2.bias'] >= 0).item())
121
+ y3 = int((inp @ w['y3.weight'].T + w['y3.bias'] >= 0).item())
122
+ return y0, y1, y2, y3
123
+
124
+ # Examples
125
+ print(binary_to_onehot(0, 0)) # (1, 0, 0, 0) - value 0
126
+ print(binary_to_onehot(0, 1)) # (0, 1, 0, 0) - value 1
127
+ print(binary_to_onehot(1, 0)) # (0, 0, 1, 0) - value 2
128
+ print(binary_to_onehot(1, 1)) # (0, 0, 0, 1) - value 3
129
+ ```
130
+
131
+ ## Applications
132
+
133
+ - Address decoding in memory systems
134
+ - Demultiplexer control signals
135
+ - State machine encoding
136
+ - Neural network softmax approximation
137
+ - Priority encoder inputs
138
+
139
+ ## Scaling
140
+
141
+ For n-bit binary to 2^n one-hot:
142
+ - 3-bit → 8 outputs (8 neurons)
143
+ - 4-bit → 16 outputs (16 neurons)
144
+
145
+ Each additional input bit doubles the outputs.
146
+
147
+ ## Files
148
+
149
+ ```
150
+ threshold-binary-to-onehot/
151
+ ├── model.safetensors
152
+ ├── model.py
153
+ ├── create_safetensors.py
154
+ ├── config.json
155
+ └── README.md
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-binary-to-onehot",
3
+ "description": "2-to-4 binary to one-hot encoder",
4
+ "inputs": 2,
5
+ "outputs": 4,
6
+ "neurons": 4,
7
+ "layers": 1,
8
+ "parameters": 12
9
+ }
create_safetensors.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import save_file
3
+
4
+ weights = {}
5
+
6
+ # Binary to One-Hot Encoder (2-to-4)
7
+ # Inputs: a1, a0 (binary value 0-3)
8
+ # Outputs: y0, y1, y2, y3 (one-hot encoding)
9
+ #
10
+ # y0 = 1 when a1=0, a0=0 (NOR)
11
+ # y1 = 1 when a1=0, a0=1 (AND with inverted a1)
12
+ # y2 = 1 when a1=1, a0=0 (AND with inverted a0)
13
+ # y3 = 1 when a1=1, a0=1 (AND)
14
+
15
+ # y0: NOR(a1, a0) - fires when both are 0
16
+ weights['y0.weight'] = torch.tensor([[-1.0, -1.0]], dtype=torch.float32)
17
+ weights['y0.bias'] = torch.tensor([0.0], dtype=torch.float32)
18
+
19
+ # y1: NOT(a1) AND a0 - fires when a1=0, a0=1
20
+ weights['y1.weight'] = torch.tensor([[-1.0, 1.0]], dtype=torch.float32)
21
+ weights['y1.bias'] = torch.tensor([-1.0], dtype=torch.float32)
22
+
23
+ # y2: a1 AND NOT(a0) - fires when a1=1, a0=0
24
+ weights['y2.weight'] = torch.tensor([[1.0, -1.0]], dtype=torch.float32)
25
+ weights['y2.bias'] = torch.tensor([-1.0], dtype=torch.float32)
26
+
27
+ # y3: a1 AND a0 - fires when both are 1
28
+ weights['y3.weight'] = torch.tensor([[1.0, 1.0]], dtype=torch.float32)
29
+ weights['y3.bias'] = torch.tensor([-2.0], dtype=torch.float32)
30
+
31
+ save_file(weights, 'model.safetensors')
32
+
33
+ def binary_to_onehot(a1, a0):
34
+ inp = torch.tensor([float(a1), float(a0)])
35
+ y0 = int((inp @ weights['y0.weight'].T + weights['y0.bias'] >= 0).item())
36
+ y1 = int((inp @ weights['y1.weight'].T + weights['y1.bias'] >= 0).item())
37
+ y2 = int((inp @ weights['y2.weight'].T + weights['y2.bias'] >= 0).item())
38
+ y3 = int((inp @ weights['y3.weight'].T + weights['y3.bias'] >= 0).item())
39
+ return y0, y1, y2, y3
40
+
41
+ print("Verifying binary-to-onehot...")
42
+ errors = 0
43
+ for val in range(4):
44
+ a1, a0 = (val >> 1) & 1, val & 1
45
+ y0, y1, y2, y3 = binary_to_onehot(a1, a0)
46
+
47
+ # Check exactly one output is high
48
+ outputs = [y0, y1, y2, y3]
49
+ if sum(outputs) != 1:
50
+ errors += 1
51
+ print(f"ERROR: {a1}{a0} -> {outputs} (not one-hot)")
52
+ # Check correct output is high
53
+ elif outputs[val] != 1:
54
+ errors += 1
55
+ print(f"ERROR: {a1}{a0} -> {outputs} (wrong position)")
56
+
57
+ if errors == 0:
58
+ print("All 4 test cases passed!")
59
+ else:
60
+ print(f"FAILED: {errors} errors")
61
+
62
+ print(f"Magnitude: {sum(t.abs().sum().item() for t in weights.values()):.0f}")
63
+ print(f"Parameters: {sum(t.numel() for t in weights.values())}")
64
+
65
+ print("\nTruth Table:")
66
+ print("a1 a0 | y0 y1 y2 y3 | value")
67
+ print("------+-------------+------")
68
+ for val in range(4):
69
+ a1, a0 = (val >> 1) & 1, val & 1
70
+ y0, y1, y2, y3 = binary_to_onehot(a1, a0)
71
+ print(f" {a1} {a0} | {y0} {y1} {y2} {y3} | {val}")
model.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 binary_to_onehot(a1, a0, weights):
8
+ """Convert 2-bit binary to 4-bit one-hot encoding."""
9
+ inp = torch.tensor([float(a1), float(a0)])
10
+ y0 = int((inp @ weights['y0.weight'].T + weights['y0.bias'] >= 0).item())
11
+ y1 = int((inp @ weights['y1.weight'].T + weights['y1.bias'] >= 0).item())
12
+ y2 = int((inp @ weights['y2.weight'].T + weights['y2.bias'] >= 0).item())
13
+ y3 = int((inp @ weights['y3.weight'].T + weights['y3.bias'] >= 0).item())
14
+ return y0, y1, y2, y3
15
+
16
+ if __name__ == '__main__':
17
+ w = load_model()
18
+ print('Binary to One-Hot Encoder (2-to-4):')
19
+ print('a1 a0 | y0 y1 y2 y3 | value')
20
+ print('------+-------------+------')
21
+ for val in range(4):
22
+ a1, a0 = (val >> 1) & 1, val & 1
23
+ y0, y1, y2, y3 = binary_to_onehot(a1, a0, w)
24
+ print(f' {a1} {a0} | {y0} {y1} {y2} {y3} | {val}')
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b68212cf121754735cc150c45cdb9587afe702f91a23356c4f210e00ecf60fd5
3
+ size 560