Skip to content

Commit 65b714b

Browse files
saitcakmakmeta-codesync[bot]
authored andcommitted
Remove AxClient.get_optimization_trace (#5168)
Summary: Pull Request resolved: #5168 Cleaning up some unused methods from AxClient. This functionality has been superseeded by `UtilityProgressionAnalysis`. Reviewed By: mpolson64, lena-kashtelyan Differential Revision: D99308562 fbshipit-source-id: b3d660f789e2e000f80d0ba7ed999db765058fe9
1 parent b5948c9 commit 65b714b

2 files changed

Lines changed: 2 additions & 133 deletions

File tree

ax/service/ax_client.py

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@
1616
from typing import Any, TypeVar
1717

1818
import ax.service.utils.early_stopping as early_stopping_utils
19-
import numpy as np
2019
import pandas as pd
2120
import torch
2221
from ax.adapter.prediction_utils import predict_by_features
2322
from ax.api.configs import ChoiceParameterConfig, RangeParameterConfig
2423
from ax.api.utils.instantiation.from_config import parameter_from_config
2524
from ax.core.arm import Arm
26-
from ax.core.base_trial import BaseTrial
2725
from ax.core.evaluations_to_data import raw_evaluations_to_data
2826
from ax.core.experiment import Experiment
2927
from ax.core.generator_run import GeneratorRun
@@ -58,12 +56,9 @@
5856
from ax.generation_strategy.generation_strategy import GenerationStrategy
5957
from ax.generation_strategy.transition_criterion import MaxGenerationParallelism
6058
from ax.global_stopping.strategies.base import BaseGlobalStoppingStrategy
61-
from ax.global_stopping.strategies.improvement import constraint_satisfaction
6259
from ax.plot.base import AxPlotConfig
6360
from ax.plot.contour import plot_contour
6461
from ax.plot.feature_importances import plot_feature_importance_by_feature
65-
from ax.plot.helper import _format_dict
66-
from ax.plot.trace import optimization_trace_single_method
6762
from ax.service.utils.analysis_base import AnalysisBase
6863
from ax.service.utils.best_point_mixin import BestPointMixin
6964
from ax.service.utils.instantiation import (
@@ -1087,77 +1082,6 @@ def get_max_concurrency(self) -> list[tuple[int, int]]:
10871082
def get_max_parallelism(self) -> list[tuple[int, int]]:
10881083
raise NotImplementedError("Use `get_max_concurrency` instead.")
10891084

1090-
def get_optimization_trace(
1091-
self, objective_optimum: float | None = None
1092-
) -> AxPlotConfig:
1093-
"""Retrieves the plot configuration for optimization trace, which shows
1094-
the evolution of the objective mean over iterations.
1095-
1096-
Args:
1097-
objective_optimum: Optimal objective, if known, for display in the
1098-
visualization.
1099-
"""
1100-
if not self.experiment.trials:
1101-
raise ValueError("Cannot generate plot as there are no trials.")
1102-
1103-
objective = self.objective
1104-
if objective.is_multi_objective:
1105-
raise UnsupportedError(
1106-
"`get_optimization_trace` is not supported "
1107-
"for multi-objective experiments"
1108-
)
1109-
1110-
if objective.is_scalarized_objective:
1111-
raise UnsupportedError(
1112-
"`get_optimization_trace` is not supported for scalarized "
1113-
"objectives. `trial.objective_mean` returns the value of "
1114-
"the first metric, not the weighted combination."
1115-
)
1116-
1117-
opt_config = none_throws(self.experiment.optimization_config)
1118-
if any(len(oc.metric_names) > 1 for oc in opt_config.outcome_constraints):
1119-
raise UnsupportedError(
1120-
"`get_optimization_trace` is not supported for scalarized "
1121-
"outcome constraints."
1122-
)
1123-
1124-
minimize: bool = objective.minimize
1125-
1126-
# Setting the objective values of infeasible points to be infinitely
1127-
# bad prevents them from increasing or decreasing the
1128-
# optimization trace.
1129-
def _constrained_trial_objective_mean(trial: BaseTrial) -> float:
1130-
if constraint_satisfaction(trial):
1131-
return assert_is_instance(trial, Trial).objective_mean
1132-
return float("inf") if minimize else float("-inf")
1133-
1134-
objective_name = self.objective_name
1135-
best_objectives = np.array(
1136-
[
1137-
[
1138-
_constrained_trial_objective_mean(trial)
1139-
for trial in self.experiment.trials.values()
1140-
if trial.status.is_completed
1141-
]
1142-
]
1143-
)
1144-
hover_labels = [
1145-
_format_dict(none_throws(assert_is_instance(trial, Trial).arm).parameters)
1146-
for trial in self.experiment.trials.values()
1147-
if trial.status.is_completed
1148-
]
1149-
return optimization_trace_single_method(
1150-
y=(
1151-
np.minimum.accumulate(best_objectives, axis=1)
1152-
if minimize
1153-
else np.maximum.accumulate(best_objectives, axis=1)
1154-
),
1155-
optimum=objective_optimum,
1156-
title="Best objective found vs. # of iterations",
1157-
ylabel=objective_name.capitalize(),
1158-
hover_labels=hover_labels,
1159-
)
1160-
11611085
def get_contour_plot(
11621086
self,
11631087
param_x: str | None = None,

ax/service/tests/test_ax_client.py

Lines changed: 2 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,8 @@
2626
from ax.core.generator_run import GeneratorRun
2727
from ax.core.metric import Metric
2828
from ax.core.multi_type_experiment import MultiTypeExperiment
29-
from ax.core.objective import MultiObjective, Objective
30-
from ax.core.optimization_config import (
31-
MultiObjectiveOptimizationConfig,
32-
OptimizationConfig,
33-
)
29+
from ax.core.objective import MultiObjective
30+
from ax.core.optimization_config import MultiObjectiveOptimizationConfig
3431
from ax.core.outcome_constraint import ObjectiveThreshold, OutcomeConstraint
3532
from ax.core.parameter import (
3633
ChoiceParameter,
@@ -493,8 +490,6 @@ def test_default_generation_strategy_continuous(self) -> None:
493490
],
494491
[Generators.SOBOL, Generators.BOTORCH_MODULAR],
495492
)
496-
with self.assertRaisesRegex(ValueError, ".* no trials"):
497-
ax_client.get_optimization_trace(objective_optimum=branin.fmin)
498493
for i in range(6):
499494
gen_limit, opt_complete = ax_client.get_current_trial_generation_limit()
500495
self.assertFalse(opt_complete)
@@ -522,7 +517,6 @@ def test_default_generation_strategy_continuous(self) -> None:
522517
self.assertEqual(
523518
none_throws(ax_client.generation_strategy.adapter)._generator_key, "BoTorch"
524519
)
525-
ax_client.get_optimization_trace(objective_optimum=branin.fmin)
526520
ax_client.get_contour_plot()
527521
trials_df = ax_client.get_trials_data_frame()
528522
self.assertIn("x", trials_df)
@@ -690,8 +684,6 @@ def test_default_generation_strategy_continuous_for_moo(self) -> None:
690684
],
691685
[Generators.SOBOL, Generators.BOTORCH_MODULAR],
692686
)
693-
with self.assertRaisesRegex(ValueError, ".* no trials"):
694-
ax_client.get_optimization_trace(objective_optimum=branin.fmin)
695687
for i in range(6):
696688
with mock.patch("ax.service.ax_client.logger.info") as mock_log:
697689
parameterization, trial_index = ax_client.get_next_trial()
@@ -739,10 +731,6 @@ def test_default_generation_strategy_continuous_for_moo(self) -> None:
739731
self.assertIn("b", trials_df)
740732
self.assertEqual(len(trials_df), 6)
741733

