Hyperactive#

Hyperactive is an advanced optimization toolkit built on top of Gradient-Free-Optimizers. It provides additional features for hyperparameter optimization.


Installation#

pip install hyperactive

Basic Usage#

from hyperactive import Hyperactive
from surfaces.test_functions.algebraic import RastriginFunction

func = RastriginFunction(n_dim=5)

hyper = Hyperactive()
hyper.add_search(func, func.search_space(), n_iter=100)
hyper.run()

print(f"Best score: {hyper.best_score(func)}")
print(f"Best params: {hyper.best_para(func)}")

Multiple Searches#

Run multiple optimizations in parallel:

from surfaces.test_functions.algebraic import SphereFunction, RastriginFunction, AckleyFunction

sphere = SphereFunction(n_dim=5)
rastrigin = RastriginFunction(n_dim=5)
ackley = AckleyFunction()

hyper = Hyperactive()

# Add multiple searches
hyper.add_search(sphere, sphere.search_space(), n_iter=100)
hyper.add_search(rastrigin, rastrigin.search_space(), n_iter=100)
hyper.add_search(ackley, ackley.search_space(), n_iter=100)

# Run all in parallel
hyper.run(max_workers=3)

# Get results
for func in [sphere, rastrigin, ackley]:
    print(f"{func.__class__.__name__}: {hyper.best_score(func):.6f}")

Optimizer Selection#

from hyperactive.optimizers import (
    RandomSearchOptimizer,
    BayesianOptimizer,
    ParticleSwarmOptimizer,
)

hyper = Hyperactive()

# Different optimizers for different functions
hyper.add_search(
    sphere,
    sphere.search_space(),
    optimizer=BayesianOptimizer(),
    n_iter=100,
)

hyper.add_search(
    rastrigin,
    rastrigin.search_space(),
    optimizer=ParticleSwarmOptimizer(population=20),
    n_iter=100,
)

hyper.run()

Memory and Warm Starting#

# Enable memory to track all evaluations
hyper.add_search(
    func,
    func.search_space(),
    n_iter=100,
    memory=True,
)
hyper.run()

# Access search history
search_data = hyper.search_data(func)

# Warm start from previous results
hyper2 = Hyperactive()
hyper2.add_search(
    func,
    func.search_space(),
    n_iter=100,
    memory_warm_start=search_data,
)
hyper2.run()

Progress Tracking#

hyper.add_search(
    func,
    func.search_space(),
    n_iter=100,
    verbosity=["progress_bar", "print_results"],
)

Constraints#

Add constraints to the search:

def constraint(params):
    # Return True if valid
    return params["x0"] + params["x1"] < 5.0

hyper.add_search(
    func,
    func.search_space(),
    n_iter=100,
    constraints=[constraint],
)

Benchmarking Setup#

from hyperactive import Hyperactive
from hyperactive.optimizers import BayesianOptimizer, RandomSearchOptimizer
from surfaces.test_functions.algebraic import RastriginFunction
import numpy as np

func = RastriginFunction(n_dim=10)

# Run multiple trials
results = {"Bayesian": [], "Random": []}

for seed in range(10):
    for name, opt in [("Bayesian", BayesianOptimizer()),
                      ("Random", RandomSearchOptimizer())]:
        hyper = Hyperactive()
        hyper.add_search(
            func,
            func.search_space(),
            optimizer=opt,
            n_iter=100,
            random_state=seed,
        )
        hyper.run()
        results[name].append(hyper.best_score(func))

for name, scores in results.items():
    print(f"{name}: {np.mean(scores):.4f} +/- {np.std(scores):.4f}")

Hyperactive vs GFO#

Feature

GFO

Hyperactive

API

Low-level

High-level

Parallel

Manual

Built-in

Warm start

Manual

Built-in

Constraints

No

Yes

Multiple searches

Manual

Built-in


Next Steps#