Download model.py from phanerozoic/threshold-xor: direct link, hf CLI and curl.
- Browser
- Download file 2.62 kB
-
https://huggingface.co/phanerozoic/threshold-xor/resolve/main/model.py
- Command line
-
hf download hf://phanerozoic/threshold-xor/model.py
-
curl -L -o model.py https://huggingface.co/phanerozoic/threshold-xor/resolve/main/model.py
2.62 kB
| """ | |
| Threshold Network for XOR Gate | |
| A formally verified two-layer threshold network computing exclusive or. | |
| XOR is not linearly separable, requiring at least 2 layers. | |
| Architecture: Layer1 computes OR and NAND, Layer2 computes AND of results. | |
| """ | |
| import torch | |
| from safetensors.torch import load_file | |
| class ThresholdXOR: | |
| """ | |
| XOR gate implemented as a 2-layer threshold network. | |
| Layer 1: OR (neuron 1) and NAND (neuron 2) in parallel | |
| Layer 2: AND of layer 1 outputs | |
| XOR(x,y) = AND(OR(x,y), NAND(x,y)) | |
| """ | |
| def __init__(self, weights_dict): | |
| self.l1_n1_weight = weights_dict['layer1.neuron1.weight'] | |
| self.l1_n1_bias = weights_dict['layer1.neuron1.bias'] | |
| self.l1_n2_weight = weights_dict['layer1.neuron2.weight'] | |
| self.l1_n2_bias = weights_dict['layer1.neuron2.bias'] | |
| self.l2_weight = weights_dict['layer2.weight'] | |
| self.l2_bias = weights_dict['layer2.bias'] | |
| def __call__(self, x1, x2): | |
| inputs = torch.tensor([float(x1), float(x2)]) | |
| or_out = ((inputs * self.l1_n1_weight).sum() + self.l1_n1_bias >= 0).float() | |
| nand_out = ((inputs * self.l1_n2_weight).sum() + self.l1_n2_bias >= 0).float() | |
| layer1_out = torch.tensor([or_out, nand_out]) | |
| output = ((layer1_out * self.l2_weight).sum() + self.l2_bias >= 0).float() | |
| return output | |
| def from_safetensors(cls, path="model.safetensors"): | |
| return cls(load_file(path)) | |
| def forward(x1, x2, weights): | |
| """ | |
| Forward pass with Heaviside activation. | |
| Args: | |
| x1, x2: Input values (0 or 1) | |
| weights: Dict with layer weights and biases | |
| Returns: | |
| XOR(x1, x2) | |
| """ | |
| inputs = torch.tensor([float(x1), float(x2)]) | |
| or_out = ((inputs * weights['layer1.neuron1.weight']).sum() + weights['layer1.neuron1.bias'] >= 0).float() | |
| nand_out = ((inputs * weights['layer1.neuron2.weight']).sum() + weights['layer1.neuron2.bias'] >= 0).float() | |
| layer1_out = torch.tensor([or_out, nand_out]) | |
| output = ((layer1_out * weights['layer2.weight']).sum() + weights['layer2.bias'] >= 0).float() | |
| return output | |
| if __name__ == "__main__": | |
| weights = load_file("model.safetensors") | |
| model = ThresholdXOR(weights) | |
| print("XOR Gate Truth Table:") | |
| print("-" * 25) | |
| for x1 in [0, 1]: | |
| for x2 in [0, 1]: | |
| out = int(model(x1, x2).item()) | |
| expected = x1 ^ x2 | |
| status = "OK" if out == expected else "FAIL" | |
| print(f"XOR({x1}, {x2}) = {out} [{status}]") | |