Docs DNA Engine

The DNA Engine: Topological Network Fingerprinting

This document covers ExtractDNA, CosineSimilarity, CompareNetworks, LogicShift detection, and the recursive signature extraction for all 19 layer types in dna.go.

For the Evolution Engine (DNA Splice + NEAT mutations), see evolution.md.


Why DNA?

Standard weight comparison breaks across precisions — you can't directly compare an INT8 weight against an FP32 weight. The DNA engine solves this by converting every layer's weights to a unit direction vector after simulating precision loss. Comparing direction vectors (cosine similarity) instead of raw values means:

  • FP32 and INT8 representations of the same model look nearly identical
  • Two networks trained on the same task converge toward the same DNA
  • Structural changes (different layer order, different grid positions) are detectable as logic shifts
Raw FP32 weights  ──►  SimulatePrecision  ──►  Normalize  ──►  unit vector
       │                  (dtype, scale)        (L2 norm)         "DNA strand"
       │
       └── FP4 weights ──►  SimulatePrecision  ──►  Normalize  ──►  same direction ≈ 1.0 similarity

Core Types

// The "DNA strand" of a single layer
type LayerSignature struct {
    Z, Y, X, L int       // 3D grid coordinates
    Type        LayerType
    DType       DType
    Weights     []float32 // L2-normalized, precision-simulated weights
}

// The complete genetic blueprint of a network
type NetworkDNA []LayerSignature

ExtractDNA — all 19 layer types

func ExtractDNA(n *VolumetricNetwork) NetworkDNA

Iterates every layer in the network, calls extractLayerSignature(l), and wraps the result with position and type metadata. The signature extraction logic handles all 19 layer types:

                    VolumetricNetwork
                           │
              ┌────────────┼────────────┐
              │            │            │
         LayerDense   LayerParallel  LayerSoftmax
         LayerRNN     LayerSequential LayerResidual
         LayerLSTM    (recursive)    (weightless)
         LayerMHA
         LayerSwiGLU
         LayerRMSNorm
         LayerLayerNorm
         LayerCNN1/2/3
         LayerConvT1/2/3D
         LayerEmbedding
         LayerKMeans
              │
              ▼
    extractLayerSignature(l)
              │
    ┌─────────┼──────────────┐
    │         │              │
    ▼         ▼              ▼
 weighted  recursive     weightless
 layers    containers    layers
    │         │              │
    ▼         ▼              ▼
 Master   flatten all    []float32{1.0}
 weights  branches
    │         │
    ▼         ▼
SimulatePrecision  Normalize(concat)
    │
    ▼
 Normalize
    │
    ▼
 []float32 unit vector

Weighted layers (Dense, RNN, LSTM, MHA, CNN*, ConvTransposed*, SwiGLU, RMSNorm, LayerNorm, Embedding, KMeans)

// All weighted layers follow this path:
scale := l.WeightStore.Scale
if scale == 0 { scale = 1.0 }
simulated := make([]float32, len(l.WeightStore.Master))
for i, w := range l.WeightStore.Master {
    simulated[i] = SimulatePrecision(w, l.DType, scale)
}
return Normalize(simulated)

SimulatePrecision clips and quantizes each weight to what it would actually be at the layer's active DType. This means the DNA of an INT8 Dense layer and an FP32 Dense layer with the same trained weights will be nearly identical.

Structural containers (Parallel, Sequential) — recursive extraction

Parallel and Sequential layers contain nested layers (ParallelBranches, SequentialLayers). A naive approach that returned {1.0} for both would make any two parallel layers look identical regardless of what's inside them. Instead, the engine recurses:

LayerParallel
├── Branch 0 (Dense 32×32)   ──► extractLayerSignature ──► unit vec A  ─┐
├── Branch 1 (RMSNorm 32)    ──► extractLayerSignature ──► unit vec B  ─┤ concat
└── FilterGateConfig (Dense) ──► extractLayerSignature ──► unit vec C  ─┘
                                                                         │
                                                                    Normalize(flat)
                                                                         │
                                                                    single unit vec
                                                                    representing ALL
                                                                    nested weights
