mlos_bench.optimizers.grid_search_optimizer
Grid search Optimizer for mlos_bench.
Grid search is a simple optimizer that exhaustively searches the configuration space.
To do this it generates a grid of configurations to try, and then suggests them one by one.
Therefore, the number of configurations to try is the product of the
cardinality of each of the
tunables.
(i.e., non quantized
tunables are not supported).
Examples
Load tunables from a JSON string.
Note: normally these would be automatically loaded from the
Environment’s
include_tunables config parameter.
>>> import json5 as json
>>> from mlos_bench.environments.status import Status
>>> from mlos_bench.services.config_persistence import ConfigPersistenceService
>>> service = ConfigPersistenceService()
>>> json_config = '''
... {
... "group_1": {
... "cost": 1,
... "params": {
... "colors": {
... "type": "categorical",
... "values": ["red", "blue", "green"],
... "default": "green",
... },
... "int_param": {
... "type": "int",
... "range": [1, 3],
... "default": 2,
... },
... "float_param": {
... "type": "float",
... "range": [0, 1],
... "default": 0.5,
... // Quantize the range into 3 bins
... "quantization_bins": 3,
... }
... }
... }
... }
... '''
>>> tunables = service.load_tunables(jsons=[json_config])
>>> # Check the defaults:
>>> tunables.get_param_values()
{'colors': 'green', 'int_param': 2, 'float_param': 0.5}
Now create a GridSearchOptimizer from a JSON config string.
>>> optimizer_json_config = '''
... {
... "class": "mlos_bench.optimizers.grid_search_optimizer.GridSearchOptimizer",
... "description": "GridSearchOptimizer",
... "config": {
... "max_suggestions": 100,
... "optimization_targets": {"score": "max"},
... "start_with_defaults": true
... }
... }
... '''
>>> config = json.loads(optimizer_json_config)
>>> grid_search_optimizer = service.build_optimizer(
... tunables=tunables,
... service=service,
... config=config,
... )
>>> # Should have 3 values for each of the 3 tunables
>>> len(list(grid_search_optimizer.pending_configs))
27
>>> next(grid_search_optimizer.pending_configs)
{'colors': 'red', 'float_param': 0, 'int_param': 1}
Here are some examples of suggesting and registering configurations.
>>> suggested_config_1 = grid_search_optimizer.suggest()
>>> # Default should be suggested first, per json config.
>>> suggested_config_1.get_param_values()
{'colors': 'green', 'int_param': 2, 'float_param': 0.5}
>>> # Get another suggestion.
>>> # Note that multiple suggestions can be pending prior to
>>> # registering their scores, supporting parallel trial execution.
>>> suggested_config_2 = grid_search_optimizer.suggest()
>>> suggested_config_2.get_param_values()
{'colors': 'red', 'int_param': 1, 'float_param': 0.0}
>>> # Register some scores.
>>> # Note: Maximization problems track negative scores to produce a minimization problem.
>>> grid_search_optimizer.register(suggested_config_1, Status.SUCCEEDED, {"score": 42})
{'score': -42.0}
>>> grid_search_optimizer.register(suggested_config_2, Status.SUCCEEDED, {"score": 7})
{'score': -7.0}
>>> (best_score, best_config) = grid_search_optimizer.get_best_observation()
>>> best_score
{'score': 42.0}
>>> assert best_config == suggested_config_1
Classes
Grid search optimizer. |
Module Contents
- class mlos_bench.optimizers.grid_search_optimizer.GridSearchOptimizer(tunables: mlos_bench.tunables.tunable_groups.TunableGroups, config: dict, global_config: dict | None = None, service: mlos_bench.services.base_service.Service | None = None)[source]
Bases:
mlos_bench.optimizers.track_best_optimizer.TrackBestOptimizerGrid search optimizer.
See
abovefor more details.Create a new optimizer for the given configuration space defined by the tunables.
- Parameters:
tunables (TunableGroups) – The tunables to optimize.
config (dict) – Free-format key/value pairs of configuration parameters to pass to the optimizer.
global_config (dict | None)
service (Service | None)
- bulk_register(configs: collections.abc.Sequence[dict], scores: collections.abc.Sequence[dict[str, mlos_bench.tunables.tunable_types.TunableValue] | None], status: collections.abc.Sequence[mlos_bench.environments.status.Status] | None = None) bool[source]
Pre-load the optimizer with the bulk data from previous experiments.
- Parameters:
configs (Sequence[dict]) – Records of tunable values from other experiments.
scores (Sequence[Optional[dict[str, TunableValue]]]) – Benchmark results from experiments that correspond to configs.
status (Optional[Sequence[Status]]) – Status of the experiments that correspond to configs.
- Returns:
is_not_empty – True if there is data to register, false otherwise.
- Return type:
- not_converged() bool[source]
Return True if not converged, False otherwise.
Base implementation just checks the iteration count.
- Return type:
- register(tunables: mlos_bench.tunables.tunable_groups.TunableGroups, status: mlos_bench.environments.status.Status, score: dict[str, mlos_bench.tunables.tunable_types.TunableValue] | None = None) dict[str, float] | None[source]
Register the observation for the given configuration.
- Parameters:
tunables (TunableGroups) – The configuration that has been benchmarked. Usually it’s the same config that the .suggest() method returned.
status (Status) – Final status of the experiment (e.g., SUCCEEDED or FAILED).
score (Optional[dict[str, TunableValue]]) – A dict with the final benchmark results. None if the experiment was not successful.
- Returns:
value – Benchmark scores extracted (and possibly transformed) from the dataframe that’s being MINIMIZED.
- Return type:
- suggest() mlos_bench.tunables.tunable_groups.TunableGroups[source]
Generate the next grid search suggestion.
- Return type:
- property pending_configs: collections.abc.Iterable[dict[str, mlos_bench.tunables.tunable_types.TunableValue]][source]
Gets the set of pending configs in this grid search optimizer.
- Return type:
Iterable[dict[str, TunableValue]]
- property suggested_configs: collections.abc.Iterable[dict[str, mlos_bench.tunables.tunable_types.TunableValue]][source]
Gets the set of configs that have been suggested but not yet registered.
- Return type:
Iterable[dict[str, TunableValue]]