Ejemplo n.º 1
0
  def setUp(self):
    self.log_dir = tempfile.mkdtemp()

    # We use numpy.random to generate audio. We seed to avoid non-determinism
    # in this test.
    numpy.random.seed(42)

    # Create old-style audio summaries for run "foo".
    tf.reset_default_graph()
    sess = tf.Session()
    placeholder = tf.placeholder(tf.float32)
    tf.summary.audio(name="baz", tensor=placeholder, sample_rate=44100)
    merged_summary_op = tf.summary.merge_all()
    foo_directory = os.path.join(self.log_dir, "foo")
    writer = tf.summary.FileWriter(foo_directory)
    writer.add_graph(sess.graph)
    for step in xrange(2):
      # The floats (sample data) range from -1 to 1.
      writer.add_summary(sess.run(merged_summary_op, feed_dict={
          placeholder: numpy.random.rand(42, 22050) * 2 - 1
      }), global_step=step)
    writer.close()

    # Create new-style audio summaries for run "bar".
    tf.reset_default_graph()
    sess = tf.Session()
    audio_placeholder = tf.placeholder(tf.float32)
    labels_placeholder = tf.placeholder(tf.string)
    summary.op("quux", audio_placeholder, sample_rate=44100,
               labels=labels_placeholder,
               description="how do you pronounce that, anyway?")
    merged_summary_op = tf.summary.merge_all()
    bar_directory = os.path.join(self.log_dir, "bar")
    writer = tf.summary.FileWriter(bar_directory)
    writer.add_graph(sess.graph)
    for step in xrange(2):
      # The floats (sample data) range from -1 to 1.
      writer.add_summary(sess.run(merged_summary_op, feed_dict={
          audio_placeholder: numpy.random.rand(42, 11025, 1) * 2 - 1,
          labels_placeholder: [
              tf.compat.as_bytes('step **%s**, sample %s' % (step, sample))
              for sample in xrange(42)
          ],
      }), global_step=step)
    writer.close()

    # Start a server with the plugin.
    multiplexer = event_multiplexer.EventMultiplexer({
        "foo": foo_directory,
        "bar": bar_directory,
    })
    context = base_plugin.TBContext(
        logdir=self.log_dir, multiplexer=multiplexer)
    self.plugin = audio_plugin.AudioPlugin(context)
    wsgi_app = application.TensorBoardWSGIApp(
        self.log_dir, [self.plugin], multiplexer, reload_interval=0)
    self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
Ejemplo n.º 2
0
  def compute_and_check_summary_pb(self,
                                   name,
                                   audio,
                                   max_outputs=3,
                                   display_name=None,
                                   description=None,
                                   audio_tensor=None,
                                   feed_dict=None):
    """Use both `op` and `pb` to get a summary, asserting validity.

    "Validity" means that the `op` and `pb` functions must return the
    same protobufs, and also that each encoded audio value appears to be
    a valid WAV file. If either of these conditions fails, the test will
    immediately fail. Otherwise, the valid protobuf will be returned.

    Returns:
      A `Summary` protocol buffer.
    """
    if audio_tensor is None:
      audio_tensor = tf.constant(audio)
    op = summary.op(name, audio_tensor, self.samples_per_second,
                    max_outputs=max_outputs,
                    display_name=display_name, description=description)
    pb = summary.pb(name, audio, self.samples_per_second,
                    max_outputs=max_outputs,
                    display_name=display_name, description=description)
    pb_via_op = self.pb_via_op(op, feed_dict=feed_dict)
    self.assertProtoEquals(pb, pb_via_op)
    audios = tf.make_ndarray(pb.value[0].tensor)[:, 0].tolist()
    invalid_audios = [x for x in audios
                      if not x.startswith(b'RIFF')]
    self.assertFalse(invalid_audios)
    return pb
 def test_new_style_audio(self):
     audio = tf.reshape(tf.linspace(0.0, 100.0, 4 * 10 * 2), (4, 10, 2))
     op = audio_summary.op('k488',
                           tf.cast(audio, tf.float32),
                           sample_rate=44100,
                           display_name='Piano Concerto No.23',
                           description='In **A major**.')
     value = self._value_from_op(op)
     assert value.HasField('tensor'), value
     self._assert_noop(value)
