Cortex Hierarchies
The cortex architecture is the package form of the article's hierarchical SILVA experiments [1]: an input is first transformed into a stimulus, one equilibrium point stabilizes a first representation, and a later equilibrium point receives that stable state as its own stimulus. The layers remain normal PyTorch modules, so a model can include convolutional stems, dense state networks, local graph terms, global attention terms, task heads, and custom branches.
One Equilibrium Point
Let \(x\) be the incoming object. It may be a tabular vector, a graph feature matrix, an image batch after a convolutional stem, or the output of a previous equilibrium point. The first operation is stimulus construction:
R_phi is input_encoder. When no encoder is supplied,
SILVACortexLayer(input_dim=d_in, state_dim=d) creates the affine encoder
The recurrent state \(z\) has the same shape as \(u\). Each solver step first forms an activated state
then sends that state through any internal transition network
For a ten-layer internal network, \(r=10\). In code this is simply an
nn.Sequential or list of modules passed as state_network.
Interaction branches are added as state-shaped fields:
The undamped transition is
The solved state is the fixed point
The numerical solver uses the damped recurrence
The parameter \(\alpha\) controls how far each solver step moves toward the new field value. Larger values react faster; smaller values are more damped and can stabilize slower semantic or chemical states. The fast/slow hierarchy uses a fast first point, commonly \(\alpha_1=0.5\), followed by a slower second point, commonly \(\alpha_2=0.2\).
Linked Cortex Points
For \(K\) cortex points, define
Point \(\ell\) solves
then passes a linked representation forward:
SILVACortexNetwork(..., links="tanh") uses
\(\lambda_\ell(z)=\tanh(z)\). Custom link modules can be supplied when the next
point needs projection, gating, normalization, or another domain-specific
adapter.
Public API
import torch
from silva_networks import SILVACortexLayer, SILVACortexNetwork, SolverConfig
def deep_state_network(dim, depth):
modules = []
for _ in range(depth):
modules += [torch.nn.Linear(dim, dim), torch.nn.Tanh()]
modules.append(torch.nn.Linear(dim, dim))
return torch.nn.Sequential(*modules)
model = SILVACortexNetwork(
[
SILVACortexLayer(
input_dim=5,
state_dim=14,
state_network=deep_state_network(14, depth=10),
self_terms=torch.nn.Linear(14, 14, bias=False),
config=SolverConfig(solver="picard", max_iter=10, alpha=0.5),
),
SILVACortexLayer(
input_encoder=torch.nn.Linear(14, 10),
state_dim=10,
state_network=torch.nn.Sequential(
torch.nn.Linear(10, 20),
torch.nn.GELU(),
torch.nn.Linear(20, 10),
),
config=SolverConfig(solver="anderson", max_iter=10, alpha=0.2, history=3),
normalize=False,
),
],
links="tanh",
head=torch.nn.Linear(10, 2),
)
The first point has a ten-layer internal transition network. The second point uses a different architecture, different state dimension, different solver, and different damping. Both are trained by ordinary PyTorch gradients.
Internal Architecture Contract
The internal architecture is defined by ordinary PyTorch modules. A SILVA
equilibrium point does not require an MLP: state_network may contain
convolutions, residual blocks, a U-Net
[27], attention
[29], graph operations, or a
domain-specific module. The final transition must preserve the equilibrium
state space:
The controls have distinct roles:
| Control | Role |
|---|---|
input_encoder |
maps the incoming object to the equilibrium-state shape |
state_network |
runs the internal architecture during every solver iteration |
| interaction terms | add broadcast-compatible self, local, global, or custom fields |
output_network |
processes the summed transition before the outer activation |
normalizer |
applies shape-appropriate normalization |
links |
transforms one solved point before it enters the next point |
For an image state with shape (batch, channels, height, width), use a
convolutional input_encoder and a spatial normalizer such as GroupNorm.
A U-Net may change resolution internally, but its returned tensor must restore
the state channels, height, and width.
spatial_point = SILVACortexLayer(
input_encoder=torch.nn.Conv2d(1, 8, kernel_size=3, padding=1),
state_network=my_unet_transition,
normalizer=torch.nn.GroupNorm(2, 8),
config=SolverConfig(solver="anderson", max_iter=20, alpha=0.35),
)
The runnable Spatial SILVA Cortex example uses a residual convolutional block and a U-Net-shaped transition inside the first point, then links its spatial state to a different vector point.
The Point Architecture Catalog provides ten built-in choices for vector, token, and spatial states, plus examples of several architectures composed inside one point and different architectures assigned to linked points.
Fixed-Point-Safe Modules
During one solve, the transition should be deterministic, differentiable, and
device/dtype preserving. Prefer GroupNorm for spatial states. Ordinary
training-mode batch normalization changes running statistics during repeated
transition evaluations, and ordinary dropout draws a new mask at every
iteration. Use fixed statistics or a solver-consistent mask when those
operations are required.
Large internal networks are not automatically stable. Damping, residual scaling, spectral normalization, and the recorded residual curve remain the practical controls for checking convergence.
Image Cortex Preset
SILVAImageCortexClassifier packages the CIFAR-style pattern:
from silva_networks import SILVAImageCortexClassifier
model = SILVAImageCortexClassifier(
in_channels=3,
hidden_dim=[128, 128],
num_classes=10,
image_size=32,
attention_mode="simple",
graph_mode="GAT",
k_neighbors=4,
alphas=(0.5, 0.2),
max_iter=20,
internal_depth=2,
self_interaction=True,
)
The options align with the experiment language:
| Option | Meaning |
|---|---|
attention_mode="none" |
no learned global branch |
attention_mode="static" |
learned static channel interaction |
attention_mode="simple" |
per-sample channel attention |
attention_mode="multi-head" |
multi-head channel attention |
graph_mode="none" |
no local channel graph |
graph_mode="GAT", "GNN", or "knn" |
dynamic hidden-channel kNN local branch |
alphas=(0.5, 0.2) |
fast first equilibrium and slower second equilibrium |
internal_depth=10 |
ten trainable state blocks inside each equilibrium point |
backward_mode="implicit" |
matrix-free implicit adjoint through GMRES |
Custom Context Modules
Every custom module may accept only the context it needs. The package passes available tensors by keyword:
class StimulusGate(torch.nn.Module):
def __init__(self, dim):
super().__init__()
self.gate = torch.nn.Linear(dim, dim)
def forward(self, z, stimulus):
return torch.sigmoid(self.gate(stimulus)) * z
The same rule works for graph modules:
class EdgeAwareLocal(torch.nn.Module):
def forward(self, z, edge_index, edge_attr=None, batch=None):
src, dst = edge_index
out = torch.zeros_like(z)
out.index_add_(0, dst, z[src])
return out
This is the package grammar for going beyond the article while staying inside the SILVA operator form.
Tests and Examples
The public validation example is
examples/cortex_hierarchy.py.
The tests in tests/test_architectures.py verify:
| Check | What is exercised |
|---|---|
| internal network | deep modules inside one equilibrium point |
| linked points | one solved point feeding another |
| alphas | fast/slow damping values are held per point |
| solvers | Picard and Anderson can coexist in one hierarchy |
| image preset | convolutional stem plus two cortex points |
| gradients | classifier loss reaches the stem and internal modules |
The Point Architecture Catalog derives the ten built-in internal mappings, while the Full Cortex Operator Example executes every branch family. Primary architecture sources are listed in Point Architecture Sources.
Where to Go Next
| Question | Page |
|---|---|
| How are several equilibrium points composed and placed on devices? | Stacking and Devices |
| Where is the hierarchy executed end to end? | Cortex Hierarchy Example |
| Which API objects build the hierarchy? | Architectures API |