Skip to content

Commit 6febb50

Browse files
authored
Hparams: Add differs field. (#6500)
Add a `differs` field at both the DataProvider level (in Hyperparameter) and at the hparams API level (in HParamInfo). Also write logic to consume it in the hparams dashboard by sorting the hparams that differ to the top. There are, unfortunately, no tests in the repo for UI changes so I had to test the changes manually. I tested that an experiment with < 5 hparams renders all hparams and selects all hparams. I tested that an internal experiment (from an internal data provider implementation) that has > 5 hparams sorts hparams with `differs===true` to the top and that the first five are selected. I checked that attempts to set the order and to set filters succeed.
1 parent 060fecb commit 6febb50

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
lines changed

tensorboard/data/provider.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,13 +559,14 @@ class Hyperparameter:
559559
"""Metadata about a hyperparameter.
560560
561561
Attributes:
562-
hyperparameter_name: A string identifier for the hyperparameter that should be unique
563-
in any result set of Hyperparameter objects.
562+
hyperparameter_name: A string identifier for the hyperparameter that
563+
should be unique in any result set of Hyperparameter objects.
564564
hyperparameter_display_name: A displayable name for the hyperparameter.
565565
Unlike hyperparameter_name, there is no uniqueness constraint.
566566
domain_type: A HyperparameterDomainType describing how we represent the
567567
set of known values in the `domain` attribute.
568-
domain: A representation of the set of known values for the hyperparameter.
568+
domain: A representation of the set of known values for the
569+
hyperparameter.
569570
570571
If domain_type is INTERVAL, a Tuple[float, float] describing the
571572
range of numeric values.
@@ -575,6 +576,11 @@ class Hyperparameter:
575576
finite set of string values.
576577
If domain_type is DISCRETE_BOOL, a Collection[bool] describing the
577578
finite set of bool values.
579+
580+
differs: Describes whether there are two or more known values for the
581+
hyperparameter for the set of experiments specified in the
582+
list_hyperparameters() request. Hyperparameters for which this is
583+
true are made more prominent or easier to discover in the UI.
578584
"""
579585

580586
hyperparameter_name: str
@@ -587,6 +593,7 @@ class Hyperparameter:
587593
Collection[bool],
588594
None,
589595
] = None
596+
differs: bool = False
590597

591598

592599
@dataclasses.dataclass(frozen=True)

tensorboard/plugins/hparams/api.proto

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ message Experiment {
6969
repeated MetricInfo metric_infos = 5;
7070
}
7171

72-
// NEXT_TAG: 7
72+
// NEXT_TAG: 8
7373
message HParamInfo {
7474
// An id for the hyperparameter.
7575
string name = 1;
@@ -96,6 +96,11 @@ message HParamInfo {
9696
// hyperparameter are taken.
9797
Interval domain_interval = 6;
9898
}
99+
100+
// Describes whether there are two or more known values for the HParam
101+
// in the specified Experiment. HParams for which this is true are made more
102+
// prominent or easier to discover in the UI.
103+
bool differs = 7;
99104
}
100105

101106
enum DataType {

tensorboard/plugins/hparams/backend_context.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ def _convert_data_provider_hparam(self, dp_hparam):
348348
hparam_info = api_pb2.HParamInfo(
349349
name=dp_hparam.hyperparameter_name,
350350
display_name=dp_hparam.hyperparameter_display_name,
351+
differs=dp_hparam.differs,
351352
)
352353
if dp_hparam.domain_type == provider.HyperparameterDomainType.INTERVAL:
353354
hparam_info.type = api_pb2.DATA_TYPE_FLOAT64

tensorboard/plugins/hparams/backend_context_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,35 @@ def test_experiment_without_any_hparams(self):
350350
self.assertIsInstance(actual_exp, api_pb2.Experiment)
351351
self.assertProtoEquals("", actual_exp)
352352

353+
def test_experiment_from_data_provider_differs(self):
354+
self._hyperparameters = [
355+
provider.Hyperparameter(
356+
hyperparameter_name="hparam1_name",
357+
hyperparameter_display_name="hparam1_display_name",
358+
differs=True,
359+
),
360+
provider.Hyperparameter(
361+
hyperparameter_name="hparam2_name",
362+
hyperparameter_display_name="hparam2_display_name",
363+
differs=False,
364+
),
365+
]
366+
self._mock_tb_context.data_provider.list_tensors.side_effect = None
367+
actual_exp = self._experiment_from_metadata()
368+
expected_exp = """
369+
hparam_infos: {
370+
name: 'hparam1_name'
371+
display_name: 'hparam1_display_name'
372+
differs: true
373+
}
374+
hparam_infos: {
375+
name: 'hparam2_name'
376+
display_name: 'hparam2_display_name'
377+
differs: false
378+
}
379+
"""
380+
self.assertProtoEquals(expected_exp, actual_exp)
381+
353382
def test_experiment_from_data_provider_interval_hparam(self):
354383
self._hyperparameters = [
355384
provider.Hyperparameter(

tensorboard/plugins/hparams/tf_hparams_query_pane/tf-hparams-query-pane.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,11 +575,12 @@ class TfHparamsQueryPane extends LegacyElementMixin(PolymerElement) {
575575
// Updates the _hparams property from the _experiment property.
576576
_computeHParams() {
577577
const result: any[] = [];
578-
const kNumHParamsToDisplayByDefault = 5;
579-
this._experiment.hparamInfos.forEach((anInfo, index) => {
578+
this._experiment.hparamInfos.forEach((anInfo) => {
580579
const hparam = {
581580
info: anInfo as any,
582-
displayed: index < kNumHParamsToDisplayByDefault,
581+
// Controls whether the hparam is chosen for display in the main view.
582+
// Set later.
583+
displayed: false,
583584
filter: {} as any,
584585
};
585586
if (hparam.info.hasOwnProperty('domainDiscrete')) {
@@ -617,6 +618,23 @@ class TfHparamsQueryPane extends LegacyElementMixin(PolymerElement) {
617618
}
618619
result.push(hparam);
619620
});
621+
// Reorder by moving hparams with 'differs === true' to the top of the list.
622+
result.sort((x, y) => {
623+
if (x.info.differs === y.info.differs) {
624+
return 0;
625+
}
626+
627+
return x.info.differs ? -1 : 1;
628+
});
629+
// Choose to display the first 5 hparams in the main view initially.
630+
const kNumHParamsToDisplayByDefault = 5;
631+
const numHparamsToDisplay = Math.min(
632+
kNumHParamsToDisplayByDefault,
633+
result.length
634+
);
635+
for (let i = 0; i < numHparamsToDisplay; i++) {
636+
result[i].displayed = true;
637+
}
620638
this.set('_hparams', result);
621639
}
622640
// Updates the _metrics property from the _experiment property.

0 commit comments

Comments
 (0)