oikan 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oikan-0.0.1/PKG-INFO +10 -0
- oikan-0.0.1/README.md +48 -0
- oikan-0.0.1/oikan/__init__.py +0 -0
- oikan-0.0.1/oikan/model.py +28 -0
- oikan-0.0.1/oikan/symbolic.py +36 -0
- oikan-0.0.1/oikan/trainer.py +34 -0
- oikan-0.0.1/oikan/visualize.py +20 -0
- oikan-0.0.1/oikan.egg-info/PKG-INFO +10 -0
- oikan-0.0.1/oikan.egg-info/SOURCES.txt +12 -0
- oikan-0.0.1/oikan.egg-info/dependency_links.txt +1 -0
- oikan-0.0.1/oikan.egg-info/requires.txt +5 -0
- oikan-0.0.1/oikan.egg-info/top_level.txt +1 -0
- oikan-0.0.1/pyproject.toml +16 -0
- oikan-0.0.1/setup.cfg +4 -0
oikan-0.0.1/PKG-INFO
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Metadata-Version: 2.2
|
2
|
+
Name: oikan
|
3
|
+
Version: 0.0.1
|
4
|
+
Summary: OIKAN: Optimized Interpretable Kolmogorov-Arnold Networks
|
5
|
+
Author: Arman Zhalgasbayev
|
6
|
+
Requires-Dist: torch
|
7
|
+
Requires-Dist: numpy
|
8
|
+
Requires-Dist: sympy
|
9
|
+
Requires-Dist: scipy
|
10
|
+
Requires-Dist: matplotlib
|
oikan-0.0.1/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# OIKAN Library
|
2
|
+
|
3
|
+
[](https://badge.fury.io/py/oikan)
|
4
|
+
[](https://pypistats.org/packages/oikan)
|
5
|
+
|
6
|
+
OIKAN (Optimized Implementation of Kolmogorov-Arnold Networks) is a PyTorch-based library for creating interpretable neural networks. It implements the KAN architecture to provide both accurate predictions and interpretable results.
|
7
|
+
|
8
|
+
## Key Features
|
9
|
+
|
10
|
+
- EfficientKAN layer implementation
|
11
|
+
- Built-in visualization tools
|
12
|
+
- Support for both regression and classification tasks
|
13
|
+
- Symbolic formula extraction
|
14
|
+
- Easy-to-use training interface
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
```bash
|
19
|
+
git clone https://github.com/silvermete0r/OIKAN.git
|
20
|
+
cd OIKAN
|
21
|
+
pip install -r requirements.txt
|
22
|
+
```
|
23
|
+
|
24
|
+
## Quick Start
|
25
|
+
|
26
|
+
### Regression Example
|
27
|
+
```python
|
28
|
+
from oikan.model import OIKAN
|
29
|
+
from oikan.trainer import train
|
30
|
+
|
31
|
+
# Create and train model
|
32
|
+
model = OIKAN(input_dim=2, output_dim=1)
|
33
|
+
train(model, train_loader)
|
34
|
+
|
35
|
+
# Extract interpretable formula
|
36
|
+
formula = extract_symbolic_formula_regression(model, X)
|
37
|
+
```
|
38
|
+
|
39
|
+
### Classification Example
|
40
|
+
```python
|
41
|
+
model = OIKAN(input_dim=2, output_dim=2)
|
42
|
+
train_classification(model, train_loader)
|
43
|
+
visualize_classification(model, X, y)
|
44
|
+
```
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import torch
|
2
|
+
import torch.nn as nn
|
3
|
+
|
4
|
+
# EfficientKAN Layer
|
5
|
+
class EfficientKAN(nn.Module):
|
6
|
+
def __init__(self, input_dim, hidden_units=10):
|
7
|
+
super(EfficientKAN, self).__init__()
|
8
|
+
self.basis_functions = nn.ModuleList([nn.Linear(1, hidden_units) for _ in range(input_dim)])
|
9
|
+
self.activations = nn.ReLU()
|
10
|
+
|
11
|
+
def forward(self, x):
|
12
|
+
transformed_features = [self.activations(bf(x[:, i].unsqueeze(1))) for i, bf in enumerate(self.basis_functions)]
|
13
|
+
return torch.cat(transformed_features, dim=1)
|
14
|
+
|
15
|
+
# OIKAN Model
|
16
|
+
class OIKAN(nn.Module):
|
17
|
+
def __init__(self, input_dim, output_dim, hidden_units=10):
|
18
|
+
super(OIKAN, self).__init__()
|
19
|
+
self.efficientkan = EfficientKAN(input_dim, hidden_units)
|
20
|
+
self.mlp = nn.Sequential(
|
21
|
+
nn.Linear(input_dim * hidden_units, 32),
|
22
|
+
nn.ReLU(),
|
23
|
+
nn.Linear(32, output_dim)
|
24
|
+
)
|
25
|
+
|
26
|
+
def forward(self, x):
|
27
|
+
transformed_x = self.efficientkan(x)
|
28
|
+
return self.mlp(transformed_x)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import torch
|
2
|
+
from sympy import symbols, simplify, Add
|
3
|
+
|
4
|
+
# Regression symbolic extraction
|
5
|
+
def extract_symbolic_formula_regression(model, input_data):
|
6
|
+
symbolic_vars = symbols([f'x{i}' for i in range(input_data.shape[1])])
|
7
|
+
|
8
|
+
with torch.no_grad():
|
9
|
+
weights = model.mlp[0].weight.cpu().numpy()
|
10
|
+
if weights.size == 0:
|
11
|
+
print("Warning: Extracted weights are empty.")
|
12
|
+
return "NaN"
|
13
|
+
|
14
|
+
formula = sum(weights[0, i] * symbolic_vars[i] for i in range(len(symbolic_vars)))
|
15
|
+
return simplify(formula)
|
16
|
+
|
17
|
+
# Classification symbolic extraction
|
18
|
+
def extract_symbolic_formula_classification(model, input_data):
|
19
|
+
"""
|
20
|
+
Extracts a symbolic decision boundary for a two-class classifier.
|
21
|
+
Approximates:
|
22
|
+
decision = (w[0] - w[1]) · x + (b[0] - b[1])
|
23
|
+
where w and b are from the model's final linear layer.
|
24
|
+
"""
|
25
|
+
symbolic_vars = symbols([f'x{i}' for i in range(input_data.shape[1])])
|
26
|
+
with torch.no_grad():
|
27
|
+
final_layer = model.mlp[-1]
|
28
|
+
w = final_layer.weight.cpu().numpy()
|
29
|
+
b = final_layer.bias.cpu().numpy()
|
30
|
+
if w.shape[0] < 2:
|
31
|
+
print("Classification symbolic extraction requires at least 2 classes.")
|
32
|
+
return "NaN"
|
33
|
+
w_diff = w[0] - w[1]
|
34
|
+
b_diff = b[0] - b[1]
|
35
|
+
formula = sum(w_diff[i] * symbolic_vars[i] for i in range(len(symbolic_vars))) + b_diff
|
36
|
+
return simplify(formula)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import torch.optim as optim
|
2
|
+
import torch.nn as nn
|
3
|
+
|
4
|
+
# Regression training
|
5
|
+
def train(model, train_loader, epochs=100, lr=0.01):
|
6
|
+
criterion = nn.MSELoss()
|
7
|
+
optimizer = optim.LBFGS(model.parameters(), lr=lr)
|
8
|
+
|
9
|
+
def closure():
|
10
|
+
optimizer.zero_grad()
|
11
|
+
outputs = model(train_loader[0])
|
12
|
+
loss = criterion(outputs, train_loader[1])
|
13
|
+
loss.backward()
|
14
|
+
print(f"Loss: {loss.item()}")
|
15
|
+
return loss
|
16
|
+
|
17
|
+
for epoch in range(epochs):
|
18
|
+
optimizer.step(closure)
|
19
|
+
if epoch % 10 == 0:
|
20
|
+
print(f"Epoch {epoch+1}/{epochs}")
|
21
|
+
|
22
|
+
# Classification training
|
23
|
+
def train_classification(model, train_loader, epochs=100, lr=0.01):
|
24
|
+
criterion = nn.CrossEntropyLoss()
|
25
|
+
optimizer = optim.Adam(model.parameters(), lr=lr)
|
26
|
+
|
27
|
+
for epoch in range(epochs):
|
28
|
+
optimizer.zero_grad()
|
29
|
+
outputs = model(train_loader[0])
|
30
|
+
loss = criterion(outputs, train_loader[1])
|
31
|
+
loss.backward()
|
32
|
+
optimizer.step()
|
33
|
+
if (epoch + 1) % 10 == 0:
|
34
|
+
print(f"Epoch {epoch+1}/{epochs}, Loss: {loss.item()}")
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import matplotlib.pyplot as plt
|
2
|
+
import torch
|
3
|
+
|
4
|
+
# Regression Visualization Function
|
5
|
+
def visualize_regression(model, X, y):
|
6
|
+
with torch.no_grad():
|
7
|
+
y_pred = model(torch.tensor(X, dtype=torch.float32)).numpy()
|
8
|
+
plt.scatter(X[:, 0], y, label='True Data')
|
9
|
+
plt.scatter(X[:, 0], y_pred, label='OIKAN Predictions', color='r')
|
10
|
+
plt.legend()
|
11
|
+
plt.show()
|
12
|
+
|
13
|
+
# Classification visualization
|
14
|
+
def visualize_classification(model, X, y):
|
15
|
+
with torch.no_grad():
|
16
|
+
outputs = model(torch.tensor(X, dtype=torch.float32))
|
17
|
+
preds = torch.argmax(outputs, dim=1).numpy()
|
18
|
+
plt.scatter(X[:, 0], X[:, 1], c=preds, cmap='viridis', edgecolor='k')
|
19
|
+
plt.title("Classification Results")
|
20
|
+
plt.show()
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Metadata-Version: 2.2
|
2
|
+
Name: oikan
|
3
|
+
Version: 0.0.1
|
4
|
+
Summary: OIKAN: Optimized Interpretable Kolmogorov-Arnold Networks
|
5
|
+
Author: Arman Zhalgasbayev
|
6
|
+
Requires-Dist: torch
|
7
|
+
Requires-Dist: numpy
|
8
|
+
Requires-Dist: sympy
|
9
|
+
Requires-Dist: scipy
|
10
|
+
Requires-Dist: matplotlib
|
@@ -0,0 +1,12 @@
|
|
1
|
+
README.md
|
2
|
+
pyproject.toml
|
3
|
+
oikan/__init__.py
|
4
|
+
oikan/model.py
|
5
|
+
oikan/symbolic.py
|
6
|
+
oikan/trainer.py
|
7
|
+
oikan/visualize.py
|
8
|
+
oikan.egg-info/PKG-INFO
|
9
|
+
oikan.egg-info/SOURCES.txt
|
10
|
+
oikan.egg-info/dependency_links.txt
|
11
|
+
oikan.egg-info/requires.txt
|
12
|
+
oikan.egg-info/top_level.txt
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
oikan
|
@@ -0,0 +1,16 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "oikan"
|
7
|
+
version = "0.0.1"
|
8
|
+
description = "OIKAN: Optimized Interpretable Kolmogorov-Arnold Networks"
|
9
|
+
authors = [{name = "Arman Zhalgasbayev"}]
|
10
|
+
dependencies = [
|
11
|
+
"torch",
|
12
|
+
"numpy",
|
13
|
+
"sympy",
|
14
|
+
"scipy",
|
15
|
+
"matplotlib"
|
16
|
+
]
|
oikan-0.0.1/setup.cfg
ADDED