Spaces:
Running
Running
# Copyright 2021 The TensorFlow Authors. All Rights Reserved. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# ============================================================================== | |
"""Implementation for tensorboard.summary.Writer and related symbols. | |
This provides a TensorBoard-native summary writing API that only depends | |
on numpy and not any particular ML framework. | |
""" | |
import time | |
import numpy as np | |
from tensorboard.plugins.scalar import metadata as scalars_metadata | |
from tensorboard.summary import _output | |
class Writer: | |
"""Writes summary data for visualization in TensorBoard. | |
This class is not thread-safe. | |
TODO(#4581): This API should be considered EXPERIMENTAL and subject to | |
backwards-incompatible changes without notice. | |
""" | |
def __init__(self, output): | |
"""Constructs a Writer. | |
Args: | |
output: `tensorboard.summary.Output` object, or a string which will be | |
interpreted as shorthand for an `Output` of the appropriate type. The | |
only currently supported type is `DirectoryOutput`, where the string | |
value given here will be used as the directory path. | |
""" | |
if isinstance(output, _output.Output): | |
self._output = output | |
elif isinstance(output, str): | |
self._output = _output.DirectoryOutput(output) | |
else: | |
raise TypeError("Unsupported output object %r" % output) | |
self._closed = False | |
def _check_not_closed(self): | |
if self._closed: | |
raise RuntimeError("Writer is already closed") | |
def flush(self): | |
"""Flushes any buffered data.""" | |
self._check_not_closed() | |
self._output.flush() | |
def close(self): | |
"""Closes the writer and prevents further use.""" | |
self._check_not_closed() | |
self._output.close() | |
self._closed = True | |
def add_scalar(self, tag, data, step, *, wall_time=None, description=None): | |
"""Adds a scalar summary. | |
Args: | |
tag: string tag used to uniquely identify this time series. | |
data: numeric scalar value for this data point. Accepts any value that | |
can be converted to a `np.float32` scalar. | |
step: integer step value for this data point. Accepts any value that | |
can be converted to a `np.int64` scalar. | |
wall_time: optional `float` seconds since the Unix epoch, representing | |
the real-world timestamp for this data point. Defaults to None in | |
which case the current time will be used. | |
description: optional string description for this entire time series. | |
This should be constant for a given tag; only the first value | |
encountered will be used. | |
""" | |
self._check_not_closed() | |
validated_data = _validate_scalar_shape(np.float32(data), "data") | |
validated_step = _validate_scalar_shape(np.int64(step), "step") | |
wall_time = wall_time if wall_time is not None else time.time() | |
self._output.emit_scalar( | |
plugin_name=scalars_metadata.PLUGIN_NAME, | |
tag=tag, | |
data=validated_data, | |
step=validated_step, | |
wall_time=wall_time, | |
description=description, | |
) | |
def _validate_scalar_shape(ndarray, name): | |
if ndarray.ndim != 0: | |
raise ValueError( | |
"Expected scalar value for %r but got %r" % (name, ndarray) | |
) | |
return ndarray | |