The user-facing class that provides metric storage functionalities. In the future we may add support for storing / logging other types of data if needed.
| 261 | |
| 262 | |
| 263 | class EventStorage: |
| 264 | """ |
| 265 | The user-facing class that provides metric storage functionalities. |
| 266 | |
| 267 | In the future we may add support for storing / logging other types of data if needed. |
| 268 | """ |
| 269 | |
| 270 | def __init__(self, start_iter=0): |
| 271 | """ |
| 272 | Args: |
| 273 | start_iter (int): the iteration number to start with |
| 274 | """ |
| 275 | self._history = defaultdict(HistoryBuffer) |
| 276 | self._smoothing_hints = {} |
| 277 | self._latest_scalars = {} |
| 278 | self._iter = start_iter |
| 279 | self._current_prefix = "" |
| 280 | self._vis_data = [] |
| 281 | self._histograms = [] |
| 282 | |
| 283 | def put_image(self, img_name, img_tensor): |
| 284 | """ |
| 285 | Add an `img_tensor` associated with `img_name`, to be shown on |
| 286 | tensorboard. |
| 287 | |
| 288 | Args: |
| 289 | img_name (str): The name of the image to put into tensorboard. |
| 290 | img_tensor (torch.Tensor or numpy.array): An `uint8` or `float` |
| 291 | Tensor of shape `[channel, height, width]` where `channel` is |
| 292 | 3. The image format should be RGB. The elements in img_tensor |
| 293 | can either have values in [0, 1] (float32) or [0, 255] (uint8). |
| 294 | The `img_tensor` will be visualized in tensorboard. |
| 295 | """ |
| 296 | self._vis_data.append((img_name, img_tensor, self._iter)) |
| 297 | |
| 298 | def put_scalar(self, name, value, smoothing_hint=True): |
| 299 | """ |
| 300 | Add a scalar `value` to the `HistoryBuffer` associated with `name`. |
| 301 | |
| 302 | Args: |
| 303 | smoothing_hint (bool): a 'hint' on whether this scalar is noisy and should be |
| 304 | smoothed when logged. The hint will be accessible through |
| 305 | :meth:`EventStorage.smoothing_hints`. A writer may ignore the hint |
| 306 | and apply custom smoothing rule. |
| 307 | |
| 308 | It defaults to True because most scalars we save need to be smoothed to |
| 309 | provide any useful signal. |
| 310 | """ |
| 311 | name = self._current_prefix + name |
| 312 | history = self._history[name] |
| 313 | value = float(value) |
| 314 | history.update(value, self._iter) |
| 315 | self._latest_scalars[name] = (value, self._iter) |
| 316 | |
| 317 | existing_hint = self._smoothing_hints.get(name) |
| 318 | if existing_hint is not None: |
| 319 | assert ( |
| 320 | existing_hint == smoothing_hint |
no outgoing calls