twanghcmut's picture
download
raw
2.59 kB
from dataclasses import dataclass
import numpy as np
@dataclass
class SearchResult:
parameters: np.ndarray
loss: float
history: list
evaluations: int
def search(
objective,
mean,
std,
bounds,
population=16,
iterations=6,
elite_fraction=0.25,
seed=0,
method="cem",
callback=None,
):
mean, std, bounds = (
np.asarray(mean, float),
np.asarray(std, float),
np.asarray(bounds, float),
)
if mean.ndim != 1 or std.shape != mean.shape or bounds.shape != (len(mean), 2):
raise ValueError("Inconsistent search dimensions")
if (
not np.isfinite(mean).all()
or not np.isfinite(std).all()
or not np.isfinite(bounds).all()
):
raise ValueError("Search inputs must be finite")
if (std <= 0).any() or (bounds[:, 0] >= bounds[:, 1]).any():
raise ValueError("Invalid search variance or bounds")
if population < 2 or iterations < 1 or not 0 < elite_fraction <= 1:
raise ValueError("Invalid sampling budget or elite fraction")
if method not in ("cem", "random"):
raise ValueError("Unknown search method")
mean = np.clip(mean, bounds[:, 0], bounds[:, 1])
best, best_loss = mean.copy(), float(objective(mean))
if not np.isfinite(best_loss):
raise ValueError("Initial objective is not finite")
random = np.random.default_rng(seed)
history = [best_loss]
minimum_std = std * 0.05
elite_count = max(2, int(np.ceil(population * elite_fraction)))
for iteration in range(iterations):
candidates = np.clip(
random.normal(mean, std, (population, len(mean))),
bounds[:, 0],
bounds[:, 1],
)
losses = np.asarray(
[objective(candidate) for candidate in candidates], dtype=float
)
losses[~np.isfinite(losses)] = np.inf
index = int(losses.argmin())
if losses[index] < best_loss:
best, best_loss = candidates[index].copy(), float(losses[index])
if method == "cem":
elite = candidates[np.argsort(losses)[:elite_count]]
finite = np.isfinite(np.sort(losses)[:elite_count])
if finite.any():
elite = elite[finite]
mean = 0.2 * mean + 0.8 * elite.mean(axis=0)
std = np.maximum(0.2 * std + 0.8 * elite.std(axis=0), minimum_std)
history.append(best_loss)
if callback:
callback(iteration + 1, best_loss)
return SearchResult(best, best_loss, history, population * iterations + 1)

Xet Storage Details

Size:
2.59 kB
·
Xet hash:
30796cc1c843899ac9f6ffabcced33979f90b6470b591e7e04b14fd4d8f932a1

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.