Классическая нейросеть работает в вещественном поле
Для реализации физики ЕТВП необходимо полноценное погружение в комплексное поле
Если вход
Переводим всю сеть в комплексное пространство:
Активация также комплексная. Используем комплексный tanh:
где
Теперь фаза и амплитуда перетекают друг в друга — как в реальном поле.
При статичной классификации (например, MNIST) параметр
Архитектура разворачивается как нейронное дифференциальное уравнение:
где:
-
$z$ — комплексное состояние сети; -
$f(z, W)$ — детерминированная динамика; -
$\eta$ — амплитуда стохастической самокоррекции; -
$\beta$ — чувствительность к градиенту.
Такая сеть естественно работает с:
- видео (время
$t$ — номер кадра); - аудио (время
$t$ — сэмпл сигнала); - физическими процессами (температура, давление, вибрация);
- финансовыми временными рядами (тики, свечи).
Коэффициент
Вводим обучаемый параметр вязкости
где
Тогда резонансный фильтр принимает вид:
Сеть сама решает, насколько жёстким должно быть «давление вакуума» на каждом уровне.
где:
-
$z(t) \in \mathbb{C}$ — комплексное состояние; -
$W, b \in \mathbb{C}$ — комплексные веса и смещения; -
$\mu$ — обучаемая вязкость; -
$\eta$ — амплитуда шума; -
$\xi(t) \sim \mathcal{N}(0, 1)$ — стохастический член; -
$\nabla^2 z$ — лапласиан (пространственная регуляризация); -
$L$ — функция потерь.
где
import torch
import torch.nn as nn
import math
class ETVP_ComplexLayer(nn.Module):
def __init__(self, dim_in, dim_out, R_max=1.0, eta_init=0.01, beta_init=0.1):
super().__init__()
# Комплексные веса
self.W_re = nn.Parameter(torch.randn(dim_in, dim_out) * 0.1)
self.W_im = nn.Parameter(torch.randn(dim_in, dim_out) * 0.1)
self.b_re = nn.Parameter(torch.zeros(dim_out))
self.b_im = nn.Parameter(torch.zeros(dim_out))
# Обучаемая вязкость
self.theta_mu = nn.Parameter(torch.tensor(0.0))
self.mu = torch.nn.functional.softplus(self.theta_mu)
# Параметры шума
self.eta = nn.Parameter(torch.tensor(eta_init))
self.beta = nn.Parameter(torch.tensor(beta_init))
self.R_max = R_max
def complex_mul(self, x_re, x_im):
out_re = x_re @ self.W_re - x_im @ self.W_im + self.b_re
out_im = x_re @ self.W_im + x_im @ self.W_re + self.b_im
return out_re, out_im
def complex_tanh(self, re, im):
return torch.tanh(re), torch.tanh(im)
def laplacian(self, z):
# Дискретный лапласиан по пространственным осям
lap = torch.zeros_like(z)
lap[1:-1] = z[:-2] - 2 * z[1:-1] + z[2:]
return lap
def forward(self, x_re, x_im, dt=0.1):
# Детерминированная динамика
z_re, z_im = self.complex_mul(x_re, x_im)
z_re, z_im = self.complex_tanh(z_re, z_im)
# Вязкость (обучаемая)
mu = torch.nn.functional.softplus(self.theta_mu)
z_re = z_re - mu * self.laplacian(z_re)
z_im = z_im - mu * self.laplacian(z_im)
# Стохастическая самокоррекция
noise_re = self.eta * torch.randn_like(z_re) * torch.tanh(self.beta * z_re.abs())
noise_im = self.eta * torch.randn_like(z_im) * torch.tanh(self.beta * z_im.abs())
z_re = z_re + dt * noise_re
z_im = z_im + dt * noise_im
# Z-принцип: проекция на сферу
W_norm = torch.sqrt((self.W_re ** 2 + self.W_im ** 2).sum())
if W_norm > self.R_max:
self.W_re.data *= self.R_max / W_norm
self.W_im.data *= self.R_max / W_norm
return z_re, z_im