regnets 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.
- regnets-0.1.0/LICENSE +21 -0
- regnets-0.1.0/PKG-INFO +232 -0
- regnets-0.1.0/README.md +212 -0
- regnets-0.1.0/pyproject.toml +51 -0
- regnets-0.1.0/setup.cfg +4 -0
- regnets-0.1.0/src/_kernel_ops.py +144 -0
- regnets-0.1.0/src/kernels.py +270 -0
- regnets-0.1.0/src/modular.py +272 -0
- regnets-0.1.0/src/regnets.egg-info/PKG-INFO +232 -0
- regnets-0.1.0/src/regnets.egg-info/SOURCES.txt +22 -0
- regnets-0.1.0/src/regnets.egg-info/dependency_links.txt +1 -0
- regnets-0.1.0/src/regnets.egg-info/requires.txt +3 -0
- regnets-0.1.0/src/regnets.egg-info/top_level.txt +4 -0
- regnets-0.1.0/src/topology/__init__.py +5 -0
- regnets-0.1.0/src/topology/core.py +176 -0
- regnets-0.1.0/src/topology/graph.py +445 -0
- regnets-0.1.0/src/topology/io.py +125 -0
- regnets-0.1.0/src/topology/lib.py +90 -0
- regnets-0.1.0/src/topology/viz.py +304 -0
- regnets-0.1.0/tests/test_modular.py +657 -0
- regnets-0.1.0/tests/test_topology.py +315 -0
- regnets-0.1.0/tests/test_topology_explorer.py +305 -0
- regnets-0.1.0/tests/test_topology_io.py +79 -0
- regnets-0.1.0/tests/test_topology_viz.py +365 -0
regnets-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ivan Slepovichev
|
|
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.
|
regnets-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: regnets
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Topology and PyTorch models for self-similar modular neural networks
|
|
5
|
+
Author: Ivan Slepovichev
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Repository, https://gitverse.ru/gurgutan/self-similar-nets
|
|
8
|
+
Project-URL: Documentation, https://gitverse.ru/gurgutan/self-similar-nets
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
13
|
+
Requires-Python: >=3.13
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: matplotlib>=3.10.7
|
|
17
|
+
Requires-Dist: networkx>=3.6.1
|
|
18
|
+
Requires-Dist: torch>=2.11.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# Regnets — самоподобные сети
|
|
22
|
+
|
|
23
|
+
Regnets задаёт топологию модульных нейронных сетей числовыми словами, строит
|
|
24
|
+
перестановки контактов и вычисляет самоподобные сети в PyTorch. Топологию можно
|
|
25
|
+
сохранить в JSON и визуализировать в SVG или PNG.
|
|
26
|
+
|
|
27
|
+
Построение топологий и чтение JSON используют только стандартную библиотеку
|
|
28
|
+
Python; вычисление выходов выполняет модуль `modular`, статическую визуализацию —
|
|
29
|
+
`topology.viz` через Matplotlib. При установке пакета зависимости PyTorch,
|
|
30
|
+
Matplotlib и NetworkX устанавливаются вместе с ним.
|
|
31
|
+
|
|
32
|
+
## Установка
|
|
33
|
+
|
|
34
|
+
Требуется Python 3.13 или новее. После публикации пакета на PyPI:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python -m pip install regnets
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Быстрый старт
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from topology.lib import cooley_tukey
|
|
44
|
+
|
|
45
|
+
topology = cooley_tukey((2, 2, 2))
|
|
46
|
+
permutations = topology.permutations()
|
|
47
|
+
print(len(permutations)) # 4
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Основные модули: `topology` — построение и сохранение топологий, `modular` и
|
|
51
|
+
`kernels` — модели и ядра PyTorch, `topology.viz` — визуализация.
|
|
52
|
+
Исходный код и подробная документация доступны в
|
|
53
|
+
[репозитории проекта](https://gitverse.ru/gurgutan/self-similar-nets).
|
|
54
|
+
Лицензия проекта — [MIT](https://gitverse.ru/gurgutan/self-similar-nets/content/master/LICENSE).
|
|
55
|
+
|
|
56
|
+
## Топология
|
|
57
|
+
|
|
58
|
+
Теоретические материалы по модульным сетям: [dorogov.su](http://dorogov.su/).
|
|
59
|
+
|
|
60
|
+
**Основной формат хранения и обмена топологиями — JSON версии 1**:
|
|
61
|
+
числовые слова `words`, размерности входов `p` и выходов `g` каждого слоя,
|
|
62
|
+
свободное имя и признак двойственности. Полное описание полей, пример и правила
|
|
63
|
+
проверки закреплены в [документе дизайна](https://gitverse.ru/gurgutan/self-similar-nets/content/master/DESIGN.md).
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from topology.lib import cooley_tukey, good, haar
|
|
67
|
+
|
|
68
|
+
p = (2,) * 10 # 1024 входа, десять слоёв
|
|
69
|
+
topology = cooley_tukey(p)
|
|
70
|
+
permutations = topology.permutations()
|
|
71
|
+
|
|
72
|
+
good_topology = good(p)
|
|
73
|
+
haar_topology = haar(p)
|
|
74
|
+
frequency_topology = cooley_tukey(p, decimation="frequency")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Стандартные функции возвращают объект `Topology` со словами и размерностями
|
|
78
|
+
модулей. Число слоёв определяется длиной `p`. Если `g` не указано, выходная
|
|
79
|
+
размерность каждого модуля равна его входной размерности.
|
|
80
|
+
|
|
81
|
+
Топологию можно создать вручную:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from topology import Topology
|
|
85
|
+
|
|
86
|
+
topology = Topology(
|
|
87
|
+
[
|
|
88
|
+
[1, 2, 3],
|
|
89
|
+
[-1, 2, 3],
|
|
90
|
+
[-1, -2, 3],
|
|
91
|
+
[-1, -2, -3],
|
|
92
|
+
],
|
|
93
|
+
p=(2, 2, 2),
|
|
94
|
+
)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Положительное число `i + 1` обозначает `u_i`, отрицательное `-(i + 1)` — `v_i`.
|
|
98
|
+
Первый элемент слова соответствует младшему разряду. Для `n` слоёв задаётся
|
|
99
|
+
`n + 1` слов; выходное поле предыдущего слоя совпадает со входным полем следующего.
|
|
100
|
+
|
|
101
|
+
Подробные соглашения, примеры индексов и границы поддерживаемых схем описаны
|
|
102
|
+
в [описании модуля топологии](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/topology.md).
|
|
103
|
+
|
|
104
|
+
## Сохранение и загрузка топологии
|
|
105
|
+
|
|
106
|
+
Топологию и размерности модулей можно сохранить в JSON-файл и затем загрузить:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from topology.io import load_topology, save_topology
|
|
110
|
+
from topology.lib import cooley_tukey
|
|
111
|
+
|
|
112
|
+
p = (2, 2, 2)
|
|
113
|
+
g = (2, 2, 2)
|
|
114
|
+
topology = cooley_tukey(p, g=g)
|
|
115
|
+
path = save_topology(topology, "topology.json", name="Моя топология")
|
|
116
|
+
loaded = load_topology(path)
|
|
117
|
+
assert loaded.name == "Моя топология"
|
|
118
|
+
assert loaded.topology == topology
|
|
119
|
+
assert (loaded.topology.p, loaded.topology.g) == (p, g)
|
|
120
|
+
permutations = loaded.topology.permutations()
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`name` — произвольное имя, которое не влияет на связи. `save_topology`
|
|
124
|
+
записывает JSON версии 1 в UTF-8, перезаписывает существующий файл и
|
|
125
|
+
возвращает путь к нему. `load_topology` проверяет файл и возвращает
|
|
126
|
+
спецификацию с топологией и её метаданными.
|
|
127
|
+
Если передать сохранению эту спецификацию, исходные имя и флаг `dual`
|
|
128
|
+
сохранятся; необязательный `name` позволяет заменить имя. При сохранении
|
|
129
|
+
самого `Topology` записывается его текущее состояние с `dual: false`.
|
|
130
|
+
Файл не содержит весов нейронной сети.
|
|
131
|
+
|
|
132
|
+
## Модель PyTorch
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from modular import ModularNet, Layer
|
|
136
|
+
from kernels import MLP
|
|
137
|
+
from topology.lib import cooley_tukey
|
|
138
|
+
|
|
139
|
+
net = ModularNet(
|
|
140
|
+
cooley_tukey((2,) * 8),
|
|
141
|
+
layers=Layer(kernel=MLP(hidden=(64, 32)), shared=False, residual=True, in_size=16),
|
|
142
|
+
device="cpu",
|
|
143
|
+
)
|
|
144
|
+
# net(x): [..., 256, 16] → [..., 256, 16]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`shared=True` разделяет параметры между позициями внутри слоя;
|
|
148
|
+
`shared=False` хранит независимые параметры упакованными тензорами.
|
|
149
|
+
Вычисления всех позиций выполняются пакетно. Параметры разных слоёв независимы.
|
|
150
|
+
Для скалярных контактов пропустите `in_size`; для разных слоёв передайте список `Layer`.
|
|
151
|
+
Описание блоков, остаточных связей и сохранения: [вычислительная модель](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/modular-nn.md).
|
|
152
|
+
|
|
153
|
+
Исполняемый пример одного синтетического шага обучения на CPU из клонированного
|
|
154
|
+
репозитория (после `uv sync`):
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
CUDA_VISIBLE_DEVICES='' uv run python examples/modular_cpu.py
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## SVG и PNG из JSON
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from topology.viz import render_topology
|
|
164
|
+
|
|
165
|
+
render_topology("topology.json") # создаёт topology.svg рядом с JSON
|
|
166
|
+
render_topology("topology.json", "network.png", mode="modules")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Отдельная утилита командной строки из клонированного репозитория:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
uv run python tools/render_topology.py examples/topology.json -o build/topology.svg
|
|
173
|
+
uv run python tools/render_topology.py examples/topology.json -m modules -o build/modules.png
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
По умолчанию рисуются контакты; `-m modules` выбирает модули.
|
|
177
|
+
Формат выбирается расширением `.svg` или `.png`, `--dpi` задаёт разрешение PNG.
|
|
178
|
+
Web App и экспорт используют одно построение графа; браузер для экспорта не нужен.
|
|
179
|
+
Подробности: [модуль визуализации и CLI](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/topology-viz.md).
|
|
180
|
+
|
|
181
|
+
## Web UI
|
|
182
|
+
|
|
183
|
+
[Открыть визуализатор на GitVerse Pages](https://gurgutan.gitverse.site/self-similar-nets/).
|
|
184
|
+
|
|
185
|
+
Браузерная версия для GitVerse Pages работает без Python-сервера; исходники
|
|
186
|
+
находятся в `apps/topology_pages`. Она сохраняет стандартные и ручные топологии,
|
|
187
|
+
оба представления графа, инспектор, поиск, диапазон слоёв и обмен JSON/PNG.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npm ci
|
|
191
|
+
npm test
|
|
192
|
+
npm run build
|
|
193
|
+
python3 -m http.server 8051 --bind 127.0.0.1 --directory build/pages
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Сборка включает фиксированную версию Cytoscape из npm, общий CSS и базовые
|
|
197
|
+
стили графа из приложения Dash. Обращения к внешнему CDN не нужны.
|
|
198
|
+
Для сборки нужен Python 3.12+ со стандартной библиотекой; зависимости Dash
|
|
199
|
+
и PyTorch не устанавливаются. Проверки `npm test` сравнивают браузерные
|
|
200
|
+
графы с Python для 112 сочетаний схем, размерностей и диапазонов,
|
|
201
|
+
включая двойственные модели.
|
|
202
|
+
Инструкция публикации: [GitVerse Pages](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/gitverse-pages.md).
|
|
203
|
+
|
|
204
|
+
Отдельное приложение на Dash и Dash Cytoscape находится в
|
|
205
|
+
`apps/topology_explorer`. Запуск из корня проекта:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
uv run --group ui python -m apps.topology_explorer
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Откройте <http://127.0.0.1:8050>. По умолчанию показаны все контакты и связи
|
|
212
|
+
сети на 16 входов. Кнопки `16`, `64` и `256` строят соответствующие сети целиком.
|
|
213
|
+
Можно выбрать стандартную схему, изменить размерности ядер, задать собственные
|
|
214
|
+
слова, включить двойственную модель, перейти к контакту по номеру,
|
|
215
|
+
переключиться на модули, сохранить JSON
|
|
216
|
+
или рисунок PNG. Настройки каждого сеанса хранятся в его странице браузера.
|
|
217
|
+
|
|
218
|
+
Порядок работы, формат файлов и ограничения описаны в
|
|
219
|
+
[руководстве визуализатора](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/topology-explorer.md).
|
|
220
|
+
|
|
221
|
+
## Разработка и проверки
|
|
222
|
+
|
|
223
|
+
Исходники находятся в `src`, топологии собраны в пакет `src/topology`.
|
|
224
|
+
После клонирования репозитория создайте окружение командой `uv sync`.
|
|
225
|
+
Проверки выполняются из корня проекта:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
uv run --group ui python -m pytest -q
|
|
229
|
+
uv run --group ui python -m ruff check src apps tests tools examples --extend-select I
|
|
230
|
+
uv run --group ui python -m ruff format --check src apps tests tools examples
|
|
231
|
+
uv run --group ui python -m pyright src apps tests tools examples
|
|
232
|
+
```
|
regnets-0.1.0/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Regnets — самоподобные сети
|
|
2
|
+
|
|
3
|
+
Regnets задаёт топологию модульных нейронных сетей числовыми словами, строит
|
|
4
|
+
перестановки контактов и вычисляет самоподобные сети в PyTorch. Топологию можно
|
|
5
|
+
сохранить в JSON и визуализировать в SVG или PNG.
|
|
6
|
+
|
|
7
|
+
Построение топологий и чтение JSON используют только стандартную библиотеку
|
|
8
|
+
Python; вычисление выходов выполняет модуль `modular`, статическую визуализацию —
|
|
9
|
+
`topology.viz` через Matplotlib. При установке пакета зависимости PyTorch,
|
|
10
|
+
Matplotlib и NetworkX устанавливаются вместе с ним.
|
|
11
|
+
|
|
12
|
+
## Установка
|
|
13
|
+
|
|
14
|
+
Требуется Python 3.13 или новее. После публикации пакета на PyPI:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
python -m pip install regnets
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Быстрый старт
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from topology.lib import cooley_tukey
|
|
24
|
+
|
|
25
|
+
topology = cooley_tukey((2, 2, 2))
|
|
26
|
+
permutations = topology.permutations()
|
|
27
|
+
print(len(permutations)) # 4
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Основные модули: `topology` — построение и сохранение топологий, `modular` и
|
|
31
|
+
`kernels` — модели и ядра PyTorch, `topology.viz` — визуализация.
|
|
32
|
+
Исходный код и подробная документация доступны в
|
|
33
|
+
[репозитории проекта](https://gitverse.ru/gurgutan/self-similar-nets).
|
|
34
|
+
Лицензия проекта — [MIT](https://gitverse.ru/gurgutan/self-similar-nets/content/master/LICENSE).
|
|
35
|
+
|
|
36
|
+
## Топология
|
|
37
|
+
|
|
38
|
+
Теоретические материалы по модульным сетям: [dorogov.su](http://dorogov.su/).
|
|
39
|
+
|
|
40
|
+
**Основной формат хранения и обмена топологиями — JSON версии 1**:
|
|
41
|
+
числовые слова `words`, размерности входов `p` и выходов `g` каждого слоя,
|
|
42
|
+
свободное имя и признак двойственности. Полное описание полей, пример и правила
|
|
43
|
+
проверки закреплены в [документе дизайна](https://gitverse.ru/gurgutan/self-similar-nets/content/master/DESIGN.md).
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from topology.lib import cooley_tukey, good, haar
|
|
47
|
+
|
|
48
|
+
p = (2,) * 10 # 1024 входа, десять слоёв
|
|
49
|
+
topology = cooley_tukey(p)
|
|
50
|
+
permutations = topology.permutations()
|
|
51
|
+
|
|
52
|
+
good_topology = good(p)
|
|
53
|
+
haar_topology = haar(p)
|
|
54
|
+
frequency_topology = cooley_tukey(p, decimation="frequency")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Стандартные функции возвращают объект `Topology` со словами и размерностями
|
|
58
|
+
модулей. Число слоёв определяется длиной `p`. Если `g` не указано, выходная
|
|
59
|
+
размерность каждого модуля равна его входной размерности.
|
|
60
|
+
|
|
61
|
+
Топологию можно создать вручную:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from topology import Topology
|
|
65
|
+
|
|
66
|
+
topology = Topology(
|
|
67
|
+
[
|
|
68
|
+
[1, 2, 3],
|
|
69
|
+
[-1, 2, 3],
|
|
70
|
+
[-1, -2, 3],
|
|
71
|
+
[-1, -2, -3],
|
|
72
|
+
],
|
|
73
|
+
p=(2, 2, 2),
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Положительное число `i + 1` обозначает `u_i`, отрицательное `-(i + 1)` — `v_i`.
|
|
78
|
+
Первый элемент слова соответствует младшему разряду. Для `n` слоёв задаётся
|
|
79
|
+
`n + 1` слов; выходное поле предыдущего слоя совпадает со входным полем следующего.
|
|
80
|
+
|
|
81
|
+
Подробные соглашения, примеры индексов и границы поддерживаемых схем описаны
|
|
82
|
+
в [описании модуля топологии](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/topology.md).
|
|
83
|
+
|
|
84
|
+
## Сохранение и загрузка топологии
|
|
85
|
+
|
|
86
|
+
Топологию и размерности модулей можно сохранить в JSON-файл и затем загрузить:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from topology.io import load_topology, save_topology
|
|
90
|
+
from topology.lib import cooley_tukey
|
|
91
|
+
|
|
92
|
+
p = (2, 2, 2)
|
|
93
|
+
g = (2, 2, 2)
|
|
94
|
+
topology = cooley_tukey(p, g=g)
|
|
95
|
+
path = save_topology(topology, "topology.json", name="Моя топология")
|
|
96
|
+
loaded = load_topology(path)
|
|
97
|
+
assert loaded.name == "Моя топология"
|
|
98
|
+
assert loaded.topology == topology
|
|
99
|
+
assert (loaded.topology.p, loaded.topology.g) == (p, g)
|
|
100
|
+
permutations = loaded.topology.permutations()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`name` — произвольное имя, которое не влияет на связи. `save_topology`
|
|
104
|
+
записывает JSON версии 1 в UTF-8, перезаписывает существующий файл и
|
|
105
|
+
возвращает путь к нему. `load_topology` проверяет файл и возвращает
|
|
106
|
+
спецификацию с топологией и её метаданными.
|
|
107
|
+
Если передать сохранению эту спецификацию, исходные имя и флаг `dual`
|
|
108
|
+
сохранятся; необязательный `name` позволяет заменить имя. При сохранении
|
|
109
|
+
самого `Topology` записывается его текущее состояние с `dual: false`.
|
|
110
|
+
Файл не содержит весов нейронной сети.
|
|
111
|
+
|
|
112
|
+
## Модель PyTorch
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from modular import ModularNet, Layer
|
|
116
|
+
from kernels import MLP
|
|
117
|
+
from topology.lib import cooley_tukey
|
|
118
|
+
|
|
119
|
+
net = ModularNet(
|
|
120
|
+
cooley_tukey((2,) * 8),
|
|
121
|
+
layers=Layer(kernel=MLP(hidden=(64, 32)), shared=False, residual=True, in_size=16),
|
|
122
|
+
device="cpu",
|
|
123
|
+
)
|
|
124
|
+
# net(x): [..., 256, 16] → [..., 256, 16]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`shared=True` разделяет параметры между позициями внутри слоя;
|
|
128
|
+
`shared=False` хранит независимые параметры упакованными тензорами.
|
|
129
|
+
Вычисления всех позиций выполняются пакетно. Параметры разных слоёв независимы.
|
|
130
|
+
Для скалярных контактов пропустите `in_size`; для разных слоёв передайте список `Layer`.
|
|
131
|
+
Описание блоков, остаточных связей и сохранения: [вычислительная модель](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/modular-nn.md).
|
|
132
|
+
|
|
133
|
+
Исполняемый пример одного синтетического шага обучения на CPU из клонированного
|
|
134
|
+
репозитория (после `uv sync`):
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
CUDA_VISIBLE_DEVICES='' uv run python examples/modular_cpu.py
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## SVG и PNG из JSON
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from topology.viz import render_topology
|
|
144
|
+
|
|
145
|
+
render_topology("topology.json") # создаёт topology.svg рядом с JSON
|
|
146
|
+
render_topology("topology.json", "network.png", mode="modules")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Отдельная утилита командной строки из клонированного репозитория:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
uv run python tools/render_topology.py examples/topology.json -o build/topology.svg
|
|
153
|
+
uv run python tools/render_topology.py examples/topology.json -m modules -o build/modules.png
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
По умолчанию рисуются контакты; `-m modules` выбирает модули.
|
|
157
|
+
Формат выбирается расширением `.svg` или `.png`, `--dpi` задаёт разрешение PNG.
|
|
158
|
+
Web App и экспорт используют одно построение графа; браузер для экспорта не нужен.
|
|
159
|
+
Подробности: [модуль визуализации и CLI](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/topology-viz.md).
|
|
160
|
+
|
|
161
|
+
## Web UI
|
|
162
|
+
|
|
163
|
+
[Открыть визуализатор на GitVerse Pages](https://gurgutan.gitverse.site/self-similar-nets/).
|
|
164
|
+
|
|
165
|
+
Браузерная версия для GitVerse Pages работает без Python-сервера; исходники
|
|
166
|
+
находятся в `apps/topology_pages`. Она сохраняет стандартные и ручные топологии,
|
|
167
|
+
оба представления графа, инспектор, поиск, диапазон слоёв и обмен JSON/PNG.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm ci
|
|
171
|
+
npm test
|
|
172
|
+
npm run build
|
|
173
|
+
python3 -m http.server 8051 --bind 127.0.0.1 --directory build/pages
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Сборка включает фиксированную версию Cytoscape из npm, общий CSS и базовые
|
|
177
|
+
стили графа из приложения Dash. Обращения к внешнему CDN не нужны.
|
|
178
|
+
Для сборки нужен Python 3.12+ со стандартной библиотекой; зависимости Dash
|
|
179
|
+
и PyTorch не устанавливаются. Проверки `npm test` сравнивают браузерные
|
|
180
|
+
графы с Python для 112 сочетаний схем, размерностей и диапазонов,
|
|
181
|
+
включая двойственные модели.
|
|
182
|
+
Инструкция публикации: [GitVerse Pages](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/gitverse-pages.md).
|
|
183
|
+
|
|
184
|
+
Отдельное приложение на Dash и Dash Cytoscape находится в
|
|
185
|
+
`apps/topology_explorer`. Запуск из корня проекта:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
uv run --group ui python -m apps.topology_explorer
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Откройте <http://127.0.0.1:8050>. По умолчанию показаны все контакты и связи
|
|
192
|
+
сети на 16 входов. Кнопки `16`, `64` и `256` строят соответствующие сети целиком.
|
|
193
|
+
Можно выбрать стандартную схему, изменить размерности ядер, задать собственные
|
|
194
|
+
слова, включить двойственную модель, перейти к контакту по номеру,
|
|
195
|
+
переключиться на модули, сохранить JSON
|
|
196
|
+
или рисунок PNG. Настройки каждого сеанса хранятся в его странице браузера.
|
|
197
|
+
|
|
198
|
+
Порядок работы, формат файлов и ограничения описаны в
|
|
199
|
+
[руководстве визуализатора](https://gitverse.ru/gurgutan/self-similar-nets/content/master/docs/topology-explorer.md).
|
|
200
|
+
|
|
201
|
+
## Разработка и проверки
|
|
202
|
+
|
|
203
|
+
Исходники находятся в `src`, топологии собраны в пакет `src/topology`.
|
|
204
|
+
После клонирования репозитория создайте окружение командой `uv sync`.
|
|
205
|
+
Проверки выполняются из корня проекта:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
uv run --group ui python -m pytest -q
|
|
209
|
+
uv run --group ui python -m ruff check src apps tests tools examples --extend-select I
|
|
210
|
+
uv run --group ui python -m ruff format --check src apps tests tools examples
|
|
211
|
+
uv run --group ui python -m pyright src apps tests tools examples
|
|
212
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "regnets"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Topology and PyTorch models for self-similar modular neural networks"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Ivan Slepovichev" }]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"matplotlib>=3.10.7",
|
|
22
|
+
"networkx>=3.6.1",
|
|
23
|
+
"torch>=2.11.0",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Repository = "https://gitverse.ru/gurgutan/self-similar-nets"
|
|
28
|
+
Documentation = "https://gitverse.ru/gurgutan/self-similar-nets"
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"ipykernel>=7.2.0",
|
|
33
|
+
"ipywidgets>=8.1.8",
|
|
34
|
+
"pyright>=1.1.408",
|
|
35
|
+
"pytest>=9.0.2",
|
|
36
|
+
"ruff>=0.15.8",
|
|
37
|
+
]
|
|
38
|
+
ui = [
|
|
39
|
+
"dash>=4.4.1",
|
|
40
|
+
"dash-cytoscape>=1.0.2",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[tool.pyright]
|
|
44
|
+
pythonVersion = "3.13"
|
|
45
|
+
venvPath = "."
|
|
46
|
+
venv = ".venv"
|
|
47
|
+
|
|
48
|
+
[tool.setuptools]
|
|
49
|
+
package-dir = {"" = "src"}
|
|
50
|
+
packages = ["topology"]
|
|
51
|
+
py-modules = ["modular", "kernels", "_kernel_ops"]
|
regnets-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""Packed tensor operations used by neural kernel descriptions."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from math import isfinite
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
from torch import Tensor, nn
|
|
8
|
+
from torch.nn import functional as F
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def positive_int(value: int, name: str) -> None:
|
|
12
|
+
"""Отклонить размерности, смысл которых изменился бы при приведении типа."""
|
|
13
|
+
if type(value) is not int or value < 1:
|
|
14
|
+
raise ValueError(f"{name} must be a positive integer.")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def boolean(value: bool, name: str) -> None:
|
|
18
|
+
"""Требовать явно заданное логическое значение."""
|
|
19
|
+
if type(value) is not bool:
|
|
20
|
+
raise ValueError(f"{name} must be a boolean.")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def positive_real(value: float, name: str) -> None:
|
|
24
|
+
"""Проверить, что числовой параметр конечен и положителен."""
|
|
25
|
+
if type(value) not in (int, float) or not isfinite(value) or value <= 0:
|
|
26
|
+
raise ValueError(f"{name} must be positive and finite.")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class KernelShape:
|
|
31
|
+
"""Размерности и правила работы с параметрами для метода build ядра."""
|
|
32
|
+
|
|
33
|
+
in_features: int
|
|
34
|
+
out_features: int
|
|
35
|
+
positions: int
|
|
36
|
+
shared: bool
|
|
37
|
+
device: torch.device | str | None = None
|
|
38
|
+
dtype: torch.dtype | None = None
|
|
39
|
+
|
|
40
|
+
def __post_init__(self) -> None:
|
|
41
|
+
for name in ("in_features", "out_features", "positions"):
|
|
42
|
+
positive_int(getattr(self, name), name)
|
|
43
|
+
boolean(self.shared, "shared")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class PackedLinear(nn.Module):
|
|
47
|
+
"""Применить одно аффинное преобразование параллельно ко всем позициям модулей."""
|
|
48
|
+
|
|
49
|
+
def __init__(self, shape: KernelShape, bias: bool = True) -> None:
|
|
50
|
+
super().__init__()
|
|
51
|
+
self.in_features = shape.in_features
|
|
52
|
+
self.out_features = shape.out_features
|
|
53
|
+
self.positions = shape.positions
|
|
54
|
+
self.shared = shape.shared
|
|
55
|
+
prefix = () if shape.shared else (shape.positions,)
|
|
56
|
+
self.weight = nn.Parameter(
|
|
57
|
+
torch.empty(
|
|
58
|
+
(*prefix, shape.out_features, shape.in_features),
|
|
59
|
+
device=shape.device,
|
|
60
|
+
dtype=shape.dtype,
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
self.bias = (
|
|
64
|
+
nn.Parameter(
|
|
65
|
+
torch.empty(
|
|
66
|
+
(*prefix, shape.out_features),
|
|
67
|
+
device=shape.device,
|
|
68
|
+
dtype=shape.dtype,
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
if bias
|
|
72
|
+
else None
|
|
73
|
+
)
|
|
74
|
+
self.reset_parameters()
|
|
75
|
+
|
|
76
|
+
def reset_parameters(self) -> None:
|
|
77
|
+
"""Инициализировать параметры по локальному числу входов независимо от числа позиций."""
|
|
78
|
+
bound = self.in_features**-0.5
|
|
79
|
+
nn.init.uniform_(self.weight, -bound, bound)
|
|
80
|
+
if self.bias is not None:
|
|
81
|
+
nn.init.uniform_(self.bias, -bound, bound)
|
|
82
|
+
|
|
83
|
+
def forward(self, x: Tensor) -> Tensor:
|
|
84
|
+
"""Преобразовать [..., positions, in_features] без цикла по позициям."""
|
|
85
|
+
if self.shared:
|
|
86
|
+
return F.linear(x, self.weight, self.bias)
|
|
87
|
+
batch_shape = x.shape[:-2]
|
|
88
|
+
matrices = x.reshape(-1, self.positions, self.in_features).transpose(0, 1)
|
|
89
|
+
y = torch.bmm(matrices, self.weight.transpose(1, 2)).transpose(0, 1)
|
|
90
|
+
y = y.reshape(*batch_shape, self.positions, self.out_features)
|
|
91
|
+
return y if self.bias is None else y + self.bias
|
|
92
|
+
|
|
93
|
+
def extra_repr(self) -> str:
|
|
94
|
+
return (
|
|
95
|
+
f"in_features={self.in_features}, out_features={self.out_features}, "
|
|
96
|
+
f"positions={self.positions}, shared={self.shared}, bias={self.bias is not None}"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class PackedNorm(nn.Module):
|
|
101
|
+
"""Нормализовать локальные признаки независимо для позиций и элементов пакета."""
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self, shape: KernelShape, *, rms: bool, eps: float, affine: bool, bias: bool
|
|
105
|
+
) -> None:
|
|
106
|
+
super().__init__()
|
|
107
|
+
self.features = shape.in_features
|
|
108
|
+
self.rms = rms
|
|
109
|
+
self.eps = eps
|
|
110
|
+
dimensions = (
|
|
111
|
+
(shape.in_features,)
|
|
112
|
+
if shape.shared
|
|
113
|
+
else (shape.positions, shape.in_features)
|
|
114
|
+
)
|
|
115
|
+
self.weight = (
|
|
116
|
+
nn.Parameter(torch.ones(dimensions, device=shape.device, dtype=shape.dtype))
|
|
117
|
+
if affine
|
|
118
|
+
else None
|
|
119
|
+
)
|
|
120
|
+
self.bias = (
|
|
121
|
+
nn.Parameter(
|
|
122
|
+
torch.zeros(dimensions, device=shape.device, dtype=shape.dtype)
|
|
123
|
+
)
|
|
124
|
+
if affine and bias
|
|
125
|
+
else None
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def forward(self, x: Tensor) -> Tensor:
|
|
129
|
+
"""Сохранить тип активации, если параметры имеют большую точность."""
|
|
130
|
+
if self.rms:
|
|
131
|
+
y = F.rms_norm(x, (self.features,), eps=self.eps)
|
|
132
|
+
else:
|
|
133
|
+
y = F.layer_norm(x, (self.features,), eps=self.eps)
|
|
134
|
+
if self.weight is not None:
|
|
135
|
+
y = y * self.weight.to(dtype=y.dtype)
|
|
136
|
+
if self.bias is not None:
|
|
137
|
+
y = y + self.bias.to(dtype=y.dtype)
|
|
138
|
+
return y
|
|
139
|
+
|
|
140
|
+
def extra_repr(self) -> str:
|
|
141
|
+
return (
|
|
142
|
+
f"features={self.features}, rms={self.rms}, eps={self.eps}, "
|
|
143
|
+
f"affine={self.weight is not None}, bias={self.bias is not None}"
|
|
144
|
+
)
|