Ejemplo n.º 4
0
 def test_new_style_audio(self):
   audio = tf.reshape(tf.linspace(0.0, 100.0, 4 * 10 * 2), (4, 10, 2))
   op = audio_summary.op('k488',
                         tf.cast(audio, tf.float32),
                         sample_rate=44100,
                         display_name='Piano Concerto No.23',
                         description='In **A major**.')
   value = self._value_from_op(op)
   assert value.HasField('tensor'), value
   self._assert_noop(value)
Ejemplo n.º 5
0
  def testNewStyleAudioSummary(self):
    """Verify processing of tensorboard.plugins.audio.summary."""
    event_sink = _EventGenerator(self, zero_out_timestamps=True)
    writer = test_util.FileWriter(self.get_temp_dir())
    writer.event_writer = event_sink
    with self.test_session() as sess:
      ipt = tf.random_normal(shape=[5, 441, 2])
      with tf.name_scope('1'):
        audio_summary.op('one', ipt, sample_rate=44100, max_outputs=1)
      with tf.name_scope('2'):
        audio_summary.op('two', ipt, sample_rate=44100, max_outputs=2)
      with tf.name_scope('3'):
        audio_summary.op('three', ipt, sample_rate=44100, max_outputs=3)
      merged = tf.summary.merge_all()
      writer.add_graph(sess.graph)
      for i in xrange(10):
        summ = sess.run(merged)
        writer.add_summary(summ, global_step=i)

    accumulator = ea.EventAccumulator(event_sink)
    accumulator.Reload()

    tags = [
        u'1/one/audio_summary',
        u'2/two/audio_summary',
        u'3/three/audio_summary',
    ]

    self.assertTagsEqual(accumulator.Tags(), {
        ea.TENSORS: tags,
        ea.GRAPH: True,
        ea.META_GRAPH: False,
    })
  def testNewStyleAudioSummary(self):
    """Verify processing of tensorboard.plugins.audio.summary."""
    event_sink = _EventGenerator(self, zero_out_timestamps=True)
    writer = tf.summary.FileWriter(self.get_temp_dir())
    writer.event_writer = event_sink
    with self.test_session() as sess:
      ipt = tf.random_normal(shape=[5, 441, 2])
      with tf.name_scope('1'):
        audio_summary.op('one', ipt, sample_rate=44100, max_outputs=1)
      with tf.name_scope('2'):
        audio_summary.op('two', ipt, sample_rate=44100, max_outputs=2)
      with tf.name_scope('3'):
        audio_summary.op('three', ipt, sample_rate=44100, max_outputs=3)
      merged = tf.summary.merge_all()
      writer.add_graph(sess.graph)
      for i in xrange(10):
        summ = sess.run(merged)
        writer.add_summary(summ, global_step=i)

    accumulator = ea.EventAccumulator(event_sink)
    accumulator.Reload()

    tags = [
        u'1/one/audio_summary',
        u'2/two/audio_summary',
        u'3/three/audio_summary',
    ]

    self.assertTagsEqual(accumulator.Tags(), {
        ea.TENSORS: tags,
        ea.GRAPH: True,
        ea.META_GRAPH: False,
    })
Ejemplo n.º 7
0
 def test_new_style_audio(self):
     with tf.compat.v1.Graph().as_default():
         audio = tf.reshape(tf.linspace(0.0, 100.0, 4 * 10 * 2), (4, 10, 2))
         op = audio_summary.op(
             "k488",
             tf.cast(audio, tf.float32),
             sample_rate=44100,
             display_name="Piano Concerto No.23",
             description="In **A major**.",
         )
         value = self._value_from_op(op)
     assert value.HasField("tensor"), value
     self._assert_noop(value)
