TopoEncoder Architecture: Attentive Atlas with Typed Latents#
TLDR#
The representation stack is an Attentive Atlas (TopoEncoderPrimitives) with chart routing and per-chart codebooks.
The discrete macro state is charted: \(K_t = (K_{\mathrm{chart}}, K_{\mathrm{code}})\), with continuous nuisance \(z_n\) and texture \(z_{\mathrm{tex}}\); geometry uses \(z_{\mathrm{geo}}\).
Routing uses CovariantChartRouter (conformal-factor transport + metric-aware temperature) with a hyperbolic-distance fallback when disabled.
Decoding mixes chart projectors with router weights and adds a separate texture residual path.
Training uses reconstruction + VQ + routing/consistency, plus tiered regularizers and optional jump and supervised topology losses.
Roadmap#
Typed latents and causal enclosure.
Encoder and chart routing.
Per-chart VQ and latent decomposition.
Decoder block.
Training wiring and loss tiers.
Diagnostics and extensions.
Training Checklist (Practical)#
Start with stable chart routing: monitor routing entropy and chart usage early.
Keep chart centers separated (chart center separation loss) before enabling expensive losses.
If
vision_preprocis enabled, validate the input shape andvision_*settings.If
soft_equiv_metricis enabled, watchsoft_equiv_l1andsoft_equiv_log_ratiofor drift.Add jump consistency and supervised topology only after the atlas stabilizes.
The Core Concept: Typed Latents and Causal Enclosure#
The TopoEncoder keeps the split-brain idea but implements it as an atlas. The macro state is a chart assignment plus a per-chart code index. The residual channels are still typed and explicitly kept out of macro closure.
Definition 25 (The Three-Channel Latent Decomposition)
The internal state at time \(t\) decomposes as:
where:
\(K_t = (K_{\mathrm{chart}}, K_{\mathrm{code}})\) is the discrete macro state. \(K_{\mathrm{chart}}\) selects an atlas chart, and \(K_{\mathrm{code}}\) selects a local code within that chart.
\(z_{n,t} \in \mathbb{R}^{d_n}\) is the structured nuisance (pose, basis, gauge residual).
\(z_{\mathrm{tex},t} \in \mathbb{R}^{d_{\mathrm{tex}}}\) is reconstruction-only texture.
The implementation diagrams below use a common width \(d_n=d_{\mathrm{tex}}=D\). If the nuisance or texture widths differ, insert learned embeddings into the \(D\)-dimensional decoder input.
The geometry latent used by the decoder is
where \(c_{\mathrm{bar}}\) is the chart center mixture and \(z_{q,\mathrm{st}}\) is the straight-through quantized code.
Definition 26 (The Golden Rule of Causal Enclosure)
The macro symbol must satisfy the causal enclosure property:
This is the joint enclosure condition: once the current macro state and action are given, neither residual channel carries additional predictive information about the next macro symbol. Predictive concentration of \(P(K_{t+1}\mid K_t,a_t)\) is a separate model-quality diagnostic.
Architecture: TopoEncoder (Attentive Atlas)#
TopoEncoderPrimitives couples a PrimitiveAttentiveAtlasEncoder with a PrimitiveTopologicalDecoder.
The encoder builds chart weights, per-chart VQ assignments, and the typed latents. The decoder uses
chart routing to mix per-chart projectors and produce the reconstruction. Implementation lives in
src/fragile/core/layers/atlas.py.
The encoder and decoder diagrams below are flat reference schematics. They show tensor shapes
and data flow with ordinary sums and differences so that the wiring is easy to read. Production
routing uses the metric-aware primitives in atlas.py: Poincare distances and barycenters,
Möbius transport/addition, logarithm and exponential maps, and projection back to the ball. The
flat expressions are placeholders for those operations, not a claim that the production router is
Euclidean.
Encoder Block#
%%{init: {"themeVariables": {"background":"#0b111b","edgeLabelBackground":"#111827","textColor":"#e5e7eb","lineColor":"#9ca3af","primaryColor":"#1f2937","primaryTextColor":"#e5e7eb","clusterBkg":"#0f172a","clusterBorder":"#334155"}}}%%
flowchart TD
subgraph ENC["PrimitiveAttentiveAtlasEncoder"]
X["Input x [B, D_in]"] --> FE["Feature extractor\nSpectralLinear + NormGatedGELU\n(or CovariantRetina)"]
FE --> F["features [B, H]"]
F --> Vproj["val_proj -> v [B, D]"]
ChartCenters["chart_centers c_k [N_c, D]"] --> RouterEnc["Chart router\nCovariantChartRouter or hyperbolic-distance"]
F --> RouterEnc
Vproj --> RouterEnc
RouterEnc --> Wenc["w_enc [B, N_c]"]
RouterEnc --> Kchart["K_chart [B]"]
Wenc --> Cbar["reference c_bar = sum(w_enc * c_k) [B, D]\nproduction: Poincare barycenter"]
ChartCenters --> Cbar
Vproj --> Vlocal["reference v_local = v - c_bar [B, D]\nproduction: Mobius subtraction"]
Cbar --> Vlocal
Codebook["Codebook (deltas) [N_c, K, D]"] --> Diff["diff = v_local - codebook [B, N_c, K, D]"]
Vlocal --> Diff
Diff --> SoftEq["SoftEquivariantLayer per chart\n(optional)"]
SoftEq --> Dist["dist = ||diff'||^2 [B, N_c, K]"]
Diff -.-> Dist
Dist --> Indices["indices per chart [B, N_c]"]
Indices --> ZqAll["z_q_all [B, N_c, D]\n(+ soft-ST if soft_equiv_soft_assign)"]
ZqAll --> ZqBlend["z_q_blended = sum(w_enc * z_q_all)"]
ZqAll --> VQLoss["vq_loss = codebook + 0.25 * commitment"]
Vlocal --> VQLoss
ZqAll --> DeltaAll["delta_all = v_local - z_q_all (detach)"]
DeltaAll --> Struct["structure_filter\nIsotropicBlock + SpectralLinear"]
Struct --> ZnAll["z_n_all_charts [B, N_c, D]"]
ZnAll --> Zn["z_n = sum(w_enc * z_n_all_charts) [B, D]"]
ZqBlend --> DeltaBlend["delta_blended = v_local - z_q_blended (detach)"]
DeltaBlend --> Ztex["z_tex = delta_blended - z_n"]
ZqBlend --> ZqSt["z_q_st = v_local + (z_q_blended - v_local).detach"]
ZqSt --> Zgeo["reference z_geo = c_bar + z_q_st + z_n\nproduction: Mobius addition + projection"]
Zn --> Zgeo
Cbar --> Zgeo
end
Covariant Chart Router#
%%{init: {"themeVariables": {"background":"#0b111b","edgeLabelBackground":"#111827","textColor":"#e5e7eb","lineColor":"#9ca3af","primaryColor":"#1f2937","primaryTextColor":"#e5e7eb","clusterBkg":"#0f172a","clusterBorder":"#334155"}}}%%
flowchart TD
subgraph ROUTER["CovariantChartRouter (shared by encoder + decoder)"]
Z["z [B, D]"] --> Dist["d_Poincare(z,c_k) [B, N_c]"]
ChartTokens["chart centers c_k [N_c, D]"] --> Dist
Dist --> Scores["scores = -d_Poincare(z,c_k) / tau(z)"]
Z --> Tau["tau(z) = sqrt(K) * (1 - ||z||^2)/2\nclamp denom + tau_min"]
Scores --> Scale["scores / tau"]
Tau --> Scale
Scale --> W["w = softmax(scores/tau) [B, N_c]"]
W --> Kchart["K_chart [B]"]
F["features [B, H]\n(encoder only)"] --> Corr["optional encoder correction\n0.1 <P_0->z(base_queries), q_z(z)+q_feat(f)+gamma(z)> / tau(z)"]
Z --> Corr
Corr --> Scale
end
Decoder Block#
%%{init: {"themeVariables": {"background":"#0b111b","edgeLabelBackground":"#111827","textColor":"#e5e7eb","lineColor":"#9ca3af","primaryColor":"#1f2937","primaryTextColor":"#e5e7eb","clusterBkg":"#0f172a","clusterBorder":"#334155"}}}%%
flowchart TD
subgraph DEC["PrimitiveTopologicalDecoder (production metric routing)"]
Zgeo["z_geo [B, D]"] --> BallG["_project_to_ball(z_geo)"]
BallG --> RouterDec["Chart router\n_poincare_hyperbolic_score"]
RouterDec --> Wdec["w_dec [B, N_c]"]
ChartIdx["chart_index (optional)"] --> OneHot["one-hot -> w_hard"]
OneHot --> Wdec
BallG --> ChartProj["chart_projectors: SpectralLinear x N_c"]
ChartProj --> Gate["NormGatedGELU on h_stack"]
Gate --> Mix["h_global = sum(w_dec * h_stack)"]
Wdec --> Mix
Mix --> Renderer["renderer: SpectralLinear + NormGatedGELU x2 + SpectralLinear"]
Mix --> Skip["render_skip: SpectralLinear"]
Renderer --> AddSkip["x_hat_base = renderer + skip"]
Skip --> AddSkip
Ztex["z_tex [B, D]"] --> TexRes["tex_residual: SpectralLinear"]
TexRes --> AddTex["x_hat = x_hat_base + tex_residual_scale * tex_residual"]
AddSkip --> AddTex
AddTex --> Xhat["x_hat [B, D_out]"]
end
Training Wiring (Optional Losses)#
%%{init: {"themeVariables": {"background":"#0b111b","edgeLabelBackground":"#111827","textColor":"#e5e7eb","lineColor":"#9ca3af","primaryColor":"#1f2937","primaryTextColor":"#e5e7eb","clusterBkg":"#0f172a","clusterBorder":"#334155"}}}%%
flowchart TD
X["batch_X"] --> Enc["TopoEncoderPrimitives.encoder"]
Enc --> Dec["TopoEncoderPrimitives.decoder"]
Dec --> ReconLoss["recon_loss"]
Enc --> VQLoss["vq_loss"]
ReconLoss --> ReconTerm["recon_term\n(optional learned precision)"]
VQLoss --> VQTerm["vq_term\n(optional learned precision)"]
Enc --> Sup["SupervisedTopologyLoss (optional)"]
Sup --> SupTerm["sup_term\n(optional learned precision)"]
Enc --> Jump["FactorizedJumpOperator (optional)"]
Jump --> LossA["atlas loss\n(recon + vq + regs + jump + sup)"]
ReconTerm --> LossA
VQTerm --> LossA
SupTerm --> LossA
Implementation toggles wired in src/experiments/topoencoder_2d.py:
covariant_attnand friends control routing tensorization, transport, and temperature.vision_preprocswaps the SpectralLinear + NormGatedGELU stack for CovariantRetina in the encoder.soft_equiv_metric,soft_equiv_soft_assign, andsoft_equiv_temperaturecontrol the per-chart metric and soft straight-through assignments.
Loss Function: Enforcing Macro/Micro Separation#
The TopoEncoder is trained with a compound objective. The core terms enforce reconstruction, quantization, and routing alignment; the tiered regularizers stabilize geometry and codebook health. Optional supervised topology and jump losses are added when enabled.
Definition 27 (The Total TopoEncoder Loss)
The compound loss is:
Where:
\(\mathcal{L}_{\text{recon}} = \|x - \hat{x}\|^2\) (MSE reconstruction).
\(\mathcal{L}_{\text{vq}}\) is the codebook + commitment loss.
\(\mathcal{L}_{\text{entropy}}=\log N_c-\frac1B\sum_bH(w_b)\) is an entropy-raising anti-collapse regularizer; chart usage/diversity terms prevent dead charts.
\(\mathcal{L}_{\text{consistency}}\) aligns encoder and decoder routing.
Tiered losses include variance, diversity, separation, codebook centering, chart center separation, residual scale, window, disentangle, orthogonality, code entropy, per-chart code entropy, KL prior, orbit, and VICReg invariance.
\(\mathcal{L}_{\text{jump}}\) enforces chart transition consistency when the jump operator is enabled.
\(\mathcal{L}_{\text{sup}}\) applies supervised topology when labels are available.
Learned precisions can reweight reconstruction, VQ, and supervised terms when enabled.
For exact definitions of each tiered loss, see Appendix F: Loss Terms Reference.
The Complete Training Loop#
The training loop in src/experiments/topoencoder_2d.py follows a fixed sequence:
Encode the batch to obtain \(K_{\mathrm{chart}}\), routing weights, \(z_n\), \(z_{\mathrm{tex}}\), \(z_{\mathrm{geo}}\), and VQ loss.
Decode in dreaming mode (no hard chart index) to obtain the reconstruction and decoder routing.
Compute reconstruction, VQ, routing entropy, and encoder-decoder consistency.
Add tiered regularizers and optional jump and supervised losses.
Apply learned precision reweighting if enabled, then backprop, clip gradients, and step.
Classifier readouts (if enabled) are trained on detached latents with their own optimizer.
Runtime Diagnostics: Routing Sharpness#
Routing sharpness is monitored through the conditional entropy of the soft router weights. It is distinct from the causal closure ratio, which compares transition-model cross-entropy with a marginal baseline (Definition 347).
Definition 28 (Routing Sharpness)
Let \(K\) be the chart assignment and \(N_c\) the number of charts. Define
Values near 1 indicate deterministic soft routing and values near 0 indicate diffuse routing. The quantity equals \(I(X;K)/\log N_c\) only when the marginal chart usage is uniform.
Additional diagnostics used in the TopoEncoder benchmark include:
window_loss/ \(I(X;K)\) (stable learning window)routing entropy and perplexity
per-chart code entropy
chart center separation
jump consistency loss (when enabled)
Advanced: Hierarchical Multi-Scale Latents#
Atlas models extend naturally to multiple scales by stacking charted codebooks.
Definition 29 (Hierarchical Latent Stack)
A multi-scale atlas uses a hierarchy of discrete chart codes:
where each level \(\ell\) has its own chart set and codebook, and higher levels capture coarser structure.
In practice this can be implemented by stacking TopoEncoder blocks or by sharing a base encoder with multiple chart routers and codebooks.
Literature Connections (Mapping + Differences)#
Atlas models and mixture-of-experts: chart routing implements a learned partition of unity.
VQ-VAE: per-chart VQ keeps discrete macro structure but with charted codebooks.
Geometric deep learning: routing temperature encodes conformal metric information.
Structured residuals: explicit nuisance and texture channels mirror disentanglement objectives.
Computational Costs#
Let \(K_{\mathrm{key}}\) be the router key width, \(K_{\mathrm{code}}\) the number of codes per chart, and \(H\) the hidden width of a soft-equivariant block. With a dense tensorized router, the leading costs are:
Routing: \(O\!\left(B(N_cD+K_{\mathrm{key}}D^2)\right)\), plus the cost of the selected metric transport.
Codebook distances: \(O(BN_cK_{\mathrm{code}}D)\) for per-chart VQ.
Soft-equivariant metric: \(O(BN_cK_{\mathrm{code}}DH)\) for a block with hidden width \(H\).
Control Theory Translation: Dictionary#
Control concept |
TopoEncoder component |
|---|---|
Discrete state |
\(K_{\mathrm{chart}}, K_{\mathrm{code}}\) |
Local coordinates |
\(z_n\) |
Emission residual |
\(z_{\mathrm{tex}}\) |
Transition map |
Jump operator |
Partition of unity |
Router weights \(w\) |
Differential-Geometry View (No Physics): Curvature as Conditioning#
Charts are local coordinate systems; chart centers define anchor points, and routing weights define smooth transitions between charts. The metric-aware temperature in routing behaves like local conditioning, sharpening attention where the conformal factor \(\lambda(z)=2/(1-\lVert z\rVert^2)\) is large near the ball boundary, where hyperbolic distances are stretched.
The Entropy-Regularized Objective Functional#
Routing entropy and policy entropy play parallel roles: both penalize collapse and stabilize exploration. In the representation stack, entropy regularizes chart usage and prevents dead charts.
Atlas-Manifold Dictionary: From Topology to Neural Networks#
Core Correspondences#
Geometry |
Network |
|---|---|
Chart |
Router weight + chart center |
Atlas overlap |
Soft routing across charts |
Transition map |
Jump operator |
Partition of unity |
Softmax router weights |
When to Use Atlas Architecture#
Use charted latents when the representation requires multiple local linearizations or when a single codebook collapses under diverse modes.