Skip to content

jhetchan/rabbit-brain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

Rabbit Brain Source Code

This directory contains the clean, modular implementation of the Neurosymbolic Rabbit Brain classifier described in our NeurIPS 2025 NeurReps workshop paper.

File Structure

  • data.py: Two Spirals dataset generation
  • rabbit_brain.py: Core implementation of the two-Julia comparator (minimal instantiation)
  • enhanced.py: Enhanced version with log-polar prewarp, soft escape scoring, etc.
  • baselines.py: Baseline classifiers (Logistic Regression, RBF-SVM)
  • evaluation.py: Multi-run evaluation for statistical reporting

Train/Test Split Requirements

To reproduce the results reported in the paper, you MUST use random_state=42 in train_test_split.

The paper results were generated using:

from data import get_train_test_split

# Correct way (matches paper)
X_train, X_test, y_train, y_test = get_train_test_split()

DO NOT use simple array slicing like X[:840] or X[840:] as this produces a completely different train/test split and will not reproduce the reported results.

Quick Start

Basic Usage (Minimal Instantiation)

from data import get_train_test_split  # Use this function!
from rabbit_brain import predict, accuracy
import cma

# Generate data with correct split
X_train, X_test, y_train, y_test = get_train_test_split()

# Define optimization objective
def fitness(params):
    yhat = predict(params, X_train)
    return (yhat != y_train).mean()

# Initialize CMA-ES
x0 = [1.0, 0.0, 0.0, 0.0, 0.1, 0.1, -0.1, -0.1]
es = cma.CMAEvolutionStrategy(x0, 0.5, {'maxiter': 200})

# Optimize
best_params = None
best_acc = 0.0
while not es.stop():
    solutions = es.ask()
    fitnesses = [fitness(p) for p in solutions]
    es.tell(solutions, fitnesses)

    for sol, fit in zip(solutions, fitnesses):
        if (1 - fit) > best_acc:
            best_acc = 1 - fit
            best_params = sol

# Evaluate
test_acc = accuracy(best_params, X_test, y_test)
print(f"Test accuracy: {test_acc:.1%}")

Multi-Run Evaluation

from data import get_train_test_split
from evaluation import evaluate_multiple_runs

# Generate data with correct split
X_train, X_test, y_train, y_test = get_train_test_split()

# Run 10 independent optimizations
results = evaluate_multiple_runs(
    X_train, y_train, X_test, y_test,
    n_runs=10,
    max_iter=200
)

print(f"Mean test accuracy: {results['test_mean']:.1%} ± {results['test_std']:.1%}")

Compare with Baselines

from data import two_spirals
from baselines import train_logistic_baseline, train_rbf_svm_baseline
from sklearn.model_selection import train_test_split

X, y = two_spirals()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

# Logistic regression
lr_results = train_logistic_baseline(X_train, y_train, X_test, y_test)
print(f"Logistic Regression: {lr_results['test_acc']:.1%}")

# RBF-SVM
svm_results = train_rbf_svm_baseline(X_train, y_train, X_test, y_test)
print(f"RBF-SVM: {svm_results['test_acc']:.1%}")

Generate Decision Boundary Plots

# Generate comparison plots (baseline vs enhanced)
cd src
python3 visualization.py

This generates baseline_vs_enhanced.png showing the decision boundaries and test accuracies for both models.

Reproducing Paper Results

All experiments use fixed data seed (7) and train/test split (random_state=42). Only CMA-ES seed varies across runs to isolate optimization variance.

Baseline (Minimal Instantiation)

Expected: 54.3% ± 2.1% test accuracy

from data import get_train_test_split
from evaluation import evaluate_multiple_runs

X_train, X_test, y_train, y_test = get_train_test_split()
results = evaluate_multiple_runs(X_train, y_train, X_test, y_test, n_runs=10)

Enhanced Model (with Curriculum Learning)

Expected: Improvement over baseline (uses identical data/split for fair comparison)

from enhanced_consistent import evaluate_enhanced_consistent

results = evaluate_enhanced_consistent(n_runs=10, max_iter=400)

Both use: two_spirals(seed=7)train_test_split(random_state=42) → vary CMA-ES seed

Enhancements applied in enhanced_consistent.py:

  • Log-polar prewarp for spiral linearization
  • Soft escape scoring for smoother boundaries
  • Curriculum learning on (T, R) parameters

Representative Parameters (Appendix A)

Baseline run (seed 49, 57.2% test):

params = [
    0.2001,    # s (scale)
    1.2112,    # phi (rotation)
    -1.0225,   # tx (translation x)
    0.0662,    # ty (translation y)
    1.5407,    # c1 real
    -1.6728,   # c1 imaginary
    0.3579,    # c2 real
    1.5169     # c2 imaginary
]

To reproduce the exact test accuracy from this run (57.2%):

from rabbit_brain import predict, accuracy
from data import get_train_test_split

# CRITICAL: Use the same train/test split as the paper
X_train, X_test, y_train, y_test = get_train_test_split()

# Evaluate on test set
test_acc = accuracy(params, X_test, y_test)
print(f"Test Accuracy: {test_acc:.1%}")  # Should give ~57.2%

Parameter Interpretation

The 8-parameter vector θ = [s, φ, tx, ty, c₁ᵣₑ, c₁ᵢₘ, c₂ᵣₑ, c₂ᵢₘ] defines:

  1. Affine prewarp (first 4 params):

    • s: Scale factor
    • φ: Rotation angle (radians)
    • tx, ty: Translation offsets
  2. Julia set parameters (last 4 params):

    • c₁ = c₁ᵣₑ + i·c₁ᵢₘ: First Julia set constant
    • c₂ = c₂ᵣₑ + i·c₂ᵢₘ: Second Julia set constant

Classification Rule

For input point (x, y):

  1. Transform: z₀ = s·exp(iφ)·(x + iy) + (tx + ity)
  2. Compute escape times:
    • t₁ = escape_time(z₀, c₁) under iteration z ↦ z² + c₁
    • t₂ = escape_time(z₀, c₂) under iteration z ↦ z² + c₂
  3. Classify: class = 0 if t₁ ≥ t₂ else 1

The decision boundary is the set of points where both Julia sets have equal escape times.

Setup and Installation

Create Virtual Environment

# Create virtual environment
python3 -m venv venv

# Activate it
source venv/bin/activate  # On macOS/Linux
# or
venv\Scripts\activate     # On Windows

Install Dependencies

pip install numpy matplotlib scikit-learn cma

Dependencies

  • numpy - Numerical computing
  • matplotlib - Plotting and visualization
  • scikit-learn - Machine learning (train/test split, preprocessing)
  • cma - CMA-ES optimization algorithm

Citation

If you use this code, please cite our paper:

@inproceedings{jhet2025rabbibrain,
  title={Neurosymbolic Rabbit Brain: Fractal Attractor Geometry for Neural Representations},
  author={Jhet Chan},
  booktitle={NeurIPS 2025 NeurReps Workshop},
  year={2025}
}

About

Neurosymbolic Rabbit Brain: Attractor Geometry for Neural Representations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages