Buckets:
| from dataclasses import dataclass | |
| import numpy as np | |
| 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.