mirror of
https://github.com/wassname/ray.git
synced 2026-06-28 17:50:55 +08:00
[tune] Add Nevergrad to Tune (#3985)
This commit is contained in:
committed by
Richard Liaw
parent
c523bc04ad
commit
dac1969647
@@ -0,0 +1,56 @@
|
||||
"""This test checks that Nevergrad is functional.
|
||||
|
||||
It also checks that it is usable with a separate scheduler.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import ray
|
||||
from ray.tune import run_experiments, register_trainable
|
||||
from ray.tune.schedulers import AsyncHyperBandScheduler
|
||||
from ray.tune.suggest import NevergradSearch
|
||||
|
||||
|
||||
def easy_objective(config, reporter):
|
||||
import time
|
||||
time.sleep(0.2)
|
||||
for i in range(config["iterations"]):
|
||||
reporter(
|
||||
timesteps_total=i,
|
||||
neg_mean_loss=-(config["height"] - 14)**2 +
|
||||
abs(config["width"] - 3))
|
||||
time.sleep(0.02)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
from nevergrad.optimization import optimizerlib
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--smoke-test", action="store_true", help="Finish quickly for testing")
|
||||
args, _ = parser.parse_known_args()
|
||||
ray.init(redirect_output=True)
|
||||
|
||||
register_trainable("exp", easy_objective)
|
||||
|
||||
config = {
|
||||
"nevergrad": {
|
||||
"run": "exp",
|
||||
"num_samples": 10 if args.smoke_test else 50,
|
||||
"config": {
|
||||
"iterations": 100,
|
||||
},
|
||||
"stop": {
|
||||
"timesteps_total": 100
|
||||
},
|
||||
}
|
||||
}
|
||||
optimizer = optimizerlib.OnePlusOne(dimension=2)
|
||||
algo = NevergradSearch(
|
||||
optimizer, ["height", "width"],
|
||||
max_concurrent=4,
|
||||
reward_attr="neg_mean_loss")
|
||||
scheduler = AsyncHyperBandScheduler(reward_attr="neg_mean_loss")
|
||||
run_experiments(config, search_alg=algo, scheduler=scheduler)
|
||||
@@ -3,6 +3,7 @@ from ray.tune.suggest.basic_variant import BasicVariantGenerator
|
||||
from ray.tune.suggest.suggestion import SuggestionAlgorithm
|
||||
from ray.tune.suggest.bayesopt import BayesOptSearch
|
||||
from ray.tune.suggest.hyperopt import HyperOptSearch
|
||||
from ray.tune.suggest.nevergrad import NevergradSearch
|
||||
from ray.tune.suggest.skopt import SkOptSearch
|
||||
from ray.tune.suggest.sigopt import SigOptSearch
|
||||
from ray.tune.suggest.variant_generator import grid_search, function, \
|
||||
@@ -13,6 +14,7 @@ __all__ = [
|
||||
"BasicVariantGenerator",
|
||||
"BayesOptSearch",
|
||||
"HyperOptSearch",
|
||||
"NevergradSearch",
|
||||
"SkOptSearch",
|
||||
"SigOptSearch",
|
||||
"SuggestionAlgorithm",
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
try:
|
||||
import nevergrad
|
||||
except Exception:
|
||||
nevergrad = None
|
||||
|
||||
from ray.tune.suggest.suggestion import SuggestionAlgorithm
|
||||
|
||||
|
||||
class NevergradSearch(SuggestionAlgorithm):
|
||||
"""A wrapper around Nevergrad to provide trial suggestions.
|
||||
|
||||
Requires Nevergrad to be installed.
|
||||
Nevergrad is an open source tool from Facebook for derivative free
|
||||
optimization of parameters and/or hyperparameters. It features a wide
|
||||
range of optimizers in a standard ask and tell interface. More information
|
||||
can be found at https://github.com/facebookresearch/nevergrad.
|
||||
|
||||
Parameters:
|
||||
optimizer (nevergrad.optimization.Optimizer): Optimizer provided
|
||||
from Nevergrad.
|
||||
parameter_names (list): List of parameter names. Should match
|
||||
the dimension of the optimizer output.
|
||||
max_concurrent (int): Number of maximum concurrent trials. Defaults
|
||||
to 10.
|
||||
reward_attr (str): The training result objective value attribute.
|
||||
This refers to an increasing value.
|
||||
|
||||
Example:
|
||||
>>> from nevergrad.optimization import optimizerlib
|
||||
>>> optimizer = optimizerlib.OnePlusOne(dimension=1, budget=100)
|
||||
>>> config = {
|
||||
>>> "my_exp": {
|
||||
>>> "run": "exp",
|
||||
>>> "num_samples": 10,
|
||||
>>> "stop": {
|
||||
>>> "training_iteration": 100
|
||||
>>> },
|
||||
>>> }
|
||||
>>> }
|
||||
>>> algo = NevergradSearch(
|
||||
>>> optimizer, max_concurrent=4, reward_attr="neg_mean_loss")
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
optimizer,
|
||||
parameter_names,
|
||||
max_concurrent=10,
|
||||
reward_attr="episode_reward_mean",
|
||||
**kwargs):
|
||||
assert nevergrad is not None, "Nevergrad must be installed!"
|
||||
assert type(max_concurrent) is int and max_concurrent > 0
|
||||
self._max_concurrent = max_concurrent
|
||||
self._parameters = parameter_names
|
||||
self._reward_attr = reward_attr
|
||||
self._nevergrad_opt = optimizer
|
||||
self._live_trial_mapping = {}
|
||||
super(NevergradSearch, self).__init__(**kwargs)
|
||||
|
||||
def _suggest(self, trial_id):
|
||||
if self._num_live_trials() >= self._max_concurrent:
|
||||
return None
|
||||
suggested_config = self._nevergrad_opt.ask()
|
||||
self._live_trial_mapping[trial_id] = suggested_config
|
||||
return dict(zip(self._parameters, suggested_config))
|
||||
|
||||
def on_trial_result(self, trial_id, result):
|
||||
pass
|
||||
|
||||
def on_trial_complete(self,
|
||||
trial_id,
|
||||
result=None,
|
||||
error=False,
|
||||
early_terminated=False):
|
||||
"""Passes the result to Nevergrad unless early terminated or errored.
|
||||
|
||||
The result is internally negated when interacting with Nevergrad
|
||||
so that Nevergrad Optimizers can "maximize" this value,
|
||||
as it minimizes on default.
|
||||
"""
|
||||
ng_trial_info = self._live_trial_mapping.pop(trial_id)
|
||||
if result:
|
||||
self._nevergrad_opt.tell(ng_trial_info, -result[self._reward_attr])
|
||||
|
||||
def _num_live_trials(self):
|
||||
return len(self._live_trial_mapping)
|
||||
Reference in New Issue
Block a user