| 407 | |
| 408 | |
| 409 | class TensorBoardParser: |
| 410 | def __init__(self, log_dir: str): |
| 411 | self.log_dir = log_dir |
| 412 | self._event_files = self._find_event_files(log_dir) |
| 413 | self._metrics = self._load_metrics() |
| 414 | |
| 415 | def _find_event_files(self, log_dir: str) -> List[str]: |
| 416 | event_files = [] |
| 417 | for root, _, files in os.walk(log_dir): |
| 418 | for f in files: |
| 419 | if f.startswith("events.out.tfevents."): |
| 420 | event_files.append(os.path.join(root, f)) |
| 421 | return event_files |
| 422 | |
| 423 | def _load_metrics(self) -> Dict[str, Dict[int, float]]: |
| 424 | metrics = defaultdict(dict) |
| 425 | |
| 426 | for event_file in self._event_files: |
| 427 | ea = EventAccumulator(event_file) |
| 428 | ea.Reload() |
| 429 | tags = ea.Tags()["scalars"] |
| 430 | for tag in tags: |
| 431 | scalars = ea.Scalars(tag) |
| 432 | for scalar in scalars: |
| 433 | step = scalar.step |
| 434 | value = scalar.value |
| 435 | if step not in metrics[tag] or value > metrics[tag][step]: |
| 436 | metrics[tag][step] = value |
| 437 | return dict(metrics) |
| 438 | |
| 439 | def metric_exist(self, metric_name: str) -> bool: |
| 440 | return metric_name in self._metrics |
| 441 | |
| 442 | def metric_min_step(self, metric_name: str) -> int: |
| 443 | return min(self.metric_steps(metric_name)) |
| 444 | |
| 445 | def metric_max_step(self, metric_name: str) -> int: |
| 446 | return max(self.metric_steps(metric_name)) |
| 447 | |
| 448 | def metric_steps(self, metric_name: str) -> List[int]: |
| 449 | if not self.metric_exist(metric_name): |
| 450 | raise ValueError(f"Metric '{metric_name}' does not exist.") |
| 451 | return list(self._metrics[metric_name].keys()) |
| 452 | |
| 453 | def metric_values(self, metric_name: str) -> List: |
| 454 | if not self.metric_exist(metric_name): |
| 455 | raise ValueError(f"Metric '{metric_name}' does not exist.") |
| 456 | return list(self._metrics[metric_name].values()) |
| 457 | |
| 458 | def metric_list(self, metric_prefix: str) -> List[str]: |
| 459 | return [name for name in self._metrics if name.startswith(metric_prefix)] |
| 460 | |
| 461 | |
| 462 | class RayCleanupPlugin: |
no outgoing calls