Skip to content

Commit 0659c81

Browse files
committed
ablation path test update
1 parent 999a971 commit 0659c81

File tree

4 files changed

+29
-31
lines changed

4 files changed

+29
-31
lines changed

deepcave/evaluators/ablation.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ def calculate(
7676
objectives: Optional[Union[Objective, List[Objective]]], # noqa
7777
budget: Optional[Union[int, float]] = None, # noqa
7878
model: Any = None,
79-
seed: int = 0,
80-
n_trees: int = 50,
8179
) -> None:
8280
"""
8381
Calculate the ablation path performances and improvements.
@@ -95,12 +93,6 @@ def calculate(
9593
model :
9694
The surrogate model to use for the prediction of the perfromances.
9795
By default None.
98-
seed : int
99-
The seed to use for reproducability.
100-
By default 0.
101-
n_trees : int
102-
The number of trees to use for the Random Forest.
103-
By default 50.
10496
"""
10597
if isinstance(objectives, list) and len(objectives) > 1:
10698
raise ValueError("Only one objective is supported for ablation paths.")
@@ -131,7 +123,7 @@ def calculate(
131123
# The default model is a RF Surrogate, but it cant be passed as parameter directly
132124
# because it needs access to its config space
133125
if self._model is None:
134-
self._model = RandomForestSurrogate(self.cs, seed=seed, n_trees=n_trees)
126+
self._model = RandomForestSurrogate(self.cs, seed=0, n_trees=50)
135127

136128
self._model.fit(X, Y)
137129
# Obtain the predicted cost of the default and incumbent configuration

deepcave/evaluators/mo_ablation.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ def calculate(
123123
objectives: Optional[Union[Objective, List[Objective]]], # noqa
124124
budget: Optional[Union[int, float]] = None, # noqa
125125
model: Any = None,
126-
seed: int = 0, # noqa
127-
n_trees: int = 50, # noqa
128126
) -> None:
129127
"""
130128
Calculate the MO ablation path performances and improvements.
@@ -139,12 +137,6 @@ def calculate(
139137
model : Any
140138
For mo ablation this parameter does not do anything, except fit the head.
141139
By default None.
142-
n_trees : int
143-
The number of trees for the surrogate model.
144-
Default is 50.
145-
seed : int
146-
The seed for the surrogate model.
147-
Default is 0.
148140
"""
149141
assert isinstance(objectives, list)
150142
for objective in objectives:
@@ -170,7 +162,8 @@ def calculate(
170162

171163
# train one model per objective
172164
Y = df[normed].to_numpy()
173-
model = RandomForestSurrogate(self.cs, seed=seed, n_trees=n_trees)
165+
if model is None:
166+
model = RandomForestSurrogate(self.cs, seed=0, n_trees=50)
174167
model.fit(X, Y)
175168
self.models.append(model)
176169

deepcave/plugins/hyperparameter/ablation_paths.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ def process(run: AbstractRun, inputs: Dict[str, Any]) -> Dict[str, Any]:
338338
data: Dict[Any, Any] = {}
339339
for budget_id, budget in enumerate(budgets):
340340
assert isinstance(budget, (int, float))
341-
evaluator.calculate(objective, budget, n_trees=n_trees, seed=0)
341+
evaluator.calculate(objective, budget)
342342
if isinstance(objective, list):
343343
assert isinstance(evaluator, MOAblation)
344344
data[budget_id] = evaluator.get_importances()

tests/test_evaluators/test_ablation.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from sympy import lambdify, symbols
2424

2525
from deepcave.evaluators.ablation import Ablation as Evaluator
26+
from deepcave.evaluators.epm.random_forest_surrogate import RandomForestSurrogate
2627
from deepcave.runs import AbstractRun
2728
from deepcave.runs.converters.deepcave import DeepCAVERun
2829
from deepcave.runs.converters.smac3v2 import SMAC3v2Run
@@ -37,8 +38,9 @@ class PolynomialSurrogateModel:
3738
"""
3839

3940
def __init__(
40-
self, n: int, max_degree: int = 2, seed: int = 42, coeffs: Optional[np.ndarray] = None
41+
self, n: int, max_degree: int = 1, seed: int = 42, coeffs: Optional[np.ndarray] = None
4142
):
43+
self.ground_truth: np.ndarray
4244
self._polynomial(n, max_degree, seed, coeffs)
4345

4446
def fit(self, X: np.ndarray, y: np.ndarray) -> np.ndarray:
@@ -83,7 +85,6 @@ def _polynomial(
8385
np.ndarray
8486
The fitting polynomial structure with random variables.
8587
"""
86-
8788
x = symbols(f"x1:{n+1}")
8889

8990
terms = []
@@ -110,12 +111,12 @@ def _polynomial(
110111

111112
if coeffs is None:
112113
np.random.seed(seed)
113-
input_values = np.random.randint(1, 5, size=len(coeff_symb))
114+
self.ground_truth = np.random.uniform(1, 5, size=len(coeff_symb))
114115

115116
else:
116-
input_values = coeffs
117+
self.ground_truth = coeffs
117118

118-
input_mapping = dict(zip(coeff_symb, input_values))
119+
input_mapping = dict(zip(coeff_symb, self.ground_truth))
119120
partial_expr = expr.subs(input_mapping)
120121

121122
variables = sorted(partial_expr.free_symbols, key=lambda s: str(s))
@@ -134,10 +135,12 @@ def test(self):
134135
objective = self.run.get_objective(0)
135136

136137
# Calculate
137-
self.evaluator.calculate(objective, budget, seed=0)
138+
model_1 = RandomForestSurrogate(self.run.configspace, seed=0)
139+
self.evaluator.calculate(objective, budget, model=model_1)
138140
importances = self.evaluator.get_ablation_performances()
139141

140-
self.evaluator.calculate(objective, budget, seed=42)
142+
model_2 = RandomForestSurrogate(self.run.configspace, seed=42)
143+
self.evaluator.calculate(objective, budget, model=model_2)
141144
importances2 = self.evaluator.get_ablation_performances()
142145

143146
# Different seed: Different results
@@ -152,10 +155,12 @@ def test_seed(self):
152155
objective = self.run.get_objective(0)
153156

154157
# Calculate
155-
self.evaluator.calculate(objective, budget, seed=0)
158+
model_1 = RandomForestSurrogate(self.run.configspace, seed=0)
159+
self.evaluator.calculate(objective, budget, model=model_1)
156160
importances = self.evaluator.get_ablation_performances()
157161

158-
self.evaluator.calculate(objective, budget, seed=0)
162+
model_2 = RandomForestSurrogate(self.run.configspace, seed=0)
163+
self.evaluator.calculate(objective, budget, model=model_2)
159164
importances2 = self.evaluator.get_ablation_performances()
160165

161166
# Same seed: Same results
@@ -174,9 +179,17 @@ def test_polynomial(self):
174179
self.evaluator.calculate(objectives=objective, budget=budget, model=model)
175180

176181
# Evaluate the final ablation path
177-
# performances = self.evaluator.get_ablation_performances()
178-
# importances = self.evaluator.get_ablation_improvements()
179-
# TODO: evaluation
182+
importances = self.evaluator.get_ablation_improvements()
183+
sorted_importances = np.array(
184+
[
185+
round(float(value[0]), 8)
186+
for key, value in sorted(importances.items())
187+
if key != "default"
188+
]
189+
)
190+
ground_truth = model.ground_truth[1:]
191+
192+
assert np.allclose(sorted_importances, ground_truth, rtol=1e-5, atol=1e-8)
180193

181194

182195
if __name__ == "__main__":

0 commit comments

Comments
 (0)