Skip to content

Commit 4669e6d

Browse files
authored
Hparams: Fix metric info generation for sessions without run names. (#6541)
Fix a bug where we couldn't generate metric infos for HyperparameterSessionRun without run names. We were failing to match the sessions with the runs returned by scalars_metadata(). As an example: When a HyperparameterSessionRun does not contain `run` field, we were generating session_names of the form 'exp1/', 'exp2/', etc.. with a trailing '/'. Meanwhile, runs would be just of the form 'exp1/run_name'. The logic to match paths in _find_longest_parent_path() would first try to find 'exp1/run_name' in session_names and then 'exp1' in session_names. The second try would fail because of the trailing slashes in session_names. So, instead, when there is no `run` field in a HyperparameterSessionRun, we drop the final '/' and just generate names like 'exp1', 'exp2', etc... and the algorithm in _find_longest_parent_path() succeeds.
1 parent 1b7c747 commit 4669e6d

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

tensorboard/plugins/hparams/backend_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ def compute_metric_infos_from_data_provider_session_groups(
403403
self, ctx, experiment_id, session_groups
404404
):
405405
session_runs = set(
406-
f"{s.experiment_id}/{s.run}"
406+
f"{s.experiment_id}/{s.run}" if s.run else s.experiment_id
407407
for sg in session_groups
408408
for s in sg.sessions
409409
)

tensorboard/plugins/hparams/backend_context_test.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ def test_experiment_from_data_provider_discrete_string_hparam(self):
561561
"""
562562
self.assertProtoEquals(expected_exp, actual_exp)
563563

564-
def test_experiment_from_data_provider_session_group(self):
564+
def test_experiment_from_data_provider_session_groups(self):
565565
self._mock_tb_context.data_provider.list_tensors.side_effect = None
566566
# The sessions chosen here mimic those returned in the implementation
567567
# of _mock_list_tensors. These work nicely with the scalars returned
@@ -614,6 +614,44 @@ def test_experiment_from_data_provider_session_group(self):
614614
"""
615615
self.assertProtoEquals(expected_exp, actual_exp)
616616

617+
def test_experiment_from_data_provider_session_group_without_run_name(self):
618+
self._mock_tb_context.data_provider.list_tensors.side_effect = None
619+
self._hyperparameters = provider.ListHyperparametersResult(
620+
hyperparameters=[],
621+
session_groups=[
622+
provider.HyperparameterSessionGroup(
623+
root=provider.HyperparameterSessionRun(
624+
experiment_id="exp/session_1", run=""
625+
),
626+
# The entire path to the run is encoded in the experiment_id
627+
# to allow us to test empty run name while still generating
628+
# metric_infos.
629+
sessions=[
630+
provider.HyperparameterSessionRun(
631+
experiment_id="exp/session_1", run=""
632+
),
633+
],
634+
hyperparameter_values=[],
635+
),
636+
],
637+
)
638+
actual_exp = self._experiment_from_metadata()
639+
expected_exp = """
640+
metric_infos: {
641+
name: {group: '', tag: 'accuracy'}
642+
}
643+
metric_infos: {
644+
name: {group: '', tag: 'loss'}
645+
}
646+
metric_infos: {
647+
name: {group: 'eval', tag: 'loss'}
648+
}
649+
metric_infos: {
650+
name: {group: 'train', tag: 'loss'}
651+
}
652+
"""
653+
self.assertProtoEquals(expected_exp, actual_exp)
654+
617655
def test_experiment_from_data_provider_old_response_type(self):
618656
self._hyperparameters = [
619657
provider.Hyperparameter(

0 commit comments

Comments
 (0)