Skip to main content

metawalker

Learned black-box optimizers for big, complex search spaces, packaged as a drop-in replacement for scikit-learn's GridSearchCV / RandomizedSearchCV and as a plain minimize() function.

The optimizers were trained once, with evolution strategies, on cheap synthetic problems. After that they run on numpy alone, and each policy is a few KB.

pip install "metawalker[sklearn]"        # from the repo: pip install -e ".[sklearn]"

Use it

from metawalker import minimize, Float, Int, Categorical

space = {"lr": Float(1e-5, 1e-1, log=True), "layers": Int(1, 8), "act": ["relu", "tanh"], "dropout": (0.0, 0.5)}
result = minimize(train_and_score, space, budget=300, method="auto", maximize=True, recheck=3)
result.best_params, result.best_value, result.recheck_values

As a scikit-learn search estimator (it uses the same internal hook as GridSearchCV, so cv, scoring, refit, n_jobs, cv_results_, best_params_ and best_estimator_ all behave the same):

from metawalker.sklearn import MetaWalkerCV

search = MetaWalkerCV(model, {"C": Float(1e-3, 1e3, log=True), "kernel": ["rbf", "linear"]},
                     n_iter=100, method="rlcma", cv=5).fit(X, y)

A GridSearchCV param_grid (a dict of value lists) works unchanged as param_space.

Choose your own panel: test methods on your own losses

You know your problem best, so the package helps you measure which method fits it. Give compare() your own loss functions, and optionally some simulated stand-ins shaped like your problem. It runs every method several times on each, with the same budget, and reports average rank, head-to-head win rates and time per run:

from metawalker import compare, make_problem, minimize

res = compare({"my_loss": (my_fn, my_space),
               "stand-in": make_problem("plateau", n=80, noise=0.01)},  # sphere, ellipsoid, rastrigin,
              methods=["rlcma", "walker_hp", "cmaes", "gp"],          # rosenbrock, ackley, levy, plateau
              budget=200, seeds=5)
print(res.summary())

minimize(my_fn, my_space, budget=600, method=["rlcma", "gp"])   # then run the panel you picked

The simulated problems come from the same generator as our benchmark: rotated and shifted, with a known optimum, so compare() scores them by true regret rather than by lucky noisy readings.

What else it does for you

import metawalker as mw

# 1. don't know your landscape? probe it (~8% of the budget), then let it pick from the benchmark's rules
res = mw.minimize_auto(my_fn, my_space, budget=500)
print(res.recommendation.reasons)   # e.g. "92% of probes returned the same value: a plateau objective -> walker_hp"

# 2. a best result you can trust: re-test the top candidates on fresh evaluations, pick by mean, report a CI
cert = mw.certify(my_fn, res, top_k=5, repeats=5)
print(cert.summary())               # cert.shrinkage = how much the raw best score was inflated by noise

# 3. which parameters mattered, which direction helps, and the best range (free, from the search history)
print(mw.importance(res).summary())

# 4. train an optimizer specialized to YOUR kind of problem, on cheap simulated stand-ins
policy = mw.train([lambda: my_simulator_factory()], init="walker_hp", generations=50, n_jobs=8)
policy.save("my_optimizer.npz"); policy.minimize(my_fn, my_space, budget=300)

# 5. evaluate on your own workers / cluster, or plug into an existing Optuna study
with mw.AskTell(my_space, budget=200, method="rlcma") as at:
    while not at.done:
        tid, params = at.ask(); at.tell(tid, run_somewhere(params))
from metawalker.asktell import MetaWalkerSampler   # optuna.create_study(sampler=MetaWalkerSampler(dists, budget=200))

# 6. compare methods on your own losses, in parallel
mw.compare({"mine": (my_fn, my_space)}, methods=["rlcma", "gp", "cmaes"], seeds=5, n_jobs=8)

Notes:

  • compare(n_jobs>1) and train(n_jobs>1) need picklable functions, plus an if __name__ == "__main__": guard on Windows.
  • certify() and importance() read the search direction from the Result.
  • Importance computed from an optimizer's history is biased toward the regions that optimizer sampled. Random-search histories give the cleanest estimate.

Which method

