Skip to main content

A lightweight NEAT library with PyTorch integration

Project description

NEATify

A modern, production-ready implementation of NEAT (NeuroEvolution of Augmenting Topologies) with PyTorch integration.

Features

[!TIP] New to NEAT? Check out our Comprehensive User Guide for a step-by-step tutorial!

Core Evolution

  • NEAT Algorithm: Complete implementation with speciation and innovation tracking
  • Dynamic Speciation: Automatic compatibility threshold adjustment
  • Advanced Mutations: Weight perturbation, topology mutations, activation mutations
  • Elitism: Preserve best genomes across generations
  • Configurable: Extensive hyperparameter control

PyTorch Integration

  • Efficient Inference: Convert genomes to PyTorch modules
  • Recurrent Networks: Full support for cyclic topologies
  • Sparse Mode: Optimized batch processing for large networks
  • Gradient Fine-Tuning: Register weights as nn.Parameter for hybrid evolution + learning
  • Bidirectional Sync: Update genomes with trained weights

Production Features

  • Checkpointing: Save/load population state
  • Serialization: JSON and Pickle export/import
  • Visualization: Species plots, genome graphs, complexity tracking
  • Benchmarks: XOR, LunarLander, function approximation
  • Hyperparameter Tuning: Grid and random search utilities

Installation

pip install neatify-ai

Quick Start

from neatify import Population, EvolutionConfig, NeatModule
import torch

# Configure evolution
config = EvolutionConfig()
config.population_size = 150
config.prob_add_connection = 0.3
config.prob_add_node = 0.1

# Create population
pop = Population(pop_size=150, num_inputs=2, num_outputs=1, config=config)

# Define fitness function
def fitness_fn(genomes):
    for genome in genomes:
        model = NeatModule(genome)
        # ... evaluate model ...
        genome.fitness = score

# Evolve
for generation in range(100):
    pop.run_generation(fitness_fn)
    best = max(pop.genomes, key=lambda g: g.fitness)
    print(f"Gen {generation}: Best fitness = {best.fitness:.4f}")

Examples

XOR Problem

python examples/xor_solve.py

LunarLander-v2

python examples/lunarlander_solve.py

Function Approximation

python examples/function_approx.py

Visualization Demo

python examples/visualization_demo.py

Hyperparameter Tuning

python examples/hyperparam_search.py --method random --trials 50

Hybrid Evolution + Learning

from neatify import NeatModule, Checkpoint
import torch.optim as optim

# 1. Evolve topology
pop.run_generation(fitness_fn)
best_genome = max(pop.genomes, key=lambda g: g.fitness)

# 2. Fine-tune weights with gradient descent
model = NeatModule(best_genome, trainable=True)
optimizer = optim.Adam(model.parameters(), lr=0.01)

for epoch in range(100):
    optimizer.zero_grad()
    output = model(input_data)
    loss = criterion(output, target)
    loss.backward()
    optimizer.step()

# 3. Sync weights back to genome
model.update_genome_weights()

# 4. Continue evolution with improved weights
pop.genomes[0] = best_genome
pop.run_generation(fitness_fn)

Checkpointing

from neatify import Checkpoint

# Save population state
Checkpoint.save(pop, "checkpoint_gen100.pkl")

# Load and resume
pop = Checkpoint.load("checkpoint_gen100.pkl")
pop.run_generation(fitness_fn)

# Save best genome
best = max(pop.genomes, key=lambda g: g.fitness)
Checkpoint.save_best(best, "best_genome.pkl")

# Export to JSON (human-readable)
Checkpoint.export_genome_json(best, "best_genome.json")

Visualization

from neatify.visualization import (
    plot_species_distribution,
    visualize_genome,
    plot_complexity_evolution
)

# Track evolution history
history = []
for gen in range(100):
    pop.run_generation(fitness_fn)
    history.append(copy.deepcopy(pop))

# Generate plots
plot_species_distribution(history, "species.png")
visualize_genome(best_genome, "network.png")
plot_complexity_evolution(history, "complexity.png")

Configuration

from neatify import EvolutionConfig

config = EvolutionConfig()

# Population
config.population_size = 150
config.elitism_count = 3
config.target_species = 5

# Mutations
config.prob_mutate_weight = 0.8
config.prob_add_connection = 0.3
config.prob_add_node = 0.1
config.prob_mutate_activation = 0.1

# Weight mutations
config.prob_replace_weight = 0.1
config.weight_mutation_power = 0.5
config.weight_perturbation_type = 'gaussian'  # or 'uniform'
config.weight_min_value = -30.0
config.weight_max_value = 30.0

# Speciation
config.compatibility_threshold = 3.0
config.c1 = 1.0  # Excess genes coefficient
config.c2 = 1.0  # Disjoint genes coefficient
config.c3 = 0.4  # Weight difference coefficient

Testing

Run all tests:

python tests/test_dynamic_threshold.py
python tests/test_elitism.py
python tests/test_weight_mutation.py
python tests/test_recurrent.py
python tests/test_activations_adapter.py
python tests/test_fine_tuning.py
python tests/test_weight_sync.py
python tests/test_checkpoint.py

Architecture

src/neatify/
├── core.py              # Genome, NodeGene, ConnectionGene
├── evolution.py         # Mutation operators, crossover, config
├── population.py        # Population management, speciation
├── pytorch_adapter.py   # PyTorch integration
├── checkpoint.py        # Save/load utilities
├── visualization.py     # Plotting functions
└── distributed/         # Distributed NEAT components

examples/
├── xor_solve.py         # Basic XOR solver
├── distributed_xor_*.py # Distributed XOR examples
├── lunarlander_solve.py # Continuous control
└── ...

tests/
├── test_*.py            # Unit tests
└── benchmark_batch.py   # Performance benchmarks

Performance

  • Sparse Mode: 3-5x faster for large, sparse networks
  • Batch Processing: Efficient GPU utilization
  • Checkpointing: Minimal overhead (~1% of evolution time)

Documentation

  • User Guide: Step-by-step tutorials, advanced usage, and best practices.
  • Walkthrough: Technical details and implementation history.
  • Examples: Practical demonstration scripts.

Citation

If you use NEATify in your research, please cite:

@software{neatify_ai_2025,
  title = {neatify-ai: Modern NEAT Implementation with PyTorch},
  year = {2025},
  url = {https://github.com/Supreme-Shrestha/neatify-ai}
}

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please see CONTRIBUTING.md for guidelines.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

neatify_ai-0.1.1.tar.gz (34.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

neatify_ai-0.1.1-py3-none-any.whl (28.2 kB view details)

Uploaded Python 3

File details

Details for the file neatify_ai-0.1.1.tar.gz.

File metadata

  • Download URL: neatify_ai-0.1.1.tar.gz
  • Upload date:
  • Size: 34.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for neatify_ai-0.1.1.tar.gz
Algorithm Hash digest
SHA256 40351021428cb2c3dfce9307d3fddbbc22c5bbac9e8f88f5b00c560f9f3dfcee
MD5 ae93a1ad6b74a447bcf30dc66c21b6df
BLAKE2b-256 866ad38917a24bc9833d5ffeef22f4e636171a2476874cedee042805765c8c1b

See more details on using hashes here.

File details

Details for the file neatify_ai-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: neatify_ai-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 28.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for neatify_ai-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ecf6cf17f04708cdb00ba723962e0f1c8773be7da9569a8bb8f671682f69fe92
MD5 d7ba3f369a5d4c92e9297d0bbd471cb4
BLAKE2b-256 782debef3cad19dcc4956be3818e62dd5ce1d77712c0709fc94f1e15871ea2b0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page