Ejemplo n.º 8
0
    def testNewStyleAudioSummary(self):
        """Verify processing of tensorboard.plugins.audio.summary."""
        event_sink = _EventGenerator(self, zero_out_timestamps=True)
        writer = test_util.FileWriter(self.get_temp_dir())
        writer.event_writer = event_sink
        with tf.compat.v1.Graph().as_default():
            with self.test_session() as sess:
                ipt = tf.random.normal(shape=[5, 441, 2])
                with tf.name_scope("1"):
                    audio_summary.op("one",
                                     ipt,
                                     sample_rate=44100,
                                     max_outputs=1)
                with tf.name_scope("2"):
                    audio_summary.op("two",
                                     ipt,
                                     sample_rate=44100,
                                     max_outputs=2)
                with tf.name_scope("3"):
                    audio_summary.op("three",
                                     ipt,
                                     sample_rate=44100,
                                     max_outputs=3)
                merged = tf.compat.v1.summary.merge_all()
                writer.add_graph(sess.graph)
                for i in range(10):
                    summ = sess.run(merged)
                    writer.add_summary(summ, global_step=i)

        accumulator = ea.EventAccumulator(event_sink)
        accumulator.Reload()

        tags = [
            graph_metadata.RUN_GRAPH_NAME,
            "1/one/audio_summary",
            "2/two/audio_summary",
            "3/three/audio_summary",
        ]
        self.assertTagsEqual(
            accumulator.Tags(),
            {
                ea.TENSORS: tags,
                ea.GRAPH: True,
                ea.META_GRAPH: False,
            },
        )

        self.assertItemsEqual(
            accumulator.ActivePlugins(),
            [audio_metadata.PLUGIN_NAME, graph_metadata.PLUGIN_NAME],
        )
Ejemplo n.º 9
0
def run(logdir, run_name, wave_name, wave_constructor):
    """Generate wave data of the given form.

    The provided function `wave_constructor` should accept a scalar tensor
    of type float32, representing the frequency (in Hz) at which to
    construct a wave, and return a tensor of shape [1, _samples(), `n`]
    representing audio data (for some number of channels `n`).

    Waves will be generated at frequencies ranging from A4 to A5.

    Arguments:
      logdir: the top-level directory into which to write summary data
      run_name: the name of this run; will be created as a subdirectory
        under logdir
      wave_name: the name of the wave being generated
      wave_constructor: see above
    """
    tf.compat.v1.reset_default_graph()
    tf.compat.v1.set_random_seed(0)

    # On each step `i`, we'll set this placeholder to `i`. This allows us
    # to know "what time it is" at each step.
    step_placeholder = tf.compat.v1.placeholder(tf.float32, shape=[])

    # We want to linearly interpolate a frequency between A4 (440 Hz) and
    # A5 (880 Hz).
    with tf.name_scope("compute_frequency"):
        f_min = 440.0
        f_max = 880.0
        t = step_placeholder / (FLAGS.steps - 1)
        frequency = f_min * (1.0 - t) + f_max * t

    # Let's log this frequency, just so that we can make sure that it's as
    # expected.
    tf.compat.v1.summary.scalar("frequency", frequency)

    # Now, we pass this to the wave constructor to get our waveform. Doing
    # so within a name scope means that any summaries that the wave
    # constructor produces will be namespaced.
    with tf.name_scope(wave_name):
        waveform = wave_constructor(frequency)

    # We also have the opportunity to annotate each audio clip with a
    # label. This is a good place to include the frequency, because it'll
    # be visible immediately next to the audio clip.
    with tf.name_scope("compute_labels"):
        samples = tf.shape(input=waveform)[0]
        wave_types = tf.tile(["*Wave type:* `%s`." % wave_name], [samples])
        frequencies = tf.strings.join([
            "*Frequency:* ",
            tf.tile([tf.as_string(frequency, precision=2)], [samples]),
            " Hz.",
        ])
        samples = tf.strings.join([
            "*Sample:* ",
            tf.as_string(tf.range(samples) + 1),
            " of ",
            tf.as_string(samples),
            ".",
        ])
        labels = tf.strings.join([wave_types, frequencies, samples],
                                 separator=" ")

    # We can place a description next to the summary in TensorBoard. This
    # is a good place to explain what the summary represents, methodology
    # for creating it, etc. Let's include the source code of the function
    # that generated the wave.
    source = "\n".join("    %s" % line.rstrip()
                       for line in inspect.getsourcelines(wave_constructor)[0])
    description = "A wave of type `%r`, generated via:\n\n%s" % (
        wave_name,
        source,
    )

    # Here's the crucial piece: we interpret this result as audio.
    summary.op(
        "waveform",
        waveform,
        FLAGS.sample_rate,
        labels=labels,
        display_name=wave_name,
        description=description,
    )

    # Now, we can collect up all the summaries and begin the run.
    summ = tf.compat.v1.summary.merge_all()

    sess = tf.compat.v1.Session()
    writer = tf.summary.FileWriter(os.path.join(logdir, run_name))
    writer.add_graph(sess.graph)
    sess.run(tf.compat.v1.global_variables_initializer())
    for step in xrange(FLAGS.steps):
        s = sess.run(summ, feed_dict={step_placeholder: float(step)})
        writer.add_summary(s, global_step=step)
    writer.close()