method what it is where it did best in our benchmark
rlcma CMA-ES whose step size and restarts are set by a learned policy 50–500 parameters: beat CMA-ES on 72–99% of test problems and TPE on 95%+
walker a learned multi-start walker; one small network shared by every parameter, so it runs at any size tied CMA-ES overall, won at 500 parameters; ~1 s of optimizer overhead
walker_hp the walker, also trained on plateau-shaped objectives flat, mostly-zero objectives (e.g. searching for RL honeypots); fastest to a valid high-exploit level in a 169-parameter honeypot search
walker_hp_warm walker_hp after a Latin-hypercube warm-up of 20% of the budget (warmup=0.2) recommended for rare-signal objectives, where only a tiny region scores at all: on a 0.5%-live plateau it found the region in 9/10 runs, against 1/10 (10 parameters) and 5/10 (50) for walker_hp
walker_rule hand-coded walker distilled from the learned one: move each coordinate with p = 0.6, pull 0.5 toward the best walker, step size s *= exp(0.5 (success EMA - 0.35)) as good as walker, with no network (mean rank 1.69 vs 1.83 over 12 problems)
cmaes CMA-ES with IPOP restarts (pycma) small, noisy problems (under ~20 parameters)
cmaes_rule CMA-ES with the hand rule distilled from rlcma: sigma × 0.8 after a generation that did not improve, unless stalled 5+ generations or the population is flat ties rlcma (wins 50%) and beats cmaes on 78% of runs; rlcma stays ahead on Levy/Rastrigin at 10 parameters
gp Optuna Gaussian-process Bayesian optimization (needs metawalker[optuna]) expensive objectives up to ~200 parameters: tied with rlcma overall and better at 100–200 parameters, but it costs ~1 hour of its own compute per 1000-evaluation run, and that cost grows fast with evaluations and dimensions
tpe Optuna TPE (needs metawalker[optuna]) baseline; rlcma beat it on 70–100% of problems
random random search baseline
auto cmaes below 20 parameters, rlcma from 20 up; gp up to 200 parameters if you pass expensive=True
[...] any list of methods = your own panel: the budget is split across them and the best is kept
panel the default panel: rlcma, walker_hp, cmaes when you don't know the landscape

Any method also takes warmup=f. It spends that fraction of the budget on Latin-hypercube points first, and those points count toward the budget and appear in the history. The walkers then start from the best 4 points and the CMA-based methods from the best one, while the other methods simply run on what is left. Use it when the signal is rare: without it the walkers shrink and restart instead of exploring, so plain random search finds a tiny live region more often than they do. The distilled rules come from the policy study (results/analysis/policy_report.md). The numbers above are medians over 3 seeds at budget 1000, from sphere, Rosenbrock, Rastrigin, Ackley, Levy and plateau at 10 and 50 parameters. compare() accepts all of these methods.

Benchmark scope. Rotated and shifted synthetic functions (sphere, ellipsoid, Rastrigin, Rosenbrock, plus held-out Ackley and Levy) with and without noise, a honeypot-like plateau family, and a real RL honeypot search. Budgets were 300–10,000 evaluations. Each learned method was trained 3 times from scratch, with results reported per training run. A comparison against Optuna GP, Optuna multivariate TPE, SMAC3 and Nevergrad NGOpt is in progress.

Behavior to know

  • Invalid configurations: if your function raises or returns nan/inf, that counts as a failed trial (result.n_failed). The search keeps going.
  • Noisy objectives: the best observed value is biased upward (the winner's curse). Use recheck=k to re-evaluate the winner k more times.
  • Categorical parameters are one coordinate split into equal bins. That's fine for a few choices, but unordered categoricals with many choices are a known weak spot.
  • 1-parameter searches with the CMA-based methods add an ignored dummy coordinate, because pycma needs 2+.
  • The panel budget is split equally, with no racing between methods.

Tests

pytest from the repo root. tests/test_regression.py checks that every optimizer reproduces the pre-refactor benchmark code bit for bit (tests/golden.json).

Metadata

Release files for metawalker 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for metawalker 0.2.0
File Size Uploaded Provenance Actions
metawalker-0.2.0.tar.gz 65.8 kB Without provenance Details for metawalker-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for metawalker 0.2.0
File Interpreter ABI Platform Actions
metawalker-0.2.0-py3-none-any.whl Python 3 none any Details for metawalker-0.2.0-py3-none-any.whl

Total release size: 119.4 kB

Release files / metawalker-0.2.0.tar.gz

Download URL metawalker-0.2.0.tar.gz
Size 65.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4d8593e3a1cebc4313eabd100f3f13e763ca0333464648abdbf0c790fd469ee7
BLAKE2b-256 checksum
How to use checksums
b71e4113c36347c4abdc4211f1ae93886f4d50749ac645a2bc559ff8e3892c0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / metawalker-0.2.0-py3-none-any.whl

Download URL metawalker-0.2.0-py3-none-any.whl
Size 53.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef90345352acb446a31d7e463317f93e43654e7dea9bb26c9b633d1417934ea1
BLAKE2b-256 checksum
How to use checksums
c67f79ae849f307066bee2e8f2235dc57c64b48b37a29c9208d0b4b6f4db18d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for metawalker 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page