Модели PyTorch
regnets.modular преобразует готовую топологию в обучаемую сеть.
regnets.kernels предоставляет готовые описания ядер и интерфейс Kernel.
Модули топологии используют
только стандартную библиотеку Python и не зависят от вычислительной части.
Использование #
Установка PyTorch #
Вычислительные модули используют необязательную зависимость PyTorch:
python -m pip install 'regnets[torch]'
В клонированном репозитории выполните uv sync --extra torch; команды
вычислительных примеров запускайте через uv run --extra torch python ....
При отсутствии PyTorch импорт regnets.modular или regnets.kernels
выдаёт ImportError с этой командой установки. Остальные ошибки загрузки
PyTorch сохраняются без подмены. Топология и её визуализация доступны
при базовой установке regnets.
Создание сети #
import torch
from torch import nn
from regnets.kernels import Dense
from regnets.modular import Layer, ModularNet
from regnets.topology.lib import cooley_tukey
net = ModularNet(
topology=cooley_tukey((2,) * 8),
layers=Layer(kernel=Dense(activation=nn.SiLU)),
device="cpu",
)
x = torch.randn(4, 256, device="cpu")
y = net(x)
assert y.shape == x.shape
Одно неизменяемое описание Layer распространяется на все слои;
параметры каждого слоя создаются независимо и сразу видны оптимизатору.
p и g принадлежат топологии и задают числа входных и выходных контактов
каждого модуля. Если g пропущено при создании топологии, используется g=p.
Числа контактов всей сети доступны как net.n_inputs и net.n_outputs.
shared=True задаёт общие параметры между позициями модулей одного слоя.
shared=False задаёт независимые параметры каждой позиции. Это относится
также к параметрам нормировки и обучаемой остаточной проекции.
Разные слои имеют независимые параметры при любом режиме.
Векторы на контактах и разные слои #
Layer(..., in_size=None), по умолчанию: скалярные контакты, форма[..., N].Layer(..., in_size=k): векторы на входных контактах слоя. Дажеin_size=1требует явного последнего измерения длины 1:[..., N, 1].out_sizeзадаёт длину вектора на выходных контактах слоя. Если его пропустить, выходной размер равен входному. Размеры должны быть положительными целыми числами.
Размер выходного вектора слоя должен совпадать с входным размером следующего
слоя. При построении сети проверяются все такие пары, включая размеры,
полученные по умолчанию. Сеть использует либо скалярные контакты во всех
слоях, либо векторные; смешивать эти режимы нельзя. Входная и выходная формы
всей сети определяются первым in_size и последним out_size соответственно.
Указание out_size для скалярного входа не поддерживается.
Ведущие пакетные измерения сохраняются. Поддерживаются одиночные примеры, пустые пакеты и неконтинуальные входы. Вход — вещественный тензор PyTorch.
from regnets.kernels import MLP
from regnets.modular import Residual
from regnets.topology.lib import good
net = ModularNet(
good((2, 3, 2), g=(3, 2, 1)),
layers=[
Layer(Dense(activation=nn.SiLU), in_size=8),
Layer(MLP(hidden=(32, 16)), shared=False,
residual=Residual(project=True), in_size=8, out_size=4),
Layer(Dense(bias=False), in_size=4, out_size=2),
],
device="cpu",
)
assert net(torch.randn(4, 12, 8)).shape == (4, 6, 2)
Одно описание Layer можно повторить на всех слоях, если оно сохраняет размер
вектора. Для переходов между размерами задайте совместимые описания слоёв,
как в примере. Для двойственной сети передайте topology.dual(): она
преобразует слова и размерности контактов. Порядок описаний слоёв и их
фактические входные и выходные размеры векторов при необходимости измените
отдельно: сеть не преобразует вычислительные ядра автоматически.
Прежний параметр ModularNet(size=...) удалён: постоянный размер переносится
в Layer(in_size=...), а последовательность размеров — в in_size и out_size
соответствующих слоёв.
Параметры Layer(p=..., g=...) удалены: задайте числа контактов в Topology
или стандартном генераторе и передайте эту топологию в ModularNet.
Блоки ядра #
Все описания создают пакетный nn.Module при конструировании сети.
Параметры не создаются и не собираются заново в forward.
| Блок | Поведение |
|---|---|
Dense() |
Линейное преобразование со смещением; выход выводится из слоя |
Dense(64, bias=False, activation=nn.SiLU) |
Явные 64 локальных выходных признака |
MLP(hidden=(64, 32)) |
Скрытые размеры 64 и 32, вход и выход выводятся из слоя |
Sequential(...) |
Последовательная композиция описаний блоков |
RMSNorm(eps=1e-6, affine=True) |
Нормировка локального среднеквадратичного значения |
LayerNorm(eps=1e-5, affine=True, bias=True) |
Нормировка локального среднего и дисперсии |
Dropout(0.1) |
Независимые маски признаков при обучении, отключён в eval() |
Identity() |
Тождественное преобразование локальных признаков |
GatedMLP(hidden=64) |
Совмещённая проекция в две ветви, SiLU-управление и выходная проекция |
У Dense по умолчанию нет активации. У MLP активация nn.SiLU
следует после скрытых преобразований; output_activation=None оставляет
последнее преобразование линейным. hidden принимает число или последовательность.
Активация задаётся фабрикой без аргументов, например nn.GELU или
lambda: nn.LeakyReLU(0.1). Обучаемую активацию оформляйте отдельным Kernel.
from regnets.kernels import Dropout, RMSNorm, Sequential
kernel = Sequential(
RMSNorm(),
MLP(hidden=(64, 32), activation=nn.SiLU),
Dropout(0.1),
)
net = ModularNet(cooley_tukey((2,) * 8), Layer(kernel=kernel, shared=False,
residual=True, in_size=32), device="cpu")
Нормировка охватывает объединённый локальный вектор входов ядра.
Позиции модулей и объекты пакета в статистике не смешиваются.
В Sequential нормировка, Dropout и Identity сохраняют текущую ширину;
Dense(64) явно устанавливает её, а Dense() и MLP используют выходную
ширину окружающего слоя. Проверяется итоговое число признаков.
Композиции могут быть вложенными.
Остаточная ветвь #
residual=True обходит одно вычислительное ядро слоя и требует
p == g и одинаковых размеров вектора на входе и выходе.
Residual(project=True) добавляет обучаемую локальную линейную проекцию
без смещения; она позволяет менять обе размерности.
Обход минует всё ядро, включая нормировку, MLP и Dropout. Он связывает
локальный вход с соответствующим локальным выходом того же модуля.
Маршрут контактов, заданный объектом Topology, при этом сохраняется.
Методы и атрибуты ModularNet #
| Обращение | Назначение |
|---|---|
net(x) |
Выполнить расчёт для входного тензора |
net.n_inputs, net.n_outputs |
Узнать число входных и выходных контактов |
net.positions |
Узнать число модулей каждого слоя |
net.parameters() |
Получить параметры для оптимизатора |
net.train(), net.eval() |
Выбрать режим обучения или применения |
net.to(...), net.double() |
Изменить устройство или тип параметров |
net.state_dict() |
Получить состояние модели |
net.load_state_dict(state) |
Загрузить совместимое состояние |
net.get_extra_state() |
Получить описание конфигурации |
Состояние и расширение #
optimizer = torch.optim.SGD(net.parameters(), lr=0.01)
loss = net(torch.randn(2, 256, 32)).square().mean()
loss.backward()
optimizer.step()
torch.save(net.state_dict(), "weights.pt")
# Вновь создайте net с той же конфигурацией перед загрузкой.
net.load_state_dict(torch.load("weights.pt", map_location="cpu", weights_only=True))
state_dict сохраняет параметры и конфигурацию в _extra_state. Получить
копию конфигурации можно также через net.get_extra_state(). В ней два раздела:
topologyсодержит тот же словарь JSON версии 1, что иsave_topology. Конструктор получаетTopology, поэтому сохраняется его текущее состояние с пустым именем иdual: false; исходные имя и флагTopologySpecтеряются при передаче только её поляtopology.layersсодержит описание каждого слоя:kernel,shared,residual,in_sizeиout_size. Размеры приведены к фактическим: еслиout_sizeне задан, он равенin_size; скалярным контактам соответствуютNone. Остаточная ветвь записана какnone,identityилиproject.kernelсодержит типы и текстовые описания построенных модулей для проверки весов.
Несовместимая конфигурация вызывает RuntimeError.
Производные индексы не сохраняются: они восстанавливаются конструктором.
to(...), double(), train() и eval() работают стандартным образом.
Конфигурацию конструкции и код собственного ядра хранит вызывающая программа;
словарь весов не создаёт модель автоматически.
Собственное описание наследует regnets.kernels.Kernel и реализует
build(shape: KernelShape) -> nn.Module. shape содержит in_features,
out_features, positions, shared, device и dtype.
Результат работает с [...,positions,in_features] и возвращает
[...,positions,out_features], сохраняя независимость позиций и пакета.
Автор создаёт зарегистрированные параметры согласно shared до первого
вычисления. Сеть проверяет форму результата; произвольный nn.Module
не векторизуется автоматически.
Полные сигнатуры приведены ниже: ModularNet и Layer, Kernel и готовые ядра.
regnets.modular #
Справочник публичного API Regnets 0.3.1. Сигнатуры, поля и описания получены из исходников при сборке. Имена в <factory: …> обозначают фабрики значений dataclass.
Для импорта этого модуля нужен PyTorch.
ModularNet наследует torch.nn.Module. Вход — вещественный тензор с net.n_inputs контактами. Несовместимые формы и описания отклоняются с ValueError, конфигурация весов — с RuntimeError. Создание и настройка модели.
Residual #
Residual(project: bool = False)
Обойти один слой, при необходимости обучая локальную проекцию без смещения.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
project |
bool |
False |
Layer #
Layer(kernel: Kernel = <factory: Dense>, shared: bool = True, residual: bool | Residual = False, *, in_size: int | None = None, out_size: int | None = None)
Описать ядро слоя, правила работы с параметрами и размеры векторов контактов.
Параметры
kernel: Неизменяемое описание, по которому создаётся векторизованное ядро.shared: Использовать общие параметры для позиций внутри слоя.residual: Обойти слой, сохранив его порядок сгруппированных контактов.in_size: Размер вектора входного контакта или None для скалярных контактов.out_size: Размер вектора выходного контакта или размер входа, если не задан.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
kernel |
Kernel |
<factory: Dense> |
shared |
bool |
True |
residual |
bool | Residual |
False |
in_size (только по имени) |
int | None |
None |
out_size (только по имени) |
int | None |
None |
ModularNet #
ModularNet(topology: Topology, layers: Layer | Sequence[Layer], *, device: torch.device | str | None=None, dtype: torch.dtype | None=None)
Применить компактную топологию с упакованными ядрами и остаточными связями.
Остаточные связи необязательны.
Параметры
topology: Соединения, не зависящие от PyTorch.layers: Одно описание, повторяемое с новыми параметрами, или n описаний. Размеры соседних контактов и скалярный или векторный режим должны совпадать.device: Начальное устройство для параметров и индексов.dtype: Начальный тип параметров.
ModularNet.p #
p: tuple[int, ...]
Вернуть числа входных контактов топологии по слоям.
ModularNet.g #
g: tuple[int, ...]
Вернуть числа выходных контактов топологии по слоям.
ModularNet.get_extra_state #
get_extra_state() -> dict
Сохранить метаданные соединений и построения вместе с зарегистрированными параметрами.
ModularNet.set_extra_state #
set_extra_state(state: dict) -> None
Запретить загрузку весов при другой конфигурации соединений или ядер.
ModularNet.forward #
forward(x: Tensor) -> Tensor
Сохранить начальные размерности пакета и применить все n+1 перестановок.
ModularNet.extra_repr #
extra_repr() -> str
Вернуть текстовое описание размеров и режима сети.
regnets.kernels #
Справочник публичного API Regnets 0.3.1. Сигнатуры, поля и описания получены из исходников при сборке. Имена в <factory: …> обозначают фабрики значений dataclass.
Для импорта этого модуля нужен PyTorch.
Неизменяемые описания ядер создают модули через build(shape). Вход имеет форму [..., positions, in_features], выход — [..., positions, out_features]. shared определяет общность параметров внутри слоя. Композиция блоков и собственное ядро.
Kernel #
Kernel()
Описать операцию над [..., positions, features] с сохранением позиций.
Подклассы создают новые экземпляры nn.Module с параметрами согласно shape.shared. Они могут смешивать локальные признаки, но не элементы пакета и не позиции.
Kernel.output_features #
output_features(in_features: int, default: int) -> int
Определить размерность выхода, когда блок находится внутри Sequential.
Kernel.build #
build(shape: KernelShape) -> nn.Module
Создать все регистрируемые параметры до создания оптимизатора.
KernelShape #
KernelShape(in_features: int, out_features: int, positions: int, shared: bool, device: torch.device | str | None = None, dtype: torch.dtype | None = None)
Размерности и правила работы с параметрами для метода build ядра.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
in_features |
int |
Обязательно |
out_features |
int |
Обязательно |
positions |
int |
Обязательно |
shared |
bool |
Обязательно |
device |
torch.device | str | None |
None |
dtype |
torch.dtype | None |
None |
Dense #
Dense(out_features: int | None = None, bias: bool = True, activation: Activation = None)
Описать аффинное преобразование с необязательной выходной активацией.
Параметры
out_features: Явная локальная размерность или размерность выхода слоя.bias: Добавить обучаемое смещение.activation: Фабрика активации без состояния, например nn.SiLU.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
out_features |
int | None |
None |
bias |
bool |
True |
activation |
Activation |
None |
Dense.output_features #
output_features(in_features: int, default: int) -> int
Определить промежуточную ширину выхода при включении блока в Sequential.
Dense.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
MLP #
MLP(hidden: int | Sequence[int] = (64,), activation: Activation = nn.SiLU, output_activation: Activation = None, bias: bool = True)
Описать локальный многослойный перцептрон с определяемыми размерностями входа и выхода.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
hidden |
int | Sequence[int] |
(64,) |
activation |
Activation |
nn.SiLU |
output_activation |
Activation |
None |
bias |
bool |
True |
MLP.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
Sequential #
Sequential(*blocks: Kernel)
Объединить блоки; блоки без изменения размерности сохраняют прежнюю локальную размерность.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
blocks |
tuple[Kernel, ...] |
Обязательно |
Sequential.output_features #
output_features(in_features: int, default: int) -> int
Определить промежуточную ширину выхода при включении блока в Sequential.
Sequential.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
Identity #
Identity()
Сохранить локальные признаки без использования параметров.
Identity.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
Dropout #
Dropout(p: float = 0.1)
Исключать отдельные локальные признаки при обучении с независимыми масками.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
p |
float |
0.1 |
Dropout.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
LayerNorm #
LayerNorm(eps: float = 1e-05, affine: bool = True, bias: bool = True)
Нормализовать весь локальный вектор признаков, не смешивая позиции и элементы пакета.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
eps |
float |
1e-05 |
affine |
bool |
True |
bias |
bool |
True |
LayerNorm.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
RMSNorm #
RMSNorm(eps: float = 1e-06, affine: bool = True)
Нормализовать локальную среднеквадратичную величину с необязательным обучаемым масштабом.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
eps |
float |
1e-06 |
affine |
bool |
True |
RMSNorm.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.
GatedMLP #
GatedMLP(hidden: int = 64, activation: Activation = nn.SiLU, bias: bool = True)
Вычислить проекции затвора и значения одной упакованной аффинной операцией.
Поля #
| Имя | Тип | По умолчанию |
|---|---|---|
hidden |
int |
64 |
activation |
Activation |
nn.SiLU |
bias |
bool |
True |
GatedMLP.build #
build(shape: KernelShape) -> nn.Module
Создать новый модуль с зарегистрированными параметрами согласно KernelShape.