torchsonn 0.1.0__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.
- torchsonn-0.1.0/LICENSE +21 -0
- torchsonn-0.1.0/PKG-INFO +231 -0
- torchsonn-0.1.0/README.md +196 -0
- torchsonn-0.1.0/pyproject.toml +95 -0
- torchsonn-0.1.0/setup.cfg +4 -0
- torchsonn-0.1.0/src/torchsonn/__init__.py +23 -0
- torchsonn-0.1.0/src/torchsonn/config/__init__.py +22 -0
- torchsonn-0.1.0/src/torchsonn/config/schemas.py +293 -0
- torchsonn-0.1.0/src/torchsonn/data/__init__.py +0 -0
- torchsonn-0.1.0/src/torchsonn/data/dataset.py +40 -0
- torchsonn-0.1.0/src/torchsonn/data/preprocessing.py +185 -0
- torchsonn-0.1.0/src/torchsonn/layer.py +184 -0
- torchsonn-0.1.0/src/torchsonn/logger.py +56 -0
- torchsonn-0.1.0/src/torchsonn/loss/__init__.py +17 -0
- torchsonn-0.1.0/src/torchsonn/loss/errors.py +273 -0
- torchsonn-0.1.0/src/torchsonn/loss/norm_mse.py +12 -0
- torchsonn-0.1.0/src/torchsonn/model.py +721 -0
- torchsonn-0.1.0/src/torchsonn/modules/__init__.py +8 -0
- torchsonn-0.1.0/src/torchsonn/modules/base.py +37 -0
- torchsonn-0.1.0/src/torchsonn/modules/soft_binner.py +28 -0
- torchsonn-0.1.0/src/torchsonn/neurons/__init__.py +24 -0
- torchsonn-0.1.0/src/torchsonn/neurons/base.py +373 -0
- torchsonn-0.1.0/src/torchsonn/neurons/binary.py +85 -0
- torchsonn-0.1.0/src/torchsonn/neurons/poly.py +124 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/__init__.py +26 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/adam.py +96 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/base.py +42 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/lbfgs.py +260 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/newton.py +123 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/newton_lm.py +82 -0
- torchsonn-0.1.0/src/torchsonn/optimizers/sgd.py +96 -0
- torchsonn-0.1.0/src/torchsonn/plot_model.py +171 -0
- torchsonn-0.1.0/src/torchsonn/schedulers/__init__.py +14 -0
- torchsonn-0.1.0/src/torchsonn/schedulers/base.py +11 -0
- torchsonn-0.1.0/src/torchsonn/schedulers/warmup_flat.py +39 -0
- torchsonn-0.1.0/src/torchsonn/trainer.py +2375 -0
- torchsonn-0.1.0/src/torchsonn/types.py +101 -0
- torchsonn-0.1.0/src/torchsonn/utils.py +73 -0
- torchsonn-0.1.0/src/torchsonn.egg-info/PKG-INFO +231 -0
- torchsonn-0.1.0/src/torchsonn.egg-info/SOURCES.txt +56 -0
- torchsonn-0.1.0/src/torchsonn.egg-info/dependency_links.txt +1 -0
- torchsonn-0.1.0/src/torchsonn.egg-info/requires.txt +16 -0
- torchsonn-0.1.0/src/torchsonn.egg-info/top_level.txt +1 -0
- torchsonn-0.1.0/tests/test_config.py +65 -0
- torchsonn-0.1.0/tests/test_data.py +240 -0
- torchsonn-0.1.0/tests/test_layer.py +137 -0
- torchsonn-0.1.0/tests/test_logger.py +76 -0
- torchsonn-0.1.0/tests/test_loss.py +136 -0
- torchsonn-0.1.0/tests/test_model.py +705 -0
- torchsonn-0.1.0/tests/test_modules.py +69 -0
- torchsonn-0.1.0/tests/test_neurons.py +288 -0
- torchsonn-0.1.0/tests/test_optimizers.py +318 -0
- torchsonn-0.1.0/tests/test_plot_model.py +214 -0
- torchsonn-0.1.0/tests/test_schedulers.py +74 -0
- torchsonn-0.1.0/tests/test_trainer.py +330 -0
- torchsonn-0.1.0/tests/test_trainer_smoke.py +397 -0
- torchsonn-0.1.0/tests/test_types.py +96 -0
- torchsonn-0.1.0/tests/test_utils.py +79 -0
torchsonn-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Konstantin Kolokolov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
torchsonn-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: torchsonn
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Self-organizing polynomial neural network on PyTorch.
|
|
5
|
+
Author: Konstantin Kolokolov
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/kvoyager/torchsonn
|
|
8
|
+
Project-URL: Repository, https://github.com/kvoyager/torchsonn
|
|
9
|
+
Project-URL: Issues, https://github.com/kvoyager/torchsonn/issues
|
|
10
|
+
Keywords: gmdh,group-method-of-data-handling,polynomial-neural-network,pytorch,self-organizing
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: hydra-core>=1.3
|
|
21
|
+
Requires-Dist: torch
|
|
22
|
+
Requires-Dist: numpy
|
|
23
|
+
Requires-Dist: scikit-learn
|
|
24
|
+
Requires-Dist: tqdm
|
|
25
|
+
Requires-Dist: omegaconf
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-cov>=5; extra == "test"
|
|
29
|
+
Requires-Dist: pandas; extra == "test"
|
|
30
|
+
Requires-Dist: torchsonn[viz]; extra == "test"
|
|
31
|
+
Provides-Extra: viz
|
|
32
|
+
Requires-Dist: graphviz; extra == "viz"
|
|
33
|
+
Requires-Dist: matplotlib; extra == "viz"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# TorchSONN
|
|
37
|
+
|
|
38
|
+
TorchSONN is a Python library implementing a self-organizing polynomial
|
|
39
|
+
neural network built on PyTorch. Layers of polynomial neurons are grown one
|
|
40
|
+
at a time; each layer tries every pair of the previous layer's outputs
|
|
41
|
+
against a small set of reference polynomials (`linear`, `linear_cov`,
|
|
42
|
+
`quadratic`, `cubic`, multi-input `polyquad`) and keeps the top-k that
|
|
43
|
+
minimize a validation criterion. Training stops automatically when adding a
|
|
44
|
+
layer no longer reduces the criterion error.
|
|
45
|
+
|
|
46
|
+
It is a GPU-accelerated extension of
|
|
47
|
+
[GmdhPy](https://github.com/kvoyager/GmdhPy), an earlier scikit-learn-style
|
|
48
|
+
library implementing the iterative Group Method of Data Handling (GMDH).
|
|
49
|
+
TorchSONN reimplements the same self-organizing algorithm on PyTorch,
|
|
50
|
+
bringing GPU acceleration to model training and inference.
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install torchsonn
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Plotting is opt-in via the `viz` extra, which adds `graphviz` (for the
|
|
59
|
+
`torchsonn.plot_model` network diagrams) and `matplotlib` (for
|
|
60
|
+
`SONN.plot_layer_error`):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install "torchsonn[viz]"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`graphviz` additionally requires the system Graphviz binaries — `dot` must be
|
|
67
|
+
on your `PATH` (see [graphviz.org/download](https://graphviz.org/download/)).
|
|
68
|
+
Training and inference work without any of this.
|
|
69
|
+
|
|
70
|
+
For development, clone the repo and install editably:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git clone https://github.com/kvoyager/torchsonn.git
|
|
74
|
+
cd torchsonn
|
|
75
|
+
pip install -e ".[test]"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Requires Python 3.12+.
|
|
79
|
+
|
|
80
|
+
## Quickstart
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import numpy as np
|
|
84
|
+
from omegaconf import OmegaConf
|
|
85
|
+
from sklearn.datasets import fetch_california_housing
|
|
86
|
+
from sklearn.preprocessing import StandardScaler
|
|
87
|
+
from torch.utils.data import DataLoader
|
|
88
|
+
|
|
89
|
+
from torchsonn import SONN, SONNDataset, Trainer
|
|
90
|
+
|
|
91
|
+
# California housing regression — 8 features, target in units of $100k.
|
|
92
|
+
housing = fetch_california_housing()
|
|
93
|
+
x = housing.data.astype(np.float32)
|
|
94
|
+
y = housing.target.astype(np.float32)
|
|
95
|
+
feature_names = list(housing.feature_names)
|
|
96
|
+
|
|
97
|
+
# 50/25/25 train/dev/test split; z-score features on the train split only.
|
|
98
|
+
n = x.shape[0]
|
|
99
|
+
i_train, i_dev = int(0.50 * n), int(0.75 * n)
|
|
100
|
+
scaler = StandardScaler().fit(x[:i_train])
|
|
101
|
+
|
|
102
|
+
train_ds = SONNDataset(scaler.transform(x[:i_train]), y[:i_train])
|
|
103
|
+
dev_ds = SONNDataset(scaler.transform(x[i_train:i_dev]), y[i_train:i_dev])
|
|
104
|
+
test_ds = SONNDataset(scaler.transform(x[i_dev:]), y[i_dev:])
|
|
105
|
+
|
|
106
|
+
train_dl = DataLoader(train_ds, batch_size=8192, shuffle=True)
|
|
107
|
+
dev_dl = DataLoader(dev_ds, batch_size=8192)
|
|
108
|
+
test_dl = DataLoader(test_ds, batch_size=8192)
|
|
109
|
+
|
|
110
|
+
# Override only what differs from the schema defaults — everything else
|
|
111
|
+
# comes from torchsonn.config.SONNConfig.
|
|
112
|
+
config = OmegaConf.merge(
|
|
113
|
+
SONN.default_config(),
|
|
114
|
+
OmegaConf.create({
|
|
115
|
+
"model": {
|
|
116
|
+
"type": "regressor",
|
|
117
|
+
"ref_functions": ["linear_cov"],
|
|
118
|
+
"nbest_neurons": 8,
|
|
119
|
+
"max_neuron_models": 28,
|
|
120
|
+
"shortcut": True,
|
|
121
|
+
"output_clamp_value": 1e6,
|
|
122
|
+
},
|
|
123
|
+
"train": {
|
|
124
|
+
"criterion_type": "validate",
|
|
125
|
+
"max_layer_count": 10,
|
|
126
|
+
"optimizer": {"name": "lbfgs",
|
|
127
|
+
"optimizer_params": {"lr": 0.1, "history_size": 10}},
|
|
128
|
+
"steps": 500,
|
|
129
|
+
"batch_size": 8192,
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
model = SONN(config, d_model=x.shape[1], feature_names=feature_names)
|
|
135
|
+
trainer = Trainer(config, feature_names=feature_names)
|
|
136
|
+
trainer.set_seed(config.train.seed)
|
|
137
|
+
trainer.train(model, train_dl, dev_dl, test_dl)
|
|
138
|
+
|
|
139
|
+
trainer.load_model_checkpoint(model, "cpu")
|
|
140
|
+
|
|
141
|
+
# Collapse the ensemble to its single best-error path so inference returns
|
|
142
|
+
# one prediction per sample.
|
|
143
|
+
trainer.prune(model)
|
|
144
|
+
|
|
145
|
+
preds, targets = trainer.infer(model, test_dl)
|
|
146
|
+
preds = preds.reshape(-1)
|
|
147
|
+
mse = ((preds - targets) ** 2).mean().item()
|
|
148
|
+
mae = (preds - targets).abs().mean().item()
|
|
149
|
+
print(f"test MSE: {mse:.4f} MAE: {mae:.4f}")
|
|
150
|
+
print(f"features used: {model.get_selected_features()}")
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Tutorials
|
|
154
|
+
|
|
155
|
+
Four end-to-end examples live under `tutorials/`, each with every config
|
|
156
|
+
key overridable on the command line:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Iris classification — multi-class with soft binner, polyquad neurons.
|
|
160
|
+
python -m tutorials.iris.iris_recognition
|
|
161
|
+
|
|
162
|
+
# California housing regression — gmdhpy-equivalent setup with LBFGS.
|
|
163
|
+
python -m tutorials.california_housing.california_housing
|
|
164
|
+
|
|
165
|
+
# UCI Concrete compressive-strength regression — reports MSE / MAE / R².
|
|
166
|
+
python -m tutorials.concrete.concrete
|
|
167
|
+
|
|
168
|
+
# Otto Group product classification — multi-class log loss, out_proj fine-tune.
|
|
169
|
+
python tutorials/otto/otto_classification.py
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Hydra overrides work on any field in the schema. A few useful ones:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Resume from the last checkpoint
|
|
176
|
+
python -m tutorials.iris.iris_recognition resume=true
|
|
177
|
+
|
|
178
|
+
# Swap optimizer + tune its kwargs
|
|
179
|
+
python -m tutorials.california_housing.california_housing \
|
|
180
|
+
train.optimizer.name=adam \
|
|
181
|
+
train.optimizer.optimizer_params.lr=5e-3
|
|
182
|
+
|
|
183
|
+
# Redirect Hydra's per-run output directory
|
|
184
|
+
python -m tutorials.iris.iris_recognition hydra.run.dir=/tmp/sonn_run
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The iris and otto tutorials also ship notebook versions
|
|
188
|
+
(`tutorials/iris/iris_recognition.ipynb` and `tutorials/otto/otto.ipynb`)
|
|
189
|
+
that render the layer-error curve, the confusion matrix, and the graphviz
|
|
190
|
+
network diagrams inline.
|
|
191
|
+
|
|
192
|
+
Every tutorial except `tutorials/otto/otto_classification.py` plots its
|
|
193
|
+
results, so they need the `[viz]` extra — iris, california_housing, and
|
|
194
|
+
concrete render network diagrams (graphviz), and iris plus both notebooks
|
|
195
|
+
call `SONN.plot_layer_error` (matplotlib). The otto script runs on a base
|
|
196
|
+
install.
|
|
197
|
+
|
|
198
|
+
## Configuration
|
|
199
|
+
|
|
200
|
+
Defaults are defined as a typed dataclass at
|
|
201
|
+
`torchsonn.config.SONNConfig` (registered with Hydra's `ConfigStore`
|
|
202
|
+
under the name `default`). Tutorial YAMLs use the
|
|
203
|
+
`defaults: [default, _self_]` pattern, so each tutorial's YAML is just
|
|
204
|
+
the diff against the schema. Override hierarchy at compose time:
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
SONNConfig defaults → tutorial YAML → CLI overrides
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Type-checked at compose time: unknown keys and wrong-typed values are
|
|
211
|
+
rejected before any training starts.
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
Released under the MIT License — see [LICENSE](LICENSE) for the full text.
|
|
216
|
+
|
|
217
|
+
## Citation
|
|
218
|
+
|
|
219
|
+
If you use TorchSONN in your research, please cite it as:
|
|
220
|
+
|
|
221
|
+
```bibtex
|
|
222
|
+
@software{kolokolov_torchsonn_2026,
|
|
223
|
+
author = {Kolokolov, Konstantin},
|
|
224
|
+
title = {{TorchSONN}: A {PyTorch} Implementation of the self-organizing polynomial neural network},
|
|
225
|
+
year = {2026},
|
|
226
|
+
version = {0.1.0},
|
|
227
|
+
url = {https://github.com/kvoyager/torchsonn},
|
|
228
|
+
note = {GitHub repository}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# TorchSONN
|
|
2
|
+
|
|
3
|
+
TorchSONN is a Python library implementing a self-organizing polynomial
|
|
4
|
+
neural network built on PyTorch. Layers of polynomial neurons are grown one
|
|
5
|
+
at a time; each layer tries every pair of the previous layer's outputs
|
|
6
|
+
against a small set of reference polynomials (`linear`, `linear_cov`,
|
|
7
|
+
`quadratic`, `cubic`, multi-input `polyquad`) and keeps the top-k that
|
|
8
|
+
minimize a validation criterion. Training stops automatically when adding a
|
|
9
|
+
layer no longer reduces the criterion error.
|
|
10
|
+
|
|
11
|
+
It is a GPU-accelerated extension of
|
|
12
|
+
[GmdhPy](https://github.com/kvoyager/GmdhPy), an earlier scikit-learn-style
|
|
13
|
+
library implementing the iterative Group Method of Data Handling (GMDH).
|
|
14
|
+
TorchSONN reimplements the same self-organizing algorithm on PyTorch,
|
|
15
|
+
bringing GPU acceleration to model training and inference.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install torchsonn
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Plotting is opt-in via the `viz` extra, which adds `graphviz` (for the
|
|
24
|
+
`torchsonn.plot_model` network diagrams) and `matplotlib` (for
|
|
25
|
+
`SONN.plot_layer_error`):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install "torchsonn[viz]"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`graphviz` additionally requires the system Graphviz binaries — `dot` must be
|
|
32
|
+
on your `PATH` (see [graphviz.org/download](https://graphviz.org/download/)).
|
|
33
|
+
Training and inference work without any of this.
|
|
34
|
+
|
|
35
|
+
For development, clone the repo and install editably:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/kvoyager/torchsonn.git
|
|
39
|
+
cd torchsonn
|
|
40
|
+
pip install -e ".[test]"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Requires Python 3.12+.
|
|
44
|
+
|
|
45
|
+
## Quickstart
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import numpy as np
|
|
49
|
+
from omegaconf import OmegaConf
|
|
50
|
+
from sklearn.datasets import fetch_california_housing
|
|
51
|
+
from sklearn.preprocessing import StandardScaler
|
|
52
|
+
from torch.utils.data import DataLoader
|
|
53
|
+
|
|
54
|
+
from torchsonn import SONN, SONNDataset, Trainer
|
|
55
|
+
|
|
56
|
+
# California housing regression — 8 features, target in units of $100k.
|
|
57
|
+
housing = fetch_california_housing()
|
|
58
|
+
x = housing.data.astype(np.float32)
|
|
59
|
+
y = housing.target.astype(np.float32)
|
|
60
|
+
feature_names = list(housing.feature_names)
|
|
61
|
+
|
|
62
|
+
# 50/25/25 train/dev/test split; z-score features on the train split only.
|
|
63
|
+
n = x.shape[0]
|
|
64
|
+
i_train, i_dev = int(0.50 * n), int(0.75 * n)
|
|
65
|
+
scaler = StandardScaler().fit(x[:i_train])
|
|
66
|
+
|
|
67
|
+
train_ds = SONNDataset(scaler.transform(x[:i_train]), y[:i_train])
|
|
68
|
+
dev_ds = SONNDataset(scaler.transform(x[i_train:i_dev]), y[i_train:i_dev])
|
|
69
|
+
test_ds = SONNDataset(scaler.transform(x[i_dev:]), y[i_dev:])
|
|
70
|
+
|
|
71
|
+
train_dl = DataLoader(train_ds, batch_size=8192, shuffle=True)
|
|
72
|
+
dev_dl = DataLoader(dev_ds, batch_size=8192)
|
|
73
|
+
test_dl = DataLoader(test_ds, batch_size=8192)
|
|
74
|
+
|
|
75
|
+
# Override only what differs from the schema defaults — everything else
|
|
76
|
+
# comes from torchsonn.config.SONNConfig.
|
|
77
|
+
config = OmegaConf.merge(
|
|
78
|
+
SONN.default_config(),
|
|
79
|
+
OmegaConf.create({
|
|
80
|
+
"model": {
|
|
81
|
+
"type": "regressor",
|
|
82
|
+
"ref_functions": ["linear_cov"],
|
|
83
|
+
"nbest_neurons": 8,
|
|
84
|
+
"max_neuron_models": 28,
|
|
85
|
+
"shortcut": True,
|
|
86
|
+
"output_clamp_value": 1e6,
|
|
87
|
+
},
|
|
88
|
+
"train": {
|
|
89
|
+
"criterion_type": "validate",
|
|
90
|
+
"max_layer_count": 10,
|
|
91
|
+
"optimizer": {"name": "lbfgs",
|
|
92
|
+
"optimizer_params": {"lr": 0.1, "history_size": 10}},
|
|
93
|
+
"steps": 500,
|
|
94
|
+
"batch_size": 8192,
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
model = SONN(config, d_model=x.shape[1], feature_names=feature_names)
|
|
100
|
+
trainer = Trainer(config, feature_names=feature_names)
|
|
101
|
+
trainer.set_seed(config.train.seed)
|
|
102
|
+
trainer.train(model, train_dl, dev_dl, test_dl)
|
|
103
|
+
|
|
104
|
+
trainer.load_model_checkpoint(model, "cpu")
|
|
105
|
+
|
|
106
|
+
# Collapse the ensemble to its single best-error path so inference returns
|
|
107
|
+
# one prediction per sample.
|
|
108
|
+
trainer.prune(model)
|
|
109
|
+
|
|
110
|
+
preds, targets = trainer.infer(model, test_dl)
|
|
111
|
+
preds = preds.reshape(-1)
|
|
112
|
+
mse = ((preds - targets) ** 2).mean().item()
|
|
113
|
+
mae = (preds - targets).abs().mean().item()
|
|
114
|
+
print(f"test MSE: {mse:.4f} MAE: {mae:.4f}")
|
|
115
|
+
print(f"features used: {model.get_selected_features()}")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Tutorials
|
|
119
|
+
|
|
120
|
+
Four end-to-end examples live under `tutorials/`, each with every config
|
|
121
|
+
key overridable on the command line:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Iris classification — multi-class with soft binner, polyquad neurons.
|
|
125
|
+
python -m tutorials.iris.iris_recognition
|
|
126
|
+
|
|
127
|
+
# California housing regression — gmdhpy-equivalent setup with LBFGS.
|
|
128
|
+
python -m tutorials.california_housing.california_housing
|
|
129
|
+
|
|
130
|
+
# UCI Concrete compressive-strength regression — reports MSE / MAE / R².
|
|
131
|
+
python -m tutorials.concrete.concrete
|
|
132
|
+
|
|
133
|
+
# Otto Group product classification — multi-class log loss, out_proj fine-tune.
|
|
134
|
+
python tutorials/otto/otto_classification.py
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Hydra overrides work on any field in the schema. A few useful ones:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Resume from the last checkpoint
|
|
141
|
+
python -m tutorials.iris.iris_recognition resume=true
|
|
142
|
+
|
|
143
|
+
# Swap optimizer + tune its kwargs
|
|
144
|
+
python -m tutorials.california_housing.california_housing \
|
|
145
|
+
train.optimizer.name=adam \
|
|
146
|
+
train.optimizer.optimizer_params.lr=5e-3
|
|
147
|
+
|
|
148
|
+
# Redirect Hydra's per-run output directory
|
|
149
|
+
python -m tutorials.iris.iris_recognition hydra.run.dir=/tmp/sonn_run
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The iris and otto tutorials also ship notebook versions
|
|
153
|
+
(`tutorials/iris/iris_recognition.ipynb` and `tutorials/otto/otto.ipynb`)
|
|
154
|
+
that render the layer-error curve, the confusion matrix, and the graphviz
|
|
155
|
+
network diagrams inline.
|
|
156
|
+
|
|
157
|
+
Every tutorial except `tutorials/otto/otto_classification.py` plots its
|
|
158
|
+
results, so they need the `[viz]` extra — iris, california_housing, and
|
|
159
|
+
concrete render network diagrams (graphviz), and iris plus both notebooks
|
|
160
|
+
call `SONN.plot_layer_error` (matplotlib). The otto script runs on a base
|
|
161
|
+
install.
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
Defaults are defined as a typed dataclass at
|
|
166
|
+
`torchsonn.config.SONNConfig` (registered with Hydra's `ConfigStore`
|
|
167
|
+
under the name `default`). Tutorial YAMLs use the
|
|
168
|
+
`defaults: [default, _self_]` pattern, so each tutorial's YAML is just
|
|
169
|
+
the diff against the schema. Override hierarchy at compose time:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
SONNConfig defaults → tutorial YAML → CLI overrides
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Type-checked at compose time: unknown keys and wrong-typed values are
|
|
176
|
+
rejected before any training starts.
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
Released under the MIT License — see [LICENSE](LICENSE) for the full text.
|
|
181
|
+
|
|
182
|
+
## Citation
|
|
183
|
+
|
|
184
|
+
If you use TorchSONN in your research, please cite it as:
|
|
185
|
+
|
|
186
|
+
```bibtex
|
|
187
|
+
@software{kolokolov_torchsonn_2026,
|
|
188
|
+
author = {Kolokolov, Konstantin},
|
|
189
|
+
title = {{TorchSONN}: A {PyTorch} Implementation of the self-organizing polynomial neural network},
|
|
190
|
+
year = {2026},
|
|
191
|
+
version = {0.1.0},
|
|
192
|
+
url = {https://github.com/kvoyager/torchsonn},
|
|
193
|
+
note = {GitHub repository}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "torchsonn"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Self-organizing polynomial neural network on PyTorch."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Konstantin Kolokolov" },
|
|
14
|
+
]
|
|
15
|
+
requires-python = ">=3.12"
|
|
16
|
+
keywords = [
|
|
17
|
+
"gmdh",
|
|
18
|
+
"group-method-of-data-handling",
|
|
19
|
+
"polynomial-neural-network",
|
|
20
|
+
"pytorch",
|
|
21
|
+
"self-organizing",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 3 - Alpha",
|
|
25
|
+
"Intended Audience :: Science/Research",
|
|
26
|
+
"Programming Language :: Python :: 3",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
]
|
|
31
|
+
dependencies = [
|
|
32
|
+
"hydra-core>=1.3",
|
|
33
|
+
"torch",
|
|
34
|
+
"numpy",
|
|
35
|
+
"scikit-learn",
|
|
36
|
+
"tqdm",
|
|
37
|
+
"omegaconf",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
test = [
|
|
42
|
+
"pytest>=8",
|
|
43
|
+
"pytest-cov>=5",
|
|
44
|
+
"pandas",
|
|
45
|
+
# test_plot_model.py imports torchsonn.plot_model; test_model.py exercises
|
|
46
|
+
# SONN.plot_layer_error.
|
|
47
|
+
"torchsonn[viz]",
|
|
48
|
+
]
|
|
49
|
+
# Plotting-only, and each reached from exactly one call site: `graphviz` from
|
|
50
|
+
# torchsonn.plot_model (an opt-in module), `matplotlib` from
|
|
51
|
+
# SONN.plot_layer_error (imported inside the method so the base install stays
|
|
52
|
+
# importable). graphviz is also inert without the system Graphviz binaries
|
|
53
|
+
# (`dot` on PATH) — a common install snag. Keeping both out of the base
|
|
54
|
+
# dependency set means a plain `pip install torchsonn` can't fail on them.
|
|
55
|
+
viz = [
|
|
56
|
+
"graphviz",
|
|
57
|
+
"matplotlib",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[project.urls]
|
|
61
|
+
Homepage = "https://github.com/kvoyager/torchsonn"
|
|
62
|
+
Repository = "https://github.com/kvoyager/torchsonn"
|
|
63
|
+
Issues = "https://github.com/kvoyager/torchsonn/issues"
|
|
64
|
+
|
|
65
|
+
[tool.setuptools.packages.find]
|
|
66
|
+
where = ["src"]
|
|
67
|
+
# `where=["src"]` makes setuptools scan inside src/ instead of the project
|
|
68
|
+
# root, picking up `torchsonn` + every subpackage (config, data, loss,
|
|
69
|
+
# modules, neurons, optimizers, schedulers). Without this hint, auto-
|
|
70
|
+
# discovery falls back to flat-layout rules and errors out because tests/
|
|
71
|
+
# and tutorials/ also have __init__.py.
|
|
72
|
+
|
|
73
|
+
[tool.pytest.ini_options]
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
addopts = "-q"
|
|
76
|
+
filterwarnings = [
|
|
77
|
+
"ignore::DeprecationWarning",
|
|
78
|
+
"ignore::UserWarning",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[tool.coverage.run]
|
|
82
|
+
source = ["torchsonn"]
|
|
83
|
+
omit = [
|
|
84
|
+
"*/tutorials/*",
|
|
85
|
+
"*/tests/*",
|
|
86
|
+
]
|
|
87
|
+
branch = false
|
|
88
|
+
|
|
89
|
+
[tool.coverage.report]
|
|
90
|
+
exclude_lines = [
|
|
91
|
+
"pragma: no cover",
|
|
92
|
+
"raise NotImplementedError",
|
|
93
|
+
"if __name__ == .__main__.:",
|
|
94
|
+
"if TYPE_CHECKING:",
|
|
95
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""TorchSONN — self-organizing polynomial neural network on PyTorch.
|
|
2
|
+
|
|
3
|
+
Everything needed for a full train / infer loop is re-exported here:
|
|
4
|
+
|
|
5
|
+
from torchsonn import SONN, SONNConfig, SONNDataset, Trainer
|
|
6
|
+
|
|
7
|
+
`PlotModel` is deliberately *not* re-exported: it pulls in the optional
|
|
8
|
+
`graphviz` dependency (``pip install "torchsonn[viz]"``), which would make a
|
|
9
|
+
bare `import torchsonn` fail on a base install. It stays reachable as
|
|
10
|
+
`from torchsonn.plot_model import PlotModel`.
|
|
11
|
+
"""
|
|
12
|
+
from torchsonn.config import SONNConfig
|
|
13
|
+
from torchsonn.data.dataset import SONNDataset
|
|
14
|
+
from torchsonn.model import SONN
|
|
15
|
+
from torchsonn.trainer import Trainer
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"SONN",
|
|
20
|
+
"SONNConfig",
|
|
21
|
+
"SONNDataset",
|
|
22
|
+
"Trainer",
|
|
23
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Hydra-structured config schemas for SONN.
|
|
2
|
+
|
|
3
|
+
Importing this package triggers `ConfigStore.store(name="default", node=SONNConfig)`,
|
|
4
|
+
so any subsequent `@hydra.main` / `hydra.compose` call that references
|
|
5
|
+
`- default` in its `defaults:` list resolves to the typed dataclass below.
|
|
6
|
+
"""
|
|
7
|
+
from torchsonn.config.schemas import (
|
|
8
|
+
ModelConfig,
|
|
9
|
+
OptimizerConfig,
|
|
10
|
+
SchedulerConfig,
|
|
11
|
+
SONNConfig,
|
|
12
|
+
TrainConfig,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"ModelConfig",
|
|
18
|
+
"OptimizerConfig",
|
|
19
|
+
"SchedulerConfig",
|
|
20
|
+
"SONNConfig",
|
|
21
|
+
"TrainConfig",
|
|
22
|
+
]
|