Skip to content

Commit 257648a

Browse files
authored
Merge pull request #160 from automl/fix/remove-objective-merging-from-plugins
Fix/remove objective merging from plugins
2 parents 09b2e2b + 2e0dfa8 commit 257648a

File tree

4 files changed

+62
-23
lines changed

4 files changed

+62
-23
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
- Runs now get displayed with their parent directory for better distinguishability.
55
- Increase plot font sizes.
66
- Add a simple loading bar functionality for longer runs.
7-
- Show a run's hoover-text for the actual budget of a trial in Cost over Time with Combined budget (#154).
8-
- Use highest budget as default budget for Cost over Time instead of Combined.
97

108
## General
119
- Seed is now required in the Recorder.
@@ -14,6 +12,13 @@
1412
- Use normalized LPI importance via variance instead of importance over mean (#152)
1513
- Return nan as importance values if variance is 0. for a hyperparameter / budget (#152)
1614

15+
## Plugins
16+
- Show a run's hoover-text for the actual budget of a trial in Cost over Time with Combined budget (#154).
17+
- Use highest budget as default budget for Cost over Time instead of Combined.
18+
- Show best value / config for each objective instead of merged objective in Overview (#159).
19+
- Use chosen objective instead of merged objective to get the incumbent for the calculation of LPI importance (#159).
20+
- Add total runtime in overview (#155).
21+
1722
# Version 1.2
1823

1924
## Plugins

deepcave/evaluators/lpi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def calculate(
9595

9696
# Set variables
9797
self.continous_neighbors = continous_neighbors
98-
self.incumbent, _ = self.run.get_incumbent(budget=budget)
98+
self.incumbent, _ = self.run.get_incumbent(budget=budget, objectives=objectives)
9999
self.default = self.cs.get_default_configuration()
100100
self.incumbent_array = self.incumbent.get_array()
101101

deepcave/plugins/summary/overview.py

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from deepcave.runs.status import Status
3838
from deepcave.utils.layout import create_table, help_button
3939
from deepcave.utils.styled_plotty import get_discrete_heatmap, save_image
40-
from deepcave.utils.util import get_latest_change
40+
from deepcave.utils.util import custom_round, get_latest_change
4141

4242

4343
class Overview(DynamicPlugin):
@@ -131,23 +131,38 @@ def load_outputs(run, *_: Any) -> List[Any]: # type: ignore
131131
List[Any]
132132
A list of the created tables of the overview.
133133
"""
134-
# Get best cost across all objectives, highest budget
135-
incumbent, _ = run.get_incumbent(statuses=[Status.SUCCESS])
136-
config_id = run.get_config_id(incumbent)
137-
objective_names = run.get_objective_names()
138-
139-
avg_costs, std_costs = run.get_avg_costs(config_id)
140-
141-
best_performances = []
142-
for idx in range(len(objective_names)):
143-
best_performances += [
144-
f"{round(avg_costs[idx], 2)} ± {round(std_costs[idx], 2)} ({objective_names[idx]})"
145-
]
146-
147134
optimizer = run.prefix
148135
if isinstance(run, Group):
149136
optimizer = run.get_runs()[0].prefix
150137

138+
performance_outputs = []
139+
for idx, obj in enumerate(run.get_objectives()):
140+
# Get best cost for the objective, highest budget
141+
incumbent, _ = run.get_incumbent(objectives=obj, statuses=[Status.SUCCESS])
142+
config_id = run.get_config_id(incumbent)
143+
avg_costs, std_costs = run.get_avg_costs(config_id)
144+
145+
if len(run.get_seeds(include_combined=False)) > 1:
146+
best_performance = (
147+
f"{custom_round(avg_costs[idx])} " f"± {custom_round(std_costs[idx])}"
148+
)
149+
else:
150+
best_performance = f"{custom_round(avg_costs[idx])}"
151+
152+
performance_outputs.append(
153+
html.Div(
154+
[
155+
html.Span(f"Best {obj.name}: {best_performance} "),
156+
html.A(
157+
"(See Configuration)",
158+
href=Configurations.get_link(run, config_id),
159+
style={"color": "white"},
160+
),
161+
],
162+
className="card-text",
163+
),
164+
)
165+
151166
# Design card for quick information here
152167
card = dbc.Card(
153168
[
@@ -162,15 +177,12 @@ def load_outputs(run, *_: Any) -> List[Any]: # type: ignore
162177
f"Latest change: {get_latest_change(run.latest_change)}",
163178
className="card-text",
164179
),
180+
*performance_outputs,
165181
html.Div(
166182
[
167183
html.Span(
168-
f"Best average performance: {', '.join(best_performances)} "
169-
),
170-
html.A(
171-
"(See Configuration)",
172-
href=Configurations.get_link(run, config_id),
173-
style={"color": "white"},
184+
f"Total runtime [s]: "
185+
f"{max(trial.end_time for trial in run.history)}"
174186
),
175187
],
176188
className="card-text",

deepcave/utils/util.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,25 @@ def print_progress_bar(
145145

146146
if iteration == total:
147147
print()
148+
149+
150+
def custom_round(number: float, min_decimals: int = 3, max_decimals: int = 10) -> float:
151+
"""
152+
Round a number to the nearest decimal.
153+
154+
Parameters
155+
----------
156+
number : float
157+
The number to round.
158+
min_decimals : int
159+
The minimum number of decimals.
160+
Default is 2.
161+
max_decimals : int
162+
The maximum number of decimals.
163+
Default is 10.
164+
"""
165+
for i in range(min_decimals, max_decimals + 1):
166+
rounded = round(number, i)
167+
if rounded != round(number, i - 1):
168+
return rounded
169+
return round(number, max_decimals)

0 commit comments

Comments
 (0)