Ejemplo n.º 10
0
 def audio(self, *args, **kwargs):
     return tf.compat.v1.Summary.FromString(
         summary.op(*args, **kwargs).numpy())
Ejemplo n.º 11
0
 def test_requires_wav_in_op(self):
     with six.assertRaisesRegex(self, ValueError, 'Unknown encoding'):
         summary.op('k488', self.stereo, 44100, encoding='pptx')
Ejemplo n.º 12
0
 def test_requires_rank_3_in_op(self):
     with six.assertRaisesRegex(self, ValueError, 'must have rank 3'):
         summary.op('k488', tf.constant([[1, 2, 3], [4, 5, 6]]), 44100)
Ejemplo n.º 13
0
def run(logdir, run_name, wave_name, wave_constructor):
  """Generate wave data of the given form.

  The provided function `wave_constructor` should accept a scalar tensor
  of type float32, representing the frequency (in Hz) at which to
  construct a wave, and return a tensor of shape [1, _samples(), `n`]
  representing audio data (for some number of channels `n`).

  Waves will be generated at frequencies ranging from A4 to A5.

  Arguments:
    logdir: the top-level directory into which to write summary data
    run_name: the name of this run; will be created as a subdirectory
      under logdir
    wave_name: the name of the wave being generated
    wave_constructor: see above
  """
  tf.reset_default_graph()
  tf.set_random_seed(0)

  # On each step `i`, we'll set this placeholder to `i`. This allows us
  # to know "what time it is" at each step.
  step_placeholder = tf.placeholder(tf.float32, shape=[])

  # We want to linearly interpolate a frequency between A4 (440 Hz) and
  # A5 (880 Hz).
  with tf.name_scope('compute_frequency'):
    f_min = 440.0
    f_max = 880.0
    t = step_placeholder / (FLAGS.steps - 1)
    frequency = f_min * (1.0 - t) + f_max * t

  # Let's log this frequency, just so that we can make sure that it's as
  # expected.
  tf.summary.scalar('frequency', frequency)

  # Now, we pass this to the wave constructor to get our waveform. Doing
  # so within a name scope means that any summaries that the wave
  # constructor produces will be namespaced.
  with tf.name_scope(wave_name):
    waveform = wave_constructor(frequency)

  # We also have the opportunity to annotate each audio clip with a
  # label. This is a good place to include the frequency, because it'll
  # be visible immediately next to the audio clip.
  with tf.name_scope('compute_labels'):
    samples = tf.shape(waveform)[0]
    wave_types = tf.tile(["*Wave type:* `%s`." % wave_name], [samples])
    frequencies = tf.string_join([
        "*Frequency:* ",
        tf.tile([tf.as_string(frequency, precision=2)], [samples]),
        " Hz.",
    ])
    samples = tf.string_join([
        "*Sample:* ", tf.as_string(tf.range(samples) + 1),
        " of ", tf.as_string(samples), ".",
    ])
    labels = tf.string_join([wave_types, frequencies, samples], separator=" ")

  # We can place a description next to the summary in TensorBoard. This
  # is a good place to explain what the summary represents, methodology
  # for creating it, etc. Let's include the source code of the function
  # that generated the wave.
  source = '\n'.join('    %s' % line.rstrip()
                     for line in inspect.getsourcelines(wave_constructor)[0])
  description = ("A wave of type `%r`, generated via:\n\n%s"
                 % (wave_name, source))

  # Here's the crucial piece: we interpret this result as audio.
  summary.op('waveform', waveform, FLAGS.sample_rate,
             labels=labels,
             display_name=wave_name,
             description=description)

  # Now, we can collect up all the summaries and begin the run.
  summ = tf.summary.merge_all()

  sess = tf.Session()
  writer = tf.summary.FileWriter(os.path.join(logdir, run_name))
  writer.add_graph(sess.graph)
  sess.run(tf.global_variables_initializer())
  for step in xrange(FLAGS.steps):
    s = sess.run(summ, feed_dict={step_placeholder: float(step)})
    writer.add_summary(s, global_step=step)
  writer.close()
