Beispiel #1
0
def text(name, data, step, description=None):
    """Write a text summary.

  Arguments:
    name: A name for this summary. The summary tag used for TensorBoard will
      be this name prefixed by any active name scopes.
    data: A UTF-8 string tensor value.
    step: Required `int64`-castable monotonic step value.
    description: Optional long-form description for this summary, as a
      constant `str`. Markdown is supported. Defaults to empty.

  Returns:
    True on success, or false if no summary was emitted because no default
    summary writer was available.
  """
    # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
    from tensorboard import compat
    tf = compat.import_tf_v2()
    summary_metadata = metadata.create_summary_metadata(
        display_name=None, description=description)
    with tf.summary.summary_scope(name, 'text_summary',
                                  values=[data, step]) as (tag, _):
        tf.debugging.assert_type(data, tf.string)
        return tf.summary.write(tag=tag,
                                tensor=data,
                                step=step,
                                metadata=summary_metadata)
Beispiel #2
0
def histogram(name, data, step, buckets=None, description=None):
    """Write a histogram summary.

  Arguments:
    name: A name for this summary. The summary tag used for TensorBoard will
      be this name prefixed by any active name scopes.
    data: A `Tensor` of any shape. Must be castable to `float64`.
    step: Required `int64`-castable monotonic step value.
    buckets: Optional positive `int`. The output will have this
      many buckets, except in two edge cases. If there is no data, then
      there are no buckets. If there is data but all points have the
      same value, then there is one bucket whose left and right
      endpoints are the same.
    description: Optional long-form description for this summary, as a
      constant `str`. Markdown is supported. Defaults to empty.

  Returns:
    True on success, or false if no summary was emitted because no default
    summary writer was available.
  """
    # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
    from tensorboard import compat
    tf = compat.import_tf_v2()
    summary_metadata = metadata.create_summary_metadata(
        display_name=None, description=description)
    with tf.summary.summary_scope(name,
                                  'histogram_summary',
                                  values=[data, buckets, step]) as (tag, _):
        tensor = _buckets(data, bucket_count=buckets)
        return tf.summary.write(tag=tag,
                                tensor=tensor,
                                step=step,
                                metadata=summary_metadata)
Beispiel #3
0
def image(name, data, step, max_outputs=3, description=None):
    """Write an image summary.

  Arguments:
    name: A name for this summary. The summary tag used for TensorBoard will
      be this name prefixed by any active name scopes.
    data: A `Tensor` representing pixel data with shape `[k, h, w, c]`,
      where `k` is the number of images, `h` and `w` are the height and
      width of the images, and `c` is the number of channels, which
      should be 1, 2, 3, or 4 (grayscale, grayscale with alpha, RGB, RGBA).
      Any of the dimensions may be statically unknown (i.e., `None`).
      Floating point data will be clipped to the range [0,1).
    step: Required `int64`-castable monotonic step value.
    max_outputs: Optional `int` or rank-0 integer `Tensor`. At most this
      many images will be emitted at each step. When more than
      `max_outputs` many images are provided, the first `max_outputs` many
      images will be used and the rest silently discarded.
    description: Optional long-form description for this summary, as a
      constant `str`. Markdown is supported. Defaults to empty.

  Returns:
    True on success, or false if no summary was emitted because no default
    summary writer was available.
  """
    # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
    from tensorboard import compat
    tf = compat.import_tf_v2()
    summary_metadata = metadata.create_summary_metadata(
        display_name=None, description=description)
    with tf.summary.summary_scope(name,
                                  'image_summary',
                                  values=[data, max_outputs,
                                          step]) as (tag, _):
        tf.debugging.assert_rank(data, 4)
        tf.debugging.assert_non_negative(max_outputs)
        images = tf.image.convert_image_dtype(data, tf.uint8, saturate=True)
        limited_images = images[:max_outputs]
        encoded_images = tf.map_fn(tf.image.encode_png,
                                   limited_images,
                                   dtype=tf.string,
                                   name='encode_each_image')
        # Workaround for map_fn returning float dtype for an empty elems input.
        encoded_images = tf.cond(
            tf.shape(input=encoded_images)[0] > 0, lambda: encoded_images,
            lambda: tf.constant([], tf.string))
        image_shape = tf.shape(input=images)
        dimensions = tf.stack([
            tf.as_string(image_shape[2], name='width'),
            tf.as_string(image_shape[1], name='height')
        ],
                              name='dimensions')
        tensor = tf.concat([dimensions, encoded_images], axis=0)
        return tf.summary.write(tag=tag,
                                tensor=tensor,
                                step=step,
                                metadata=summary_metadata)
Beispiel #4
0
from __future__ import division
from __future__ import print_function

import glob
import os

import numpy as np
import tensorflow as tf

from tensorboard.plugins.histogram import metadata
from tensorboard.plugins.histogram import summary
from tensorboard.util import tensor_util

try:
    from tensorboard import compat
    tf_v2 = compat.import_tf_v2()
except ImportError:
    tf_v2 = None

try:
    tf.enable_eager_execution()
except AttributeError:
    # TF 2.0 doesn't have this symbol because eager is the default.
    pass


class SummaryBaseTest(object):
    def setUp(self):
        super(SummaryBaseTest, self).setUp()
        np.random.seed(0)
        self.gaussian = np.random.normal(size=[100])
