CompressedGemma commited on
Commit
944a442
·
verified ·
1 Parent(s): eb1dc11

Construct source neuron

Browse files
Files changed (1) hide show
  1. construct_correct_neurons.py +122 -0
construct_correct_neurons.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Construct neurons to match two Jacobian boundaries at x1 ≈ -0.665558 and x2 ≈ 0.594541."""
3
+
4
+ import torch
5
+ import math
6
+ import os
7
+ from safetensors.torch import save_file
8
+
9
+ # Target boundaries and slopes
10
+ boundary_x1 = -0.665558
11
+ boundary_x2 = 0.594541
12
+ left_slope = 11.0
13
+ mid_slope = 1.0
14
+ right_slope = 0.5
15
+
16
+ # Right equation: y = 0.5 * x - 0.2489895
17
+ right_eq = lambda x: 0.5 * x - 0.2489895
18
+
19
+ # Middle equation (continuous at boundary_x2):
20
+ c_mid = right_eq(boundary_x2) - mid_slope * boundary_x2
21
+ mid_eq = lambda x: mid_slope * x + c_mid
22
+
23
+ # Left equation (continuous at boundary_x1):
24
+ c_left = mid_eq(boundary_x1) - left_slope * boundary_x1
25
+ left_eq = lambda x: left_slope * x + c_left
26
+
27
+ print("Constructing neurons to match:")
28
+ print(f" Boundary 1 at x = {boundary_x1}")
29
+ print(f" Boundary 2 at x = {boundary_x2}")
30
+ print(f" Left slope = {left_slope:4.1f}, range: x < {boundary_x1:.6f}")
31
+ print(f" Middle slope = {mid_slope:4.1f}, range: {boundary_x1:.6f} < x < {boundary_x2:.6f}")
32
+ print(f" Right slope = {right_slope:4.1f}, range: x > {boundary_x2:.6f}")
33
+
34
+ # Use native PyTorch tensors to avoid redundant casting overhead
35
+ W1 = torch.zeros((8, 1), dtype=torch.float32)
36
+ b1 = torch.zeros(8, dtype=torch.float32)
37
+ W2 = torch.zeros((1, 8), dtype=torch.float32)
38
+ b2 = torch.zeros(1, dtype=torch.float32)
39
+
40
+ # Neuron 0: Always active pure slope carrier
41
+ # FIX: Use a robustly large bias so the neuron doesn't turn off during extreme negative activation outliers
42
+ W1[0, 0] = 1.0
43
+ b1[0] = 100.0 # Guarantees the carrier stays active for x > -100.0
44
+ W2[0, 0] = right_slope
45
+
46
+ # Neuron 1: Active left of boundary_x1 (adds left_slope - mid_slope = 10.0 to slope)
47
+ W1[1, 0] = -1.0
48
+ b1[1] = boundary_x1
49
+ W2[0, 1] = -(left_slope - mid_slope)
50
+
51
+ # Neuron 2: Active left of boundary_x2 (adds mid_slope - right_slope = 0.5 to slope)
52
+ W1[2, 0] = -1.0
53
+ b1[2] = boundary_x2
54
+ W2[0, 2] = -(mid_slope - right_slope)
55
+
56
+ # Neurons 3-7: Inactive (zero weights)
57
+
58
+ # Calculate exact b2 so that the function matches target_y at boundary_x2
59
+ target_y = right_eq(boundary_x2)
60
+ neuron0_out = W2[0, 0] * (W1[0, 0] * boundary_x2 + b1[0])
61
+ b2[0] = target_y - neuron0_out
62
+
63
+ print("\nConstructed neuron weights:")
64
+ print(f"W1:\n{W1.numpy()}")
65
+ print(f"b1: {b1.numpy()}")
66
+ print(f"W2:\n{W2.numpy()}")
67
+ print(f"b2: {b2.numpy()}")
68
+
69
+
70
+ # Verify the construction natively
71
+ def mlp_forward(x):
72
+ x_t = torch.tensor([[x]], dtype=torch.float32)
73
+ h = x_t @ W1.T + b1
74
+ h = torch.relu(h)
75
+ y = h @ W2.T + b2
76
+ return y.item()
77
+
78
+ print("\n" + "=" * 60)
79
+ print("Automated Verification:")
80
+ print("=" * 60)
81
+
82
+ # Test at Boundary 1
83
+ y_b1 = mlp_forward(boundary_x1)
84
+ expected_y_b1 = mid_eq(boundary_x1)
85
+ assert math.isclose(y_b1, expected_y_b1, rel_tol=1e-4, abs_tol=1e-5), f"Boundary 1 mismatch! Expected {expected_y_b1}, got {y_b1}"
86
+ print(f"✓ Boundary 1 (x = {boundary_x1}) matched")
87
+
88
+ # Test at Boundary 2
89
+ y_b2 = mlp_forward(boundary_x2)
90
+ expected_y_b2 = right_eq(boundary_x2)
91
+ assert math.isclose(y_b2, expected_y_b2, rel_tol=1e-4, abs_tol=1e-5), f"Boundary 2 mismatch! Expected {expected_y_b2}, got {y_b2}"
92
+ print(f"✓ Boundary 2 (x = {boundary_x2}) matched")
93
+
94
+ # Test left slope
95
+ x_left1, x_left2 = boundary_x1 - 0.10, boundary_x1 - 0.05
96
+ slope_left = (mlp_forward(x_left2) - mlp_forward(x_left1)) / (x_left2 - x_left1)
97
+ assert math.isclose(slope_left, left_slope, rel_tol=1e-4, abs_tol=1e-5), f"Left slope mismatch! Expected {left_slope}, got {slope_left}"
98
+ print(f"✓ Left slope matched: {slope_left:.4f}")
99
+
100
+ # Test middle slope
101
+ x_mid1, x_mid2 = (boundary_x1 + boundary_x2) / 2, ((boundary_x1 + boundary_x2) / 2) + 0.05
102
+ slope_mid = (mlp_forward(x_mid2) - mlp_forward(x_mid1)) / (x_mid2 - x_mid1)
103
+ assert math.isclose(slope_mid, mid_slope, rel_tol=1e-4, abs_tol=1e-5), f"Middle slope mismatch! Expected {mid_slope}, got {slope_mid}"
104
+ print(f"✓ Middle slope matched: {slope_mid:.4f}")
105
+
106
+ # Test right slope
107
+ x_right1, x_right2 = boundary_x2 + 0.05, boundary_x2 + 0.10
108
+ slope_right = (mlp_forward(x_right2) - mlp_forward(x_right1)) / (x_right2 - x_right1)
109
+ assert math.isclose(slope_right, right_slope, rel_tol=1e-4, abs_tol=1e-5), f"Right slope mismatch! Expected {right_slope}, got {slope_right}"
110
+ print(f"✓ Right slope matched: {slope_right:.4f}")
111
+
112
+ os.makedirs("test_mlp_hf", exist_ok=True)
113
+
114
+ # Save the constructed weights
115
+ save_file({
116
+ "layer1.weight": W1,
117
+ "layer1.bias": b1,
118
+ "layer2.weight": W2,
119
+ "layer2.bias": b2,
120
+ }, "test_mlp_hf/model.safetensors")
121
+
122
+ print("\nSuccessfully saved constructed neuron to test_mlp_hf/model.safetensors")