Ejemplo n.º 14
0
  def setUp(self):
    self.log_dir = tempfile.mkdtemp()

    # We use numpy.random to generate audio. We seed to avoid non-determinism
    # in this test.
    numpy.random.seed(42)

    # Create old-style audio summaries for run "foo".
    tf.compat.v1.reset_default_graph()
    sess = tf.compat.v1.Session()
    placeholder = tf.compat.v1.placeholder(tf.float32)
    tf.compat.v1.summary.audio(name="baz", tensor=placeholder, sample_rate=44100)
    merged_summary_op = tf.compat.v1.summary.merge_all()
    foo_directory = os.path.join(self.log_dir, "foo")
    with test_util.FileWriterCache.get(foo_directory) as writer:
      writer.add_graph(sess.graph)
      for step in xrange(2):
        # The floats (sample data) range from -1 to 1.
        writer.add_summary(sess.run(merged_summary_op, feed_dict={
            placeholder: numpy.random.rand(42, 22050) * 2 - 1
        }), global_step=step)

    # Create new-style audio summaries for run "bar".
    tf.compat.v1.reset_default_graph()
    sess = tf.compat.v1.Session()
    audio_placeholder = tf.compat.v1.placeholder(tf.float32)
    labels_placeholder = tf.compat.v1.placeholder(tf.string)
    summary.op("quux", audio_placeholder, sample_rate=44100,
               labels=labels_placeholder,
               description="how do you pronounce that, anyway?")
    merged_summary_op = tf.compat.v1.summary.merge_all()
    bar_directory = os.path.join(self.log_dir, "bar")
    with test_util.FileWriterCache.get(bar_directory) as writer:
      writer.add_graph(sess.graph)
      for step in xrange(2):
        # The floats (sample data) range from -1 to 1.
        writer.add_summary(sess.run(merged_summary_op, feed_dict={
            audio_placeholder: numpy.random.rand(42, 11025, 1) * 2 - 1,
            labels_placeholder: [
                tf.compat.as_bytes('step **%s**, sample %s' % (step, sample))
                for sample in xrange(42)
            ],
        }), global_step=step)

    # Start a server with the plugin.
    multiplexer = event_multiplexer.EventMultiplexer({
        "foo": foo_directory,
        "bar": bar_directory,
    })
    context = base_plugin.TBContext(
        logdir=self.log_dir, multiplexer=multiplexer)
    self.plugin = audio_plugin.AudioPlugin(context)
    # Setting a reload interval of -1 disables reloading. We disable reloading
    # because we seek to block tests from running til after one reload finishes.
    # This setUp method thus manually reloads the multiplexer. TensorBoard would
    # otherwise reload in a non-blocking thread.
    wsgi_app = application.TensorBoardWSGIApp(
        self.log_dir, [self.plugin], multiplexer, reload_interval=-1,
        path_prefix='')
    self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
    multiplexer.Reload()
Ejemplo n.º 15
0
 def test_requires_wav_in_op(self):
   with six.assertRaisesRegex(self, ValueError, 'Unknown encoding'):
     summary.op('k488', self.stereo, 44100, encoding='pptx')
Ejemplo n.º 16
0
 def test_requires_rank_3_in_op(self):
   with six.assertRaisesRegex(self, ValueError, 'must have rank 3'):
     summary.op('k488', tf.constant([[1, 2, 3], [4, 5, 6]]), 44100)