Beispiel #5
0
def audio(name,
          data,
          sample_rate,
          step,
          max_outputs=3,
          encoding=None,
          description=None):
    """Write an audio summary.

  Arguments:
    name: A name for this summary. The summary tag used for TensorBoard will
      be this name prefixed by any active name scopes.
    data: A `Tensor` representing audio data with shape `[k, t, c]`,
      where `k` is the number of audio clips, `t` is the number of
      frames, and `c` is the number of channels. Elements should be
      floating-point values in `[-1.0, 1.0]`. Any of the dimensions may
      be statically unknown (i.e., `None`).
    sample_rate: An `int` or rank-0 `int32` `Tensor` that represents the
      sample rate, in Hz. Must be positive.
    step: Required `int64`-castable monotonic step value.
    max_outputs: Optional `int` or rank-0 integer `Tensor`. At most this
      many audio clips will be emitted at each step. When more than
      `max_outputs` many clips are provided, the first `max_outputs`
      many clips will be used and the rest silently discarded.
    encoding: Optional constant `str` for the desired encoding. Only "wav"
      is currently supported, but this is not guaranteed to remain the
      default, so if you want "wav" in particular, set this explicitly.
    description: Optional long-form description for this summary, as a
      constant `str`. Markdown is supported. Defaults to empty.

  Returns:
    True on success, or false if no summary was emitted because no default
    summary writer was available.
  """
    # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
    from tensorboard import compat
    tf = compat.import_tf_v2()
    # TODO(nickfelt): get encode_wav() exported in the public API.
    from tensorflow.python.ops import gen_audio_ops

    if encoding is None:
        encoding = 'wav'
    if encoding != 'wav':
        raise ValueError('Unknown encoding: %r' % encoding)
    summary_metadata = metadata.create_summary_metadata(
        display_name=None,
        description=description,
        encoding=metadata.Encoding.Value('WAV'))
    inputs = [data, sample_rate, max_outputs, step]
    with tf.summary.summary_scope(name, 'audio_summary',
                                  values=inputs) as (tag, _):
        tf.debugging.assert_rank(data, 3)
        tf.debugging.assert_non_negative(max_outputs)
        limited_audio = data[:max_outputs]
        encode_fn = functools.partial(gen_audio_ops.encode_wav,
                                      sample_rate=sample_rate)
        encoded_audio = tf.map_fn(encode_fn,
                                  limited_audio,
                                  dtype=tf.string,
                                  name='encode_each_audio')
        # Workaround for map_fn returning float dtype for an empty elems input.
        encoded_audio = tf.cond(
            tf.shape(input=encoded_audio)[0] > 0, lambda: encoded_audio,
            lambda: tf.constant([], tf.string))
        limited_labels = tf.tile([''], tf.shape(input=limited_audio)[:1])
        tensor = tf.transpose(a=tf.stack([encoded_audio, limited_labels]))
        return tf.summary.write(tag=tag,
                                tensor=tensor,
                                step=step,
                                metadata=summary_metadata)
Beispiel #6
0
def _buckets(data, bucket_count=None):
    """Create a TensorFlow op to group data into histogram buckets.

  Arguments:
    data: A `Tensor` of any shape. Must be castable to `float64`.
    bucket_count: Optional positive `int` or scalar `int32` `Tensor`.
  Returns:
    A `Tensor` of shape `[k, 3]` and type `float64`. The `i`th row is
    a triple `[left_edge, right_edge, count]` for a single bucket.
    The value of `k` is either `bucket_count` or `1` or `0`.
  """
    # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
    from tensorboard import compat
    tf = compat.import_tf_v2()
    if bucket_count is None:
        bucket_count = DEFAULT_BUCKET_COUNT
    with tf.name_scope('buckets', values=[data, bucket_count]):
        tf.debugging.assert_scalar(bucket_count)
        tf.debugging.assert_type(bucket_count, tf.int32)
        data = tf.reshape(data, shape=[-1])  # flatten
        data = tf.cast(data, tf.float64)
        is_empty = tf.equal(tf.size(data), 0)

        def when_empty():
            return tf.constant([], shape=(0, 3), dtype=tf.float64)

        def when_nonempty():
            min_ = tf.reduce_min(data)
            max_ = tf.reduce_max(data)
            range_ = max_ - min_
            is_singular = tf.equal(range_, 0)

            def when_nonsingular():
                bucket_width = range_ / tf.cast(bucket_count, tf.float64)
                offsets = data - min_
                bucket_indices = tf.cast(tf.floor(offsets / bucket_width),
                                         dtype=tf.int32)
                clamped_indices = tf.minimum(bucket_indices, bucket_count - 1)
                one_hots = tf.one_hot(clamped_indices, depth=bucket_count)
                bucket_counts = tf.cast(tf.reduce_sum(one_hots, axis=0),
                                        dtype=tf.float64)
                edges = tf.linspace(min_, max_, bucket_count + 1)
                # Ensure edges[-1] == max_, which TF's linspace implementation does not
                # do, leaving it subject to the whim of floating point rounding error.
                edges = tf.concat([edges[:-1], [max_]], 0)
                left_edges = edges[:-1]
                right_edges = edges[1:]
                return tf.transpose(
                    tf.stack([left_edges, right_edges, bucket_counts]))

            def when_singular():
                center = min_
                bucket_starts = tf.stack([center - 0.5])
                bucket_ends = tf.stack([center + 0.5])
                bucket_counts = tf.stack([tf.cast(tf.size(data), tf.float64)])
                return tf.transpose(
                    tf.stack([bucket_starts, bucket_ends, bucket_counts]))

            return tf.cond(is_singular, when_singular, when_nonsingular)

        return tf.cond(is_empty, when_empty, when_nonempty)