fix(dashboard): add alpha temperature to training losses panel
This commit is contained in:
@@ -5,7 +5,7 @@ Pure-stdlib SVG output (matplotlib not available on this box).
|
||||
Generates ONE file:
|
||||
docs/campaign_dashboard.svg - four panels, current (v2) run only:
|
||||
1. test-match win % vs opponents (campaign_v4_stdout.log eval lines)
|
||||
2. critic_loss / |actor_loss| (training_metrics.jsonl, shared log-y)
|
||||
2. critic_loss / |actor_loss| / alpha (training_metrics.jsonl, shared log-y)
|
||||
3. alpha temperature (training_metrics.jsonl, linear)
|
||||
4. throughput, games/hour buckets (training_metrics.jsonl 'epoch' deltas;
|
||||
1 metrics row == one 10-game chunk,
|
||||
@@ -36,6 +36,7 @@ GAMES_PER_ROW = 10 # one training_metrics.jsonl row per 10-round chunk
|
||||
COLORS = {"Corners": "#d62728", "Crazy": "#1f77b4", "Target": "#2ca02c",
|
||||
"RamFire": "#ff7f0e", "SacTwin": "#9467bd"}
|
||||
CRITIC_C, ACTOR_C = "#1f77b4", "#ff7f0e"
|
||||
ALPHA_C = "#9467bd" # same purple as the dedicated alpha panel
|
||||
RELOAD_JS = ('<script type="text/javascript"><![CDATA[ '
|
||||
'setTimeout(function(){ location.reload(); }, 60000); ]]></script>')
|
||||
W, H = 1400, 1720
|
||||
@@ -51,7 +52,7 @@ ROWS = {
|
||||
}
|
||||
PANEL_TITLES = [
|
||||
"Test matches - win % vs opponents",
|
||||
"Training losses (log scale)",
|
||||
"Training losses & alpha (log scale)",
|
||||
"Alpha temperature",
|
||||
"Throughput - games per hour",
|
||||
]
|
||||
@@ -285,11 +286,12 @@ def panel_losses(rows, geo):
|
||||
critic = metric_col(rows, "critic_loss", positive=True)
|
||||
actor = metric_col(rows, "actor_loss") # abs() applied; sign dropped
|
||||
actor = [(i, v) for i, v in actor if v > 0]
|
||||
if not (critic or actor):
|
||||
alpha = metric_col(rows, "alpha")
|
||||
if not (critic or actor or alpha):
|
||||
s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \
|
||||
"no valid loss points</text>\n"
|
||||
return
|
||||
allv = [v for _, v in critic + actor]
|
||||
allv = [v for _, v in critic + actor + alpha]
|
||||
lo, hi = math.floor(math.log10(min(allv))), math.ceil(math.log10(max(allv)))
|
||||
if lo == hi:
|
||||
hi = lo + 1
|
||||
@@ -301,8 +303,11 @@ def panel_losses(rows, geo):
|
||||
ticks_log(lo, hi, pb, pt), "metric line number", "loss (log)")
|
||||
s += polyline([(xm(i), ym(v)) for i, v in critic], CRITIC_C, 1.8)
|
||||
s += polyline([(xm(i), ym(v)) for i, v in actor], ACTOR_C, 1.8)
|
||||
s += legend([(CRITIC_C, "critic_loss"), (ACTOR_C, "|actor_loss|")],
|
||||
x0 + 12, pb + 52)
|
||||
s += polyline([(xm(i), ym(v)) for i, v in alpha], ALPHA_C, 1.8)
|
||||
items = [(CRITIC_C, "critic_loss"), (ACTOR_C, "|actor_loss|")]
|
||||
if alpha:
|
||||
items.append((ALPHA_C, "alpha"))
|
||||
s += legend(items, x0 + 12, pb + 52)
|
||||
return s
|
||||
|
||||
def panel_alpha(rows, geo):
|
||||
@@ -435,14 +440,15 @@ def selftest():
|
||||
ET.fromstring(text) # whole doc must parse -> closing tag present
|
||||
assert RELOAD_JS in text, "auto-reload script missing"
|
||||
for t in PANEL_TITLES:
|
||||
assert t in text, f"panel title missing: {t}"
|
||||
assert esc(t) in text, f"panel title missing: {t}"
|
||||
assert text.count(PANEL_TITLES[0]) == 1
|
||||
assert "How to read" in text, "reading guide missing"
|
||||
assert 'width="1400"' in text and 'height="1720"' in text
|
||||
# circles: 4 eval dots (panel 1) + 2 throughput rate dots (panel 4)
|
||||
assert text.count("<circle") == 6, text.count("<circle")
|
||||
# 2 trends + 2 losses + 1 alpha + 1 throughput
|
||||
assert text.count("<polyline") == 6, text.count("<polyline")
|
||||
# 2 trends + 3 losses-panel polylines (critic, actor, alpha)
|
||||
# + 1 dedicated alpha panel + 1 throughput
|
||||
assert text.count("<polyline") == 7, text.count("<polyline")
|
||||
|
||||
# orientation guard: a known rising series (10% -> 90%) rendered through
|
||||
# the FULL build path must plot upward (smaller SVG y) and forward in
|
||||
|
||||
Reference in New Issue
Block a user