case LayerParallel:
    var flat []float32
    for _, branch := range l.ParallelBranches {
        if branch.IsRemoteLink { continue }   // remote links have no local weights
        flat = append(flat, extractLayerSignature(branch)...)
    }
    if l.FilterGateConfig != nil {
        flat = append(flat, extractLayerSignature(*l.FilterGateConfig)...)
    }
    if len(flat) == 0 { return []float32{1.0} }
    return Normalize(flat)

case LayerSequential:
    var flat []float32
    for _, sub := range l.SequentialLayers {
        flat = append(flat, extractLayerSignature(sub)...)
    }
    if len(flat) == 0 { return []float32{1.0} }
    return Normalize(flat)

Remote links (IsRemoteLink = true) are spatial hops with no local weights — they are skipped during extraction.

Weightless layers (Softmax, Residual)

case LayerSoftmax, LayerResidual:
    return []float32{1.0}

A {1.0} vector is a neutral presence marker. Two Softmax layers at the same position will score 1.0 similarity (identical), which is correct — they are architecturally identical by definition.


Normalize

func Normalize(v []float32) []float32

Converts a weight vector to a unit vector:

mag = sqrt(v[0]² + v[1]² + ... + v[n]²)
output[i] = v[i] / mag
  • If mag == 0 (all-zero weights), returns a zero vector
  • Two zero vectors score 1.0 similarity (both represent an untrained/zeroed layer)
  • One zero + one nonzero scores 0.0 (orthogonal by convention)

CosineSimilarity

func CosineSimilarity(s1, s2 LayerSignature) float32

Returns a score in [-1.0, 1.0] comparing two layer signatures:

         s1.Weights · s2.Weights
sim  =  ─────────────────────────   =  dot product  (since |s1| = |s2| = 1)
              |s1| × |s2|

Guard rails:

Condition Returns
s1.Type != s2.Type 0.0 — architectural mismatch
s1.DType != s2.DType 0.0 — precision mismatch
len(s1.Weights) != len(s2.Weights) 0.0 — dimension mismatch
Both zero vectors 1.0 — identical untrained layers
One zero, one nonzero 0.0 — no similarity

Similarity values to interpret:

-1.0  ────────────  0.0  ────────────  +1.0
  │                  │                   │
opposite          no match          identical
direction                           direction
(learned to      (different         (same functional
do opposite)      purpose)           role)

CompareNetworks

func CompareNetworks(dna1, dna2 NetworkDNA) NetworkComparisonResult

type NetworkComparisonResult struct {
    OverallOverlap float32
    LayerOverlaps  map[string]float32   // "z,y,x,l" → score
    LogicShifts    []LogicShift
}

Two-phase comparison:

Phase 1 — Direct Position Matching

Match each layer in dna1 with the layer at the same (Z, Y, X, L) position in dna2:

dna1:   [L0: Dense]  [L1: RNN]  [L2: Dense]
              │              │          │
              │ same pos     │          │ same pos
              ▼              ▼          ▼
dna2:   [L0: Dense]  [L1: Dense]  [L2: Dense]
              │              │          │
          sim=0.94       sim=0.0    sim=0.87   (0.0 because type mismatch)
              │              │          │
              └──────────────┴──────────┘
                              │
                         avg = 0.60
                    OverallOverlap = 0.60

Phase 2 — Logic Drift Detection

For each layer in dna1, search all positions in dna2 for the best cosine match — not just the same position:

dna1 L0 (Dense, sim vector A)
    │
    ├──► compare vs dna2 L0 → sim=0.72
    ├──► compare vs dna2 L1 → sim=0.31
    └──► compare vs dna2 L2 → sim=0.91  ← best match!

Best match (0.91) is at position L2, not L0.
Since 0.91 > 0.8 threshold AND positions differ:
→ LogicShift { SourcePos:"0,0,0,0", TargetPos:"0,0,0,2", Overlap:0.91 }
type LogicShift struct {
    SourcePos string   // "z,y,x,l" in dna1
    TargetPos string   // "z,y,x,l" in dna2
    Overlap   float32  // cosine score > 0.8
}

Logic shifts appear when:

  • A network was restructured and layers were reordered
  • A NEAT mutation moved a functional pattern to a different grid position
  • Two networks converged to the same function at different coordinates

Full DNA Pipeline

  Network A (trained)                   Network B (trained)
       │                                      │
       ▼                                      ▼
 ExtractDNA(A)                          ExtractDNA(B)
       │                                      │
  for each layer:                        for each layer:
  ┌──────────────────────────────┐       ┌──────────────────────────────┐
  │ Parallel/Sequential:         │       │ Parallel/Sequential:         │
  │   recurse into branches      │       │   recurse into branches      │
  │   concat + Normalize         │       │   concat + Normalize         │
  │ Weighted:                    │       │ Weighted:                    │
  │   SimulatePrecision(w, dtype)│       │   SimulatePrecision(w, dtype)│
  │   Normalize(simulated)       │       │   Normalize(simulated)       │
  │ Weightless:                  │       │ Weightless:                  │
  │   {1.0}                      │       │   {1.0}                      │
  └──────────────────────────────┘       └──────────────────────────────┘
       │                                      │
       │  NetworkDNA ([]LayerSignature)        │  NetworkDNA
       └─────────────────┬────────────────────┘
                         │
                         ▼
               CompareNetworks(dnaA, dnaB)
                         │
            ┌────────────┴────────────┐
            │                         │
            ▼                         ▼
    Phase 1: Direct            Phase 2: Cross-pos
    position matching          best-match search
            │                         │
    LayerOverlaps              LogicShifts
    OverallOverlap             (migrations)
            │
            └────────────────────────▶ NetworkComparisonResult

Use Cases

Measuring Quantization Fidelity

dnaFP32 := poly.ExtractDNA(net)
// morph all layers to INT8...
poly.MorphAllLayers(net, poly.DTypeInt8)
dnaINT8 := poly.ExtractDNA(net)
result := poly.CompareNetworks(dnaFP32, dnaINT8)
// result.OverallOverlap near 1.0 → quantization preserved behavior
// result.OverallOverlap near 0.0 → quantization destroyed the model

Detecting Training Convergence

Sample DNA every N epochs. When OverallOverlap between consecutive snapshots stabilizes above 0.99, the network has converged.

Epoch 0   → Epoch 10  : overlap = 0.12  (learning fast)
Epoch 10  → Epoch 50  : overlap = 0.61  (settling)
Epoch 50  → Epoch 100 : overlap = 0.94  (nearly converged)
Epoch 100 → Epoch 150 : overlap = 0.99  (converged)

Cross-Architecture Similarity

Two networks with different layer counts share coordinates for only the positions they have in common. CompareNetworks will match only those overlapping positions, and the OverallOverlap is averaged over matched layers only.

Logic Drift After NEAT Mutations

After a NEAT topology mutation moves a Dense layer from position 0,0,0,0 to 0,0,0,2, the logic shift detector will report:

LogicShift {
    SourcePos: "0,0,0,0",
    TargetPos: "0,0,0,2",
    Overlap:   0.93,
}

This is how you track functional identity across structural mutations.


DNA Signature Sizes by Layer Type

Layer Type Signature Length Notes
Dense (32) 1024 inputH × outputH
MHA (32, 4 heads) 4224 Q+K+V+O projections + biases
SwiGLU (32) 6144 gate + up + down × 3 projections
RMSNorm (32) 32 scale vector only
LayerNorm (32) 64 gamma + beta
CNN1/2 (8f, 1c, k3) 72 filters × channels × k²
CNN3 (8f, 1c, k3) 216 filters × channels × k³
RNN (32) 2080 Wx + Wh + bias
LSTM (32) 8320 4 gates × (Wx + Wh + bias)
Embedding (256 vocab, 32 dim) 8192 vocab × dim
KMeans (8 clusters, 32 dim) 256 clusters × dim
Softmax 1 neutral marker
Residual 1 neutral marker
Parallel (2× Dense 32) 1056 concat of branches, renormalized
Sequential (2× Dense 32) 2048 concat of sub-layers, renormalized