Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

logger.py 6.0 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  1. import os
  2. from contextlib import contextmanager
  3. from datetime import datetime
  4. from typing import TextIO, ContextManager, Any, Dict
  5. import yaml
  6. class DAGsHubLogger:
  7. """
  8. A plain Python logger for your metrics and hyperparameters.
  9. The saved file format is plain and open - CSV for metrics files, YAML for hyperparameters.
  10. You can use this logger manually, or use one of our integrations with high-level libraries like Keras or pytorch-lightning.
  11. """
  12. metrics_file: TextIO
  13. hparams: Dict[str, Any]
  14. def __init__(self,
  15. metrics_path: str = 'metrics.csv',
  16. should_log_metrics: bool = True,
  17. hparams_path: str = 'params.yml',
  18. should_log_hparams: bool = True,
  19. should_make_dirs: bool = True,
  20. eager_logging: bool = True,
  21. ):
  22. """
  23. :param metrics_path: Where to save the single metrics CSV file.
  24. :param should_log_metrics: Whether to log metrics at all. Should probably always be True.
  25. :param hparams_path: Where to save the single hyperparameter YAML file.
  26. :param should_log_hparams: Whether to log hyperparameters to a file.
  27. Should be False if you want to work with hyperparameters in a dependency file,
  28. rather than specifying them using command line arguments.
  29. :param should_make_dirs: If true, the directory structure required by metrics_path and hparams_path
  30. will be created. Has no effect if the directory structure already exists.
  31. :param eager_logging: If true, the logged metrics and hyperparams will be saved to file immediately.
  32. If false, the logger will wait until save() is called, and until then, will hold metrics and hyperparams
  33. in memory. Watch out not to run out of memory!
  34. """
  35. self.metrics_path = metrics_path
  36. self.should_log_metrics = should_log_metrics
  37. self.hparams_path = hparams_path
  38. self.should_log_hparams = should_log_hparams
  39. self.should_make_dirs = should_make_dirs
  40. self.eager_logging = eager_logging
  41. self.unsaved_metrics = []
  42. self.hparams = {}
  43. if eager_logging:
  44. self.save()
  45. def log_metrics(self, metrics: Dict[str, Any] = None, step_num: int = 1, **kwargs):
  46. if self.should_log_metrics:
  47. copy_of_metrics = dict(metrics or {})
  48. copy_of_metrics.update(kwargs)
  49. self.unsaved_metrics.append((copy_of_metrics, self.epoch_milisec(), step_num))
  50. if self.eager_logging:
  51. self.save_metrics()
  52. @staticmethod
  53. def epoch_milisec():
  54. microsec_timestamp = datetime.now().timestamp()
  55. return int(microsec_timestamp * 1000)
  56. def log_hyperparams(self, params: Dict[str, Any] = None, **kwargs):
  57. if self.should_log_hparams:
  58. self.hparams.update(params or {})
  59. self.hparams.update(kwargs)
  60. if self.eager_logging:
  61. self.save_hparams()
  62. def save(self):
  63. self.save_metrics()
  64. self.save_hparams()
  65. def save_metrics(self):
  66. if self.should_log_metrics:
  67. if not hasattr(self, 'metrics_file'):
  68. self.init_metrics_file()
  69. for metrics, timestamp, step_num in self.unsaved_metrics:
  70. for name, value in metrics.items():
  71. self.metrics_file.write(f'{name},{value},{timestamp},{step_num}\n')
  72. self.unsaved_metrics = []
  73. def save_hparams(self):
  74. if self.should_log_hparams:
  75. self.ensure_dir(self.hparams_path)
  76. with open(self.hparams_path, 'w') as f:
  77. yaml.safe_dump(self.hparams, f)
  78. def init_metrics_file(self):
  79. self.ensure_dir(self.metrics_path)
  80. self.metrics_file = open(self.metrics_path, 'w')
  81. self.metrics_file.write("Name,Value,Timestamp,Step\n")
  82. def ensure_dir(self, filename: str):
  83. if self.should_make_dirs:
  84. dirname = os.path.dirname(filename)
  85. if dirname:
  86. os.makedirs(dirname, exist_ok=True)
  87. def close(self):
  88. if hasattr(self, 'metrics_file'):
  89. self.metrics_file.close()
  90. @contextmanager
  91. def dagshub_logger(metrics_path: str = 'metrics.csv',
  92. should_log_metrics: bool = True,
  93. hparams_path: str = 'params.yml',
  94. should_log_hparams: bool = True,
  95. should_make_dirs: bool = True,
  96. eager_logging: bool = True, ) -> ContextManager[DAGsHubLogger]:
  97. """
  98. Example usage:
  99. with dagshub_logger() as logger:
  100. logger.log_hyperparams( {'lr': 1e-3, 'num_layers': 42} )\n
  101. logger.log_metrics( {'loss': 3.14, 'val_loss': 6.28} )\n
  102. logger.log_metrics(acc=0.999)\n
  103. :param metrics_path: Where to save the single metrics CSV file.
  104. :param should_log_metrics: Whether to log metrics at all. Should probably always be True.
  105. :param hparams_path: Where to save the single hyperparameter YAML file.
  106. :param should_log_hparams: Whether to log hyperparameters to a file.
  107. Should be False if you want to work with hyperparameters in a dependency file,
  108. rather than specifying them using command line arguments.
  109. :param should_make_dirs: If true, the directory structure required by metrics_path and hparams_path
  110. will be created. Has no effect if the directory structure already exists.
  111. :param eager_logging: If true, the logged metrics and hyperparams will be saved to file immediately.
  112. If false, the logger will wait until save() is called, and until then, will hold metrics and hyperparams
  113. in memory. Watch out not to run out of memory!
  114. """
  115. logger = DAGsHubLogger(metrics_path=metrics_path, should_log_metrics=should_log_metrics,
  116. hparams_path=hparams_path, should_log_hparams=should_log_hparams,
  117. should_make_dirs=should_make_dirs, eager_logging=eager_logging)
  118. try:
  119. yield logger
  120. finally:
  121. logger.save()
  122. logger.close()
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...