Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename maximum_hypervolume to optimal_value in MOO Benchmark Problems #2598

Closed
wants to merge 1 commit into from
Closed
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
22 changes: 12 additions & 10 deletions ax/benchmark/benchmark_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,14 +314,16 @@ def from_botorch_synthetic(


class MultiObjectiveBenchmarkProblem(BenchmarkProblem):
"""A BenchmarkProblem support multiple objectives. Rather than knowing each
objective's optimal value we track a known maximum hypervolume computed from a
given reference point.
"""
A `BenchmarkProblem` that supports multiple objectives.

For multi-objective problems, `optimal_value` indicates the maximum
hypervolume attainable with the given `reference_point`.
"""

def __init__(
self,
maximum_hypervolume: float,
optimal_value: float,
reference_point: List[float],
*,
name: str,
Expand All @@ -334,7 +336,7 @@ def __init__(
has_ground_truth: bool = False,
tracking_metrics: Optional[List[BenchmarkMetricBase]] = None,
) -> None:
self.maximum_hypervolume = maximum_hypervolume
self.optimal_value = optimal_value
self.reference_point = reference_point
super().__init__(
name=name,
Expand All @@ -348,10 +350,6 @@ def __init__(
tracking_metrics=tracking_metrics,
)

@property
def optimal_value(self) -> float:
return self.maximum_hypervolume

@classmethod
def from_botorch_multi_objective(
cls,
Expand Down Expand Up @@ -425,6 +423,10 @@ def from_botorch_multi_objective(
is_noiseless=problem.is_noiseless,
observe_noise_sd=observe_noise_sd,
has_ground_truth=problem.has_ground_truth,
maximum_hypervolume=test_problem.max_hv,
optimal_value=test_problem.max_hv,
reference_point=test_problem._ref_point,
)

@property
def maximum_hypervolume(self) -> float:
return self.optimal_value
26 changes: 10 additions & 16 deletions ax/benchmark/problems/surrogate.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class SurrogateBenchmarkProblemBase(Base):
"""
Base class for SOOSurrogateBenchmarkProblem and MOOSurrogateBenchmarkProblem.

Allows for lazy creation of objects needed to construct a `runner`,
including a surrogate and datasets.
Its `runner` is created lazily, when `runner` is accessed or `set_runner` is
called, to defer construction of the surrogate and downloading of datasets.
"""

def __init__(
Expand Down Expand Up @@ -147,8 +147,10 @@ def __repr__(self) -> str:

class SOOSurrogateBenchmarkProblem(SurrogateBenchmarkProblemBase):
"""
Has the same attributes/properties as a `SingleObjectiveBenchmarkProblem`,
but allows for constructing from a surrogate.
Has the same attributes/properties as a `MultiObjectiveBenchmarkProblem`,
but its runner is not constructed until needed, to allow for deferring
constructing the surrogate and downloading data. The surrogate is only
defined when `runner` is accessed or `set_runner` is called.
"""

def __init__(
Expand Down Expand Up @@ -187,19 +189,15 @@ class MOOSurrogateBenchmarkProblem(SurrogateBenchmarkProblemBase):
"""
Has the same attributes/properties as a `MultiObjectiveBenchmarkProblem`,
but its runner is not constructed until needed, to allow for deferring
constructing the surrogate.

Simple aspects of the problem problem such as its search space
are defined immediately, while the surrogate is only defined when [TODO]
in order to avoid expensive operations like downloading files and fitting
a model.
constructing the surrogate and downloading data. The surrogate is only
defined when `runner` is accessed or `set_runner` is called.
"""

optimization_config: MultiObjectiveOptimizationConfig

def __init__(
self,
maximum_hypervolume: float,
optimal_value: float,
reference_point: List[float],
*,
name: str,
Expand Down Expand Up @@ -228,8 +226,4 @@ def __init__(
_runner=_runner,
)
self.reference_point = reference_point
self.maximum_hypervolume = maximum_hypervolume

@property
def optimal_value(self) -> float:
return self.maximum_hypervolume
self.optimal_value = optimal_value
4 changes: 1 addition & 3 deletions ax/benchmark/tests/test_benchmark_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,7 @@ def test_moo_from_botorch(self) -> None:
)

# Test hypervolume
self.assertEqual(
branin_currin_problem.maximum_hypervolume, test_problem._max_hv
)
self.assertEqual(branin_currin_problem.optimal_value, test_problem._max_hv)
self.assertEqual(branin_currin_problem.reference_point, test_problem._ref_point)

def test_maximization_problem(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion ax/storage/json_store/encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def multi_objective_benchmark_problem_to_dict(
"observe_noise_sd": moo_benchmark_problem.observe_noise_sd,
"has_ground_truth": moo_benchmark_problem.has_ground_truth,
"tracking_metrics": moo_benchmark_problem.tracking_metrics,
"maximum_hypervolume": moo_benchmark_problem.maximum_hypervolume,
"optimal_value": moo_benchmark_problem.optimal_value,
"reference_point": moo_benchmark_problem.reference_point,
}

Expand Down
2 changes: 1 addition & 1 deletion ax/utils/testing/benchmark_stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def get_moo_surrogate() -> MOOSurrogateBenchmarkProblem:
outcome_names=["branin_a", "branin_b"],
observe_noise_stds=True,
get_surrogate_and_datasets=lambda: (surrogate, []),
maximum_hypervolume=1.0,
optimal_value=1.0,
reference_point=[],
)

Expand Down