742-
with self.subTest("it raises UnsupportedError for get_optimization_trace"):
743-
with self.assertRaises(UnsupportedError):
744-
ax_client.get_optimization_trace(objective_optimum=branin.fmin)
745-
746734
with self.subTest(
747735
"it raises UnsupportedError for get_contour_plot without metric"
748736
):
@@ -3641,49 +3629,6 @@ def test_with_node_based_gs(self) -> None:
36413629
)._generator_key,
36423630
"Sobol",
36433631
)
3644-
with mock.patch(
3645-
"ax.service.ax_client.optimization_trace_single_method"
3646-
) as mock_plot:
3647-
ax_client.get_optimization_trace()
3648-
mock_plot.assert_called_once()
3649-
3650-
def test_get_optimization_trace_scalarized(self) -> None:
3651-
"""get_optimization_trace raises UnsupportedError for scalarized."""
3652-
ax_client = get_branin_optimization()
3653-
params, idx = ax_client.get_next_trial()
3654-
ax_client.complete_trial(trial_index=idx, raw_data={"branin": (1.0, 0.0)})
3655-
ax_client.experiment.add_tracking_metric(Metric(name="other_metric"))
3656-
ax_client.experiment._optimization_config = OptimizationConfig(
3657-
objective=Objective(
3658-
expression="2*branin + -1*other_metric",
3659-
metric_name_to_signature={
3660-
"branin": "branin",
3661-
"other_metric": "other_metric",
3662-
},
3663-
),
3664-
)
3665-
with self.assertRaisesRegex(UnsupportedError, "not supported for scalarized"):
3666-
ax_client.get_optimization_trace()
3667-
3668-
def test_get_optimization_trace_scalarized_outcome_constraint(self) -> None:
3669-
"""get_optimization_trace raises UnsupportedError for scalarized
3670-
outcome constraints."""
3671-
ax_client = get_branin_optimization()
3672-
params, idx = ax_client.get_next_trial()
3673-
ax_client.complete_trial(trial_index=idx, raw_data={"branin": (1.0, 0.0)})
3674-
ax_client.experiment.add_tracking_metric(Metric(name="m1"))
3675-
ax_client.experiment.add_tracking_metric(Metric(name="m2"))
3676-
ax_client.experiment._optimization_config = OptimizationConfig(
3677-
objective=Objective(metric=Metric(name="branin"), minimize=True),
3678-
outcome_constraints=[
3679-
OutcomeConstraint(
3680-
expression="2*m1 + 3*m2 <= 10",
3681-
metric_name_to_signature={"m1": "m1", "m2": "m2"},
3682-
),
3683-
],
3684-
)
3685-
with self.assertRaisesRegex(UnsupportedError, "not supported for scalarized"):
3686-
ax_client.get_optimization_trace()
36873632

36883633

36893634
# Utility functions for testing get_model_predictions without calling

0 commit comments

Comments
 (0)