Leave a dotted key out of the runs export header
_leaves named a column for a key like `-1.0` that _dig can never read back, so the export showed an always-empty column. Skip such a key.
This commit is contained in:
@@ -441,9 +441,15 @@ def _leaves(value: Any, prefix: str = "") -> Iterator[tuple[str, Any]]:
|
||||
the numbers arrive inside `final_metrics` — and a record in one cell is
|
||||
not a column anybody can compare. Lists are left whole: a curve belongs in
|
||||
the long table, not in a cell of this one.
|
||||
|
||||
A key with a dot in its own name — a frequency written `-1.0` — is left
|
||||
out, and whatever sits under it with it: `_dig` cannot read such a path
|
||||
back, so naming it would promise a column that is always empty.
|
||||
"""
|
||||
if isinstance(value, dict):
|
||||
for key, inner in value.items():
|
||||
if "." in str(key):
|
||||
continue
|
||||
yield from _leaves(inner, f"{prefix}.{key}" if prefix else str(key))
|
||||
else:
|
||||
yield prefix, value
|
||||
|
||||
@@ -1121,6 +1121,9 @@ def exported():
|
||||
"note": "n/a",
|
||||
"final_metrics": {"train_loss": acc * 2},
|
||||
"test_metrics": {"known": {"perfect": 1.0}},
|
||||
# Keyed by a number written with its decimal point,
|
||||
# which no dotted path can address.
|
||||
"spectrum": {"-1.0": acc, "0.25": {"mean": acc}},
|
||||
},
|
||||
created_at=made + timedelta(seconds=index),
|
||||
)
|
||||
@@ -1199,6 +1202,8 @@ def test_an_exported_run_row_carries_every_recorded_input(
|
||||
assert rows[0]["metric.final_metrics.train_loss"] == 0.5
|
||||
assert rows[0]["metric.test_metrics.known.perfect"] == 1.0
|
||||
assert "metric.note" not in rows[0]
|
||||
# A key holding the separator cannot be read back, so it is not a column.
|
||||
assert not any(key.startswith("metric.spectrum") for key in rows[0])
|
||||
|
||||
named = _lines(export(format="jsonl", metrics="test_metrics.known.perfect"))
|
||||
assert list(named[0])[-1] == "metric.test_metrics.known.perfect"
|
||||
|
||||
+2
-1
@@ -134,7 +134,8 @@ the inputs that *vary* across the selection in `param.` columns (the sweep
|
||||
axis) unless `?params=` names them, and the run's numbers in `metric.`
|
||||
columns. Both are dotted paths into whatever a node returned, so
|
||||
`?metrics=final_metrics.train_loss` selects a field of a record and the
|
||||
defaults reach every number inside one. The run id is on every row of both, which is what makes an exported
|
||||
defaults reach every number inside one. A key with a dot in its own name, such
|
||||
as `-1.0`, cannot be addressed that way and gets no column. The run id is on every row of both, which is what makes an exported
|
||||
file a join back to the run rather than a loose table.
|
||||
|
||||
`compare` answers in the same shape a chart widget draws, so three training
|
||||
|
||||
Reference in New Issue
Block a user