Ensure tf.summary.X ops can accept spaces in the "name" field.

The old tf.X_summary ops used "tag" as their first arg, which allowed
spaces.

The new tf.summary.X ops use "name" as their first arg, which would
disallow spaces. To make an easy, backwards compatible transition,
these ops now convert spaces to underscores and log a warning.
Change: 136760473
This commit is contained in:
Dan Mané 2016-10-20 13:26:53 -08:00 committed by TensorFlower Gardener
parent 5e48873977
commit af1c9a17a4
3 changed files with 25 additions and 0 deletions
tensorflow/python

View File

@ -2100,6 +2100,7 @@ py_library(
deps = [
":client",
":framework",
":platform",
":protos_all_py",
":pywrap_tensorflow",
":summary_ops",

View File

@ -44,6 +44,7 @@ from tensorflow.python.ops import gen_logging_ops as _gen_logging_ops
# pylint: disable=unused-import
from tensorflow.python.ops.summary_ops import tensor_summary
# pylint: enable=unused-import
from tensorflow.python.platform import tf_logging as _logging
from tensorflow.python.util.all_util import remove_undocumented
from tensorflow.python.util import compat as _compat
@ -55,6 +56,19 @@ def _collect(val, collections, default_collections):
_ops.add_to_collection(key, val)
def _clean_tag(name):
# In the past, the first argument to summary ops was a tag, which allowed
# spaces. Since now we pass in the name, spaces are disallowed; to ease the
# transition and support backwards compatbility, we will convert the spaces
# to underscores (and also warn about it).
if name is not None and ' ' in name:
_logging.warning(
'Summary tag name %s contains spaces; replacing with underscores.' %
name)
name = name.replace(' ', '_')
return name
def scalar(name, tensor, collections=None):
"""Outputs a `Summary` protocol buffer containing a single scalar value.
@ -73,6 +87,7 @@ def scalar(name, tensor, collections=None):
Raises:
ValueError: If tensor has the wrong shape or type.
"""
name = _clean_tag(name)
with _ops.name_scope(name, None, [tensor]) as scope:
# pylint: disable=protected-access
val = _gen_logging_ops._scalar_summary(
@ -124,6 +139,7 @@ def image(name, tensor, max_outputs=3, collections=None):
A scalar `Tensor` of type `string`. The serialized `Summary` protocol
buffer.
"""
name = _clean_tag(name)
with _ops.name_scope(name, None, [tensor]) as scope:
# pylint: disable=protected-access
val = _gen_logging_ops._image_summary(
@ -158,6 +174,7 @@ def histogram(name, values, collections=None):
buffer.
"""
# pylint: enable=line-too-long
name = _clean_tag(name)
with _ops.name_scope(name, 'HistogramSummary', [values]) as scope:
# pylint: disable=protected-access
val = _gen_logging_ops._histogram_summary(
@ -199,6 +216,7 @@ def audio(name, tensor, sample_rate, max_outputs=3, collections=None):
buffer.
"""
# pylint: enable=line-too-long
name = _clean_tag(name)
with _ops.name_scope(name, None, [tensor]) as scope:
# pylint: disable=protected-access
sample_rate = _ops.convert_to_tensor(
@ -237,6 +255,7 @@ def merge(inputs, collections=None, name=None):
buffer resulting from the merging.
"""
# pylint: enable=line-too-long
name = _clean_tag(name)
with _ops.name_scope(name, 'Merge', inputs):
# pylint: disable=protected-access
val = _gen_logging_ops._merge_summary(inputs=inputs, name=name)

View File

@ -65,6 +65,11 @@ class ScalarSummaryTest(tf.test.TestCase):
self.assertEqual(len(summary.value), 1)
self.assertEqual(summary.value[0].tag, 'outer/inner')
def testSummaryNameConversion(self):
c = tf.constant(3)
s = tf.summary.scalar('name with spaces', c)
self.assertEqual(s.op.name, 'name_with_spaces')
if __name__ == '__main__':
tf.test.main()