Keras Drop-In
Use neat_optim.NEAT inside
model.compile(...) with Keras 3 and a backend such
as TensorFlow.
Overview
NEAT is not neural architecture search and not a full game-theory solver. It is a small optimizer package with a Keras adapter, a NumPy reference engine, player-aware TensorFlow helpers, and an explicit math spec.
Use neat_optim.NEAT inside
model.compile(...) with Keras 3 and a backend such
as TensorFlow.
Validate the update rule with deterministic NumPy code before moving into framework-specific training.
Treat each example, task, or objective head as a gradient contributor in a custom TensorFlow training loop.
Find docs
Quickstart
Install the Keras extra when training models. Install the core package only when you need the NumPy/reference engine.
pip install "neat-optim[keras]" tensorflow
pip install neat-optim
Keras ecosystem
model.compile
The main workflow is intentionally familiar to Keras users:
create a model, pass NEAT as the optimizer, then
inspect diagnostics after training.
neat-optim[keras]keras>=3.13,<4import keras
from neat_optim import NEAT
model = keras.Sequential([
keras.layers.Input((32,)),
keras.layers.Dense(64, activation="relu"),
keras.layers.Dense(10),
])
optimizer = NEAT(
learning_rate=1e-3,
alpha=0.25,
beta=0.9,
nce_mode="projection",
opponent_source="gradient_ema",
correction_warmup_steps=5,
)
model.compile(
optimizer=optimizer,
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=["accuracy"],
)
model.fit(x_train, y_train, epochs=5)
print(optimizer.diagnostic_snapshot())
Choose a mode
Use NEAT when you want a drop-in optimizer for
regular Keras model training.
Use diagnostic_snapshot() to see conflict ratio,
correction ratio, update alignment, and active correction
fraction.
Use neat_step(...) for deterministic debugging,
algorithm experiments, and framework-independent validation.
Use player_train_step(...) when each example or
task should contribute its own gradient.
API
The package keeps a narrow public API so optimizer behavior is easier to inspect, serialize, benchmark, and test.
neat_optim.NEATKeras optimizer implementation for model.compile.
NEATConfig and ArrayStateReference engine configuration and per-parameter state.
PlayerNEATConfigConfiguration for explicit per-player gradient updates.
neat_stepFramework-agnostic one-step API for NumPy-style updates.
neat_player_stepPlayer-aware one-step API with conflict and sparsity metrics.
player_train_stepTensorFlow helper for custom loops with per-example losses.
Configuration
| Argument | Use |
|---|---|
learning_rate |
Optimizer step size. |
alpha |
Scale of the Nash correction estimate. |
beta |
Momentum mixing factor. |
nce_mode |
projection, cosine, or off. |
opponent_source |
momentum, previous_gradient, or gradient_ema. |
correction_warmup_steps |
Delay correction until a configured number of steps pass. |
conflict_threshold |
Minimum measured conflict before correction is applied. |
sparsity_l1 and prune_threshold |
Optional pressure toward sparse or pruned weights. |
Research
NEAT detects directional conflict between a gradient and an opponent proxy. When conflict is present, it applies a bounded correction before momentum and weight decay.
conflict_t = relu(-cos(g_t, o_t))
proj_t = proj_{o_t}(g_t)
nce_t = -alpha * conflict_t * proj_t
u_t = g_t + nce_t
m_t = beta * m_{t-1} + (1 - beta) * u_t
theta_t+1 = (1 - lr * wd) * theta_t - lr * m_t
Player-aware NEAT
In player-aware mode, each element along the leading dimension of
player_grads is treated as a player. The default
opponent signal is the mean of the other players.
import keras
from neat_optim import PlayerNEATConfig
from neat_optim.training import create_player_states, player_train_step
loss_fn = keras.losses.SparseCategoricalCrossentropy(
from_logits=True,
reduction="none",
)
states = create_player_states(model)
config = PlayerNEATConfig(
learning_rate=1e-2,
alpha=0.25,
beta=0.9,
sparsity_l1=1e-4,
prune_threshold=1e-3,
)
result = player_train_step(model, x_batch, y_batch, loss_fn, states, config)
states = result.states
Benchmarks
NEAT includes benchmark harnesses for sanity checks, synthetic conflict tasks, Keras MLPs, Keras vision tasks, CIFAR-10, and GLUE SST-2. The current results are early and should be read as evidence, not a universal superiority claim.
Adaptive NEAT, two epochs, seeds 7, 11, and 19.
Adaptive NEAT on the same short Keras CNN setup.
Standard NEAT trailed SGD, Adam, and AdamW in this run.
python benchmarks/run.py
python benchmarks/sweep_neat.py
Contributing
Local development uses an editable install with the development and Keras extras. Run linting, formatting, tests, build checks, and MkDocs validation before releases.
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,keras]"
ruff check .
ruff format .
pytest
python -m build
mkdocs build --strict
All docs
Use these links when you need the complete source files, long-form research notes, release workflow, or project policies.
Questions
Open an issue on GitHub for repo discussions, or email the project contact for direct questions.