Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/requirements-doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ sphinx_rtd_theme
tabulate
uvicorn
werkzeug
tune-sklearn==0.0.5
git+git://github.com/ray-project/tune-sklearn@master#tune-sklearn
scikit-optimize
2 changes: 1 addition & 1 deletion doc/source/tune/_tutorials/tune-sklearn.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
clf,
parameter_grid,
search_optimization="bayesian",
n_iter=3,
n_trials=3,
early_stopping=True,
max_iters=10,
)
Expand Down
2 changes: 1 addition & 1 deletion python/ray/tune/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ py_test(

py_test(
name = "test_sample",
size = "medium",
size = "small",
srcs = ["tests/test_sample.py"],
deps = [":tune_lib"],
tags = ["exclusive"],
Expand Down
2 changes: 1 addition & 1 deletion python/ray/tune/examples/mnist_pytorch.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def train_mnist(config):
else:
ray.init(num_cpus=2 if args.smoke_test else None)
sched = AsyncHyperBandScheduler(
time_attr="training_iteration", metric="mean_accuracy")
time_attr="training_iteration", metric="mean_accuracy", mode="max")
analysis = tune.run(
train_mnist,
name="exp",
Expand Down
4 changes: 3 additions & 1 deletion python/ray/tune/examples/mnist_pytorch_trainable.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ def load_checkpoint(self, checkpoint_path):
if __name__ == "__main__":
args = parser.parse_args()
ray.init(address=args.ray_address, num_cpus=6 if args.smoke_test else None)
sched = ASHAScheduler(metric="mean_accuracy")
sched = ASHAScheduler()
analysis = tune.run(
TrainMNIST,
metric="mean_accuracy",
mode="max",
scheduler=sched,
stop={
"mean_accuracy": 0.95,
Expand Down
4 changes: 2 additions & 2 deletions python/ray/tune/schedulers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

def create_scheduler(
scheduler,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
**kwargs,
):
"""Instantiate a scheduler based on the given string.
Expand Down
39 changes: 34 additions & 5 deletions python/ray/tune/schedulers/async_hyperband.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class AsyncHyperBandScheduler(FIFOScheduler):
def __init__(self,
time_attr="training_iteration",
reward_attr=None,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
max_t=100,
grace_period=1,
reduction_factor=4,
Expand All @@ -49,7 +49,8 @@ def __init__(self,
assert grace_period > 0, "grace_period must be positive!"
assert reduction_factor > 1, "Reduction Factor not valid!"
assert brackets > 0, "brackets must be positive!"
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'!"
if mode:
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'!"

if reward_attr is not None:
mode = "max"
Expand All @@ -73,13 +74,41 @@ def __init__(self,
self._counter = 0 # for
self._num_stopped = 0
self._metric = metric
if mode == "max":
self._mode = mode
self._metric_op = None
if self._mode == "max":
self._metric_op = 1.
elif mode == "min":
elif self._mode == "min":
self._metric_op = -1.
self._time_attr = time_attr

def set_search_properties(self, metric, mode):
if self._metric and metric:
return False
if self._mode and mode:
return False

if metric:
self._metric = metric
if mode:
self._mode = mode

if self._mode == "max":
self._metric_op = 1.
elif self._mode == "min":
self._metric_op = -1.

return True

def on_trial_add(self, trial_runner, trial):
if not self._metric or not self._metric_op:
raise ValueError(
"{} has been instantiated without a valid `metric` ({}) or "
"`mode` ({}) parameter. Either pass these parameters when "
"instantiating the scheduler, or pass them as parameters "
"to `tune.run()`".format(self.__class__.__name__, self._metric,
self._mode))

sizes = np.array([len(b._rungs) for b in self._brackets])
probs = np.e**(sizes - sizes.max())
normalized = probs / probs.sum()
Expand Down
7 changes: 7 additions & 0 deletions python/ray/tune/schedulers/hb_bohb.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ def on_trial_add(self, trial_runner, trial):
to current bracket. Else, create new iteration, create new bracket,
add to bracket.
"""
if not self._metric or not self._metric_op:
raise ValueError(
"{} has been instantiated without a valid `metric` ({}) or "
"`mode` ({}) parameter. Either pass these parameters when "
"instantiating the scheduler, or pass them as parameters "
"to `tune.run()`".format(self.__class__.__name__, self._metric,
self._mode))

cur_bracket = self._state["bracket"]
cur_band = self._hyperbands[self._state["band_idx"]]
Expand Down
39 changes: 34 additions & 5 deletions python/ray/tune/schedulers/hyperband.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,13 @@ class HyperBandScheduler(FIFOScheduler):
def __init__(self,
time_attr="training_iteration",
reward_attr=None,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
max_t=81,
reduction_factor=3):
assert max_t > 0, "Max (time_attr) not valid!"
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'!"
if mode:
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'!"

if reward_attr is not None:
mode = "max"
Expand All @@ -108,19 +109,47 @@ def __init__(self,
self._state = {"bracket": None, "band_idx": 0}
self._num_stopped = 0
self._metric = metric
if mode == "max":
self._mode = mode
self._metric_op = None

if self._mode == "max":
self._metric_op = 1.
elif mode == "min":
elif self._mode == "min":
self._metric_op = -1.
self._time_attr = time_attr

def set_search_properties(self, metric, mode):
if self._metric and metric:
return False
if self._mode and mode:
return False

if metric:
self._metric = metric
if mode:
self._mode = mode

if self._mode == "max":
self._metric_op = 1.
elif self._mode == "min":
self._metric_op = -1.

return True

def on_trial_add(self, trial_runner, trial):
"""Adds new trial.

On a new trial add, if current bracket is not filled,
add to current bracket. Else, if current band is not filled,
create new bracket, add to current bracket.
Else, create new iteration, create new bracket, add to bracket."""
if not self._metric or not self._metric_op:
raise ValueError(
"{} has been instantiated without a valid `metric` ({}) or "
"`mode` ({}) parameter. Either pass these parameters when "
"instantiating the scheduler, or pass them as parameters "
"to `tune.run()`".format(self.__class__.__name__, self._metric,
self._mode))

cur_bracket = self._state["bracket"]
cur_band = self._hyperbands[self._state["band_idx"]]
Expand Down
45 changes: 39 additions & 6 deletions python/ray/tune/schedulers/median_stopping_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@ class MedianStoppingRule(FIFOScheduler):
def __init__(self,
time_attr="time_total_s",
reward_attr=None,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
grace_period=60.0,
min_samples_required=3,
min_time_slice=0,
hard_stop=True):
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'!"
if reward_attr is not None:
mode = "max"
metric = reward_attr
Expand All @@ -60,15 +59,49 @@ def __init__(self,
self._min_samples_required = min_samples_required
self._min_time_slice = min_time_slice
self._metric = metric
assert mode in {"min", "max"}, "`mode` must be 'min' or 'max'."
self._worst = float("-inf") if mode == "max" else float("inf")
self._compare_op = max if mode == "max" else min
self._worst = None
self._compare_op = None

self._mode = mode
if mode:
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'."
self._worst = float("-inf") if self._mode == "max" else float(
"inf")
self._compare_op = max if self._mode == "max" else min

self._time_attr = time_attr
self._hard_stop = hard_stop
self._trial_state = {}
self._last_pause = collections.defaultdict(lambda: float("-inf"))
self._results = collections.defaultdict(list)

def set_search_properties(self, metric, mode):
if self._metric and metric:
return False
if self._mode and mode:
return False

if metric:
self._metric = metric
if mode:
self._mode = mode

self._worst = float("-inf") if self._mode == "max" else float("inf")
self._compare_op = max if self._mode == "max" else min

return True

def on_trial_add(self, trial_runner, trial):
if not self._metric or not self._worst or not self._compare_op:
raise ValueError(
"{} has been instantiated without a valid `metric` ({}) or "
"`mode` ({}) parameter. Either pass these parameters when "
"instantiating the scheduler, or pass them as parameters "
"to `tune.run()`".format(self.__class__.__name__, self._metric,
self._mode))

super(MedianStoppingRule, self).on_trial_add(trial_runner, trial)

def on_trial_result(self, trial_runner, trial, result):
"""Callback for early stopping.

Expand Down
39 changes: 34 additions & 5 deletions python/ray/tune/schedulers/pbt.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ class PopulationBasedTraining(FIFOScheduler):
def __init__(self,
time_attr="time_total_s",
reward_attr=None,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
perturbation_interval=60.0,
hyperparam_mutations={},
quantile_fraction=0.25,
Expand Down Expand Up @@ -253,7 +253,8 @@ def __init__(self,
"perturbation_interval must be a positive number greater "
"than 0. Current value: '{}'".format(perturbation_interval))

assert mode in ["min", "max"], "`mode` must be 'min' or 'max'!"
if mode:
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'."

if reward_attr is not None:
mode = "max"
Expand All @@ -265,9 +266,11 @@ def __init__(self,

FIFOScheduler.__init__(self)
self._metric = metric
if mode == "max":
self._mode = mode
self._metric_op = None
if self._mode == "max":
self._metric_op = 1.
elif mode == "min":
elif self._mode == "min":
self._metric_op = -1.
self._time_attr = time_attr
self._perturbation_interval = perturbation_interval
Expand All @@ -285,7 +288,33 @@ def __init__(self,
self._num_checkpoints = 0
self._num_perturbations = 0

def set_search_properties(self, metric, mode):
if self._metric and metric:
return False
if self._mode and mode:
return False

if metric:
self._metric = metric
if mode:
self._mode = mode

if self._mode == "max":
self._metric_op = 1.
elif self._mode == "min":
self._metric_op = -1.

return True

def on_trial_add(self, trial_runner, trial):
if not self._metric or not self._metric_op:
raise ValueError(
"{} has been instantiated without a valid `metric` ({}) or "
"`mode` ({}) parameter. Either pass these parameters when "
"instantiating the scheduler, or pass them as parameters "
"to `tune.run()`".format(self.__class__.__name__, self._metric,
self._mode))

self._trial_state[trial] = PBTTrialState(trial)

for attr in self._hyperparam_mutations.keys():
Expand Down
12 changes: 12 additions & 0 deletions python/ray/tune/schedulers/trial_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ class TrialScheduler:
PAUSE = "PAUSE" #: Status for pausing trial execution
STOP = "STOP" #: Status for stopping trial execution

def set_search_properties(self, metric, mode):
"""Pass search properties to scheduler.

This method acts as an alternative to instantiating schedulers
that react to metrics with their own `metric` and `mode` parameters.

Args:
metric (str): Metric to optimize
mode (str): One of ["min", "max"]. Direction to optimize.
"""
return True

def on_trial_add(self, trial_runner, trial):
"""Called when a new trial is added to the trial runner."""

Expand Down
4 changes: 2 additions & 2 deletions python/ray/tune/suggest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

def create_searcher(
search_alg,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
**kwargs,
):
"""Instantiate a search algorithm based on the given string.
Expand Down
7 changes: 4 additions & 3 deletions python/ray/tune/suggest/ax.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,16 @@ def easy_objective(config):

def __init__(self,
space=None,
metric="episode_reward_mean",
mode="max",
metric=None,
mode=None,
parameter_constraints=None,
outcome_constraints=None,
ax_client=None,
use_early_stopped_trials=None,
max_concurrent=None):
assert ax is not None, "Ax must be installed!"
assert mode in ["min", "max"], "`mode` must be one of ['min', 'max']"
if mode:
assert mode in ["min", "max"], "`mode` must be 'min' or 'max'."

super(AxSearch, self).__init__(
metric=metric,
Expand Down
Loading