mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-17 12:30:35 +08:00
Merge pull request #179 from optuna/disable-intermedite-value
Hide intermediate values chart if no intermediate values
This commit is contained in:
@@ -73,6 +73,7 @@ const study_detail = {
|
||||
attributes: { low: -3, high: 3 },
|
||||
},
|
||||
],
|
||||
has_intermediate_values: false,
|
||||
}
|
||||
|
||||
it("Sort TrialTable by trial number", () => {
|
||||
|
||||
@@ -34,6 +34,7 @@ from optuna.study import StudySummary
|
||||
from optuna.trial import FrozenTrial
|
||||
from optuna.trial import TrialState
|
||||
|
||||
from ._intermediate_values import has_intermediate_values
|
||||
from ._search_space import get_search_space
|
||||
from ._serializer import serialize_study_detail
|
||||
from ._serializer import serialize_study_summary
|
||||
@@ -217,9 +218,15 @@ def create_app(storage: BaseStorage) -> Bottle:
|
||||
if summary is None:
|
||||
response.status = 404 # Not found
|
||||
return {"reason": f"study_id={study_id} is not found"}
|
||||
trials = get_trials(storage, study_id)[after:]
|
||||
trials = get_trials(storage, study_id)
|
||||
intersection, union = get_search_space(study_id, trials)
|
||||
return serialize_study_detail(summary, trials, intersection, union)
|
||||
return serialize_study_detail(
|
||||
summary,
|
||||
trials[after:],
|
||||
intersection,
|
||||
union,
|
||||
has_intermediate_values(study_id, trials),
|
||||
)
|
||||
|
||||
@app.get("/api/studies/<study_id:int>/param_importances")
|
||||
@handle_json_api_exception
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import threading
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
|
||||
from optuna.trial import FrozenTrial
|
||||
from optuna.trial import TrialState
|
||||
|
||||
|
||||
# In-memory cache
|
||||
intermediate_values_cache_lock = threading.Lock()
|
||||
intermediate_values_cache: Dict[int, "_IntermediateValues"] = {}
|
||||
states_of_interest = [TrialState.COMPLETE, TrialState.PRUNED]
|
||||
|
||||
|
||||
def has_intermediate_values(study_id: int, trials: List[FrozenTrial]) -> bool:
|
||||
with intermediate_values_cache_lock:
|
||||
intermediate_values = intermediate_values_cache.get(study_id, None)
|
||||
if intermediate_values is None:
|
||||
intermediate_values = _IntermediateValues()
|
||||
intermediate_values.update(trials)
|
||||
intermediate_values_cache[study_id] = intermediate_values
|
||||
return intermediate_values.has_intermediate_values
|
||||
|
||||
|
||||
class _IntermediateValues:
|
||||
def __init__(self) -> None:
|
||||
self._cursor: int = -1
|
||||
self.has_intermediate_values: bool = False
|
||||
|
||||
def update(self, trials: List[FrozenTrial]) -> None:
|
||||
if self.has_intermediate_values:
|
||||
return
|
||||
|
||||
next_cursor = self._cursor
|
||||
for trial in reversed(trials):
|
||||
if self._cursor > trial.number:
|
||||
break
|
||||
|
||||
if not trial.state.is_finished():
|
||||
next_cursor = trial.number
|
||||
|
||||
if trial.state not in states_of_interest:
|
||||
continue
|
||||
|
||||
current = len(trial.intermediate_values) > 0
|
||||
if current:
|
||||
self.has_intermediate_values = True
|
||||
return
|
||||
self._cursor = next_cursor
|
||||
@@ -90,6 +90,7 @@ def serialize_study_detail(
|
||||
trials: List[FrozenTrial],
|
||||
intersection: List[Tuple[str, BaseDistribution]],
|
||||
union: List[Tuple[str, BaseDistribution]],
|
||||
has_intermediate_values: bool,
|
||||
) -> Dict[str, Any]:
|
||||
serialized: Dict[str, Any] = {
|
||||
"name": summary.study_name,
|
||||
@@ -109,6 +110,7 @@ def serialize_study_detail(
|
||||
|
||||
serialized["intersection_search_space"] = serialize_search_space(intersection)
|
||||
serialized["union_search_space"] = serialize_search_space(union)
|
||||
serialized["has_intermediate_values"] = has_intermediate_values
|
||||
return serialized
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ interface StudyDetailResponse {
|
||||
trials: TrialResponse[]
|
||||
intersection_search_space: SearchSpace[]
|
||||
union_search_space: SearchSpace[]
|
||||
has_intermediate_values: boolean
|
||||
}
|
||||
|
||||
export const getStudyDetailAPI = (
|
||||
@@ -70,6 +71,7 @@ export const getStudyDetailAPI = (
|
||||
trials: trials,
|
||||
union_search_space: res.data.union_search_space,
|
||||
intersection_search_space: res.data.intersection_search_space,
|
||||
has_intermediate_values: res.data.has_intermediate_values,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -190,7 +190,9 @@ export const StudyDetail: FC<{
|
||||
/>
|
||||
<FormControlLabel
|
||||
disabled={
|
||||
studyDetail !== null && !isSingleObjectiveStudy(studyDetail)
|
||||
studyDetail !== null &&
|
||||
(!isSingleObjectiveStudy(studyDetail) ||
|
||||
!studyDetail.has_intermediate_values)
|
||||
}
|
||||
control={
|
||||
<Checkbox
|
||||
@@ -344,6 +346,7 @@ export const StudyDetail: FC<{
|
||||
|
||||
{studyDetail !== null &&
|
||||
isSingleObjectiveStudy(studyDetail) &&
|
||||
studyDetail.has_intermediate_values &&
|
||||
preferences.graphIntermediateValuesChecked ? (
|
||||
<Card sx={{ margin: theme.spacing(2) }}>
|
||||
<CardContent>
|
||||
|
||||
+1
@@ -77,6 +77,7 @@ declare interface StudyDetail {
|
||||
trials: Trial[]
|
||||
intersection_search_space: SearchSpace[]
|
||||
union_search_space: SearchSpace[]
|
||||
has_intermediate_values: boolean
|
||||
}
|
||||
|
||||
declare interface StudyDetails {
|
||||
|
||||
Reference in New Issue
Block a user