mirror of
https://github.com/zebrajr/tensorflow.git
synced 2025-12-07 00:20:20 +01:00
Add some routines for managing summaries to slim.
PiperOrigin-RevId: 157541902
This commit is contained in:
parent
d58cd29620
commit
37d9d5f0e8
|
|
@ -144,6 +144,7 @@ py_library(
|
|||
":learning",
|
||||
":model_analyzer",
|
||||
":queues",
|
||||
":summaries",
|
||||
"//tensorflow/contrib/framework:framework_py",
|
||||
"//tensorflow/contrib/layers:layers_py",
|
||||
"//tensorflow/contrib/losses:losses_py",
|
||||
|
|
@ -160,6 +161,32 @@ py_library(
|
|||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "summaries",
|
||||
srcs = ["python/slim/summaries.py"],
|
||||
srcs_version = "PY2AND3",
|
||||
deps = [
|
||||
"//tensorflow/python:framework",
|
||||
"//tensorflow/python:logging_ops",
|
||||
"//tensorflow/python:nn",
|
||||
"//tensorflow/python:summary",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "summaries_test",
|
||||
srcs = ["python/slim/summaries_test.py"],
|
||||
srcs_version = "PY2AND3",
|
||||
deps = [
|
||||
":summaries",
|
||||
"//tensorflow/python:array_ops",
|
||||
"//tensorflow/python:client_testlib",
|
||||
"//tensorflow/python:framework",
|
||||
"//tensorflow/python:platform",
|
||||
"//tensorflow/python:summary",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all_files",
|
||||
srcs = glob(
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ from tensorflow.contrib.slim.python.slim import evaluation
|
|||
from tensorflow.contrib.slim.python.slim import learning
|
||||
from tensorflow.contrib.slim.python.slim import model_analyzer
|
||||
from tensorflow.contrib.slim.python.slim import queues
|
||||
from tensorflow.contrib.slim.python.slim import summaries
|
||||
from tensorflow.contrib.slim.python.slim.data import data_decoder
|
||||
from tensorflow.contrib.slim.python.slim.data import data_provider
|
||||
from tensorflow.contrib.slim.python.slim.data import dataset
|
||||
|
|
|
|||
220
tensorflow/contrib/slim/python/slim/summaries.py
Normal file
220
tensorflow/contrib/slim/python/slim/summaries.py
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
# Copyright 2017 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.
|
||||
# ==============================================================================
|
||||
"""Contains helper functions for creating summaries.
|
||||
|
||||
This module contains various helper functions for quickly and easily adding
|
||||
tensorflow summaries. These allow users to print summary values
|
||||
automatically as they are computed and add prefixes to collections of summaries.
|
||||
|
||||
Example usage:
|
||||
|
||||
import tensorflow as tf
|
||||
slim = tf.contrib.slim
|
||||
|
||||
slim.summaries.add_histogram_summaries(slim.variables.get_model_variables())
|
||||
slim.summaries.add_scalar_summary(total_loss, 'Total Loss')
|
||||
slim.summaries.add_scalar_summary(learning_rate, 'Learning Rate')
|
||||
slim.summaries.add_histogram_summaries(my_tensors)
|
||||
slim.summaries.add_zero_fraction_summaries(my_tensors)
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from tensorflow.python.framework import ops
|
||||
from tensorflow.python.ops import logging_ops
|
||||
from tensorflow.python.ops import nn_impl as nn
|
||||
from tensorflow.python.summary import summary
|
||||
|
||||
|
||||
def _get_summary_name(tensor, name=None, prefix=None, postfix=None):
|
||||
"""Produces the summary name given.
|
||||
|
||||
Args:
|
||||
tensor: A variable or op `Tensor`.
|
||||
name: The optional name for the summary.
|
||||
prefix: An optional prefix for the summary name.
|
||||
postfix: An optional postfix for the summary name.
|
||||
|
||||
Returns:
|
||||
a summary name.
|
||||
"""
|
||||
if not name:
|
||||
name = tensor.op.name
|
||||
if prefix:
|
||||
name = prefix + '/' + name
|
||||
if postfix:
|
||||
name = name + '/' + postfix
|
||||
return name
|
||||
|
||||
|
||||
def add_histogram_summary(tensor, name=None, prefix=None):
|
||||
"""Adds a histogram summary for the given tensor.
|
||||
|
||||
Args:
|
||||
tensor: A variable or op tensor.
|
||||
name: The optional name for the summary.
|
||||
prefix: An optional prefix for the summary names.
|
||||
|
||||
Returns:
|
||||
A scalar `Tensor` of type `string` whose contents are the serialized
|
||||
`Summary` protocol buffer.
|
||||
"""
|
||||
return summary.histogram(
|
||||
_get_summary_name(tensor, name, prefix), tensor)
|
||||
|
||||
|
||||
def add_image_summary(tensor, name=None, prefix=None, print_summary=False):
|
||||
"""Adds an image summary for the given tensor.
|
||||
|
||||
Args:
|
||||
tensor: a variable or op tensor with shape [batch,height,width,channels]
|
||||
name: the optional name for the summary.
|
||||
prefix: An optional prefix for the summary names.
|
||||
print_summary: If `True`, the summary is printed to stdout when the summary
|
||||
is computed.
|
||||
|
||||
Returns:
|
||||
An image `Tensor` of type `string` whose contents are the serialized
|
||||
`Summary` protocol buffer.
|
||||
"""
|
||||
summary_name = _get_summary_name(tensor, name, prefix)
|
||||
# If print_summary, then we need to make sure that this call doesn't add the
|
||||
# non-printing op to the collection. We'll add it to the collection later.
|
||||
collections = [] if print_summary else None
|
||||
op = summary.image(
|
||||
name=summary_name, tensor=tensor, collections=collections)
|
||||
if print_summary:
|
||||
op = logging_ops.Print(op, [tensor], summary_name)
|
||||
ops.add_to_collection(ops.GraphKeys.SUMMARIES, op)
|
||||
return op
|
||||
|
||||
|
||||
def add_scalar_summary(tensor, name=None, prefix=None, print_summary=False):
|
||||
"""Adds a scalar summary for the given tensor.
|
||||
|
||||
Args:
|
||||
tensor: a variable or op tensor.
|
||||
name: the optional name for the summary.
|
||||
prefix: An optional prefix for the summary names.
|
||||
print_summary: If `True`, the summary is printed to stdout when the summary
|
||||
is computed.
|
||||
|
||||
Returns:
|
||||
A scalar `Tensor` of type `string` whose contents are the serialized
|
||||
`Summary` protocol buffer.
|
||||
"""
|
||||
collections = [] if print_summary else None
|
||||
summary_name = _get_summary_name(tensor, name, prefix)
|
||||
|
||||
# If print_summary, then we need to make sure that this call doesn't add the
|
||||
# non-printing op to the collection. We'll add it to the collection later.
|
||||
op = summary.scalar(
|
||||
name=summary_name, tensor=tensor, collections=collections)
|
||||
if print_summary:
|
||||
op = logging_ops.Print(op, [tensor], summary_name)
|
||||
ops.add_to_collection(ops.GraphKeys.SUMMARIES, op)
|
||||
return op
|
||||
|
||||
|
||||
def add_zero_fraction_summary(tensor, name=None, prefix=None,
|
||||
print_summary=False):
|
||||
"""Adds a summary for the percentage of zero values in the given tensor.
|
||||
|
||||
Args:
|
||||
tensor: a variable or op tensor.
|
||||
name: the optional name for the summary.
|
||||
prefix: An optional prefix for the summary names.
|
||||
print_summary: If `True`, the summary is printed to stdout when the summary
|
||||
is computed.
|
||||
|
||||
Returns:
|
||||
A scalar `Tensor` of type `string` whose contents are the serialized
|
||||
`Summary` protocol buffer.
|
||||
"""
|
||||
name = _get_summary_name(tensor, name, prefix, 'Fraction of Zero Values')
|
||||
tensor = nn.zero_fraction(tensor)
|
||||
return add_scalar_summary(tensor, name, print_summary=print_summary)
|
||||
|
||||
|
||||
def add_histogram_summaries(tensors, prefix=None):
|
||||
"""Adds a histogram summary for each of the given tensors.
|
||||
|
||||
Args:
|
||||
tensors: A list of variable or op tensors.
|
||||
prefix: An optional prefix for the summary names.
|
||||
|
||||
Returns:
|
||||
A list of scalar `Tensors` of type `string` whose contents are the
|
||||
serialized `Summary` protocol buffer.
|
||||
"""
|
||||
summary_ops = []
|
||||
for tensor in tensors:
|
||||
summary_ops.append(add_histogram_summary(tensor, prefix=prefix))
|
||||
return summary_ops
|
||||
|
||||
|
||||
def add_image_summaries(tensors, prefix=None):
|
||||
"""Adds an image summary for each of the given tensors.
|
||||
|
||||
Args:
|
||||
tensors: A list of variable or op tensors.
|
||||
prefix: An optional prefix for the summary names.
|
||||
|
||||
Returns:
|
||||
A list of scalar `Tensors` of type `string` whose contents are the
|
||||
serialized `Summary` protocol buffer.
|
||||
"""
|
||||
summary_ops = []
|
||||
for tensor in tensors:
|
||||
summary_ops.append(add_image_summary(tensor, prefix=prefix))
|
||||
return summary_ops
|
||||
|
||||
|
||||
def add_scalar_summaries(tensors, prefix=None, print_summary=False):
|
||||
"""Adds a scalar summary for each of the given tensors.
|
||||
|
||||
Args:
|
||||
tensors: a list of variable or op tensors.
|
||||
prefix: An optional prefix for the summary names.
|
||||
print_summary: If `True`, the summary is printed to stdout when the summary
|
||||
is computed.
|
||||
|
||||
Returns:
|
||||
A list of scalar `Tensors` of type `string` whose contents are the
|
||||
serialized `Summary` protocol buffer.
|
||||
"""
|
||||
summary_ops = []
|
||||
for tensor in tensors:
|
||||
summary_ops.append(add_scalar_summary(tensor, prefix=prefix,
|
||||
print_summary=print_summary))
|
||||
return summary_ops
|
||||
|
||||
|
||||
def add_zero_fraction_summaries(tensors, prefix=None):
|
||||
"""Adds a scalar zero-fraction summary for each of the given tensors.
|
||||
|
||||
Args:
|
||||
tensors: a list of variable or op tensors.
|
||||
prefix: An optional prefix for the summary names.
|
||||
|
||||
Returns:
|
||||
A list of scalar `Tensors` of type `string` whose contents are the
|
||||
serialized `Summary` protocol buffer.
|
||||
"""
|
||||
summary_ops = []
|
||||
for tensor in tensors:
|
||||
summary_ops.append(add_zero_fraction_summary(tensor, prefix=prefix))
|
||||
return summary_ops
|
||||
108
tensorflow/contrib/slim/python/slim/summaries_test.py
Normal file
108
tensorflow/contrib/slim/python/slim/summaries_test.py
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Copyright 2017 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.
|
||||
# ==============================================================================
|
||||
"""Tests for tensorflow.contrib.slim.summaries."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import glob
|
||||
import os
|
||||
|
||||
|
||||
from tensorflow.contrib.slim.python.slim import summaries
|
||||
from tensorflow.python.framework import ops
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.platform import gfile
|
||||
from tensorflow.python.platform import test
|
||||
from tensorflow.python.summary import summary
|
||||
from tensorflow.python.summary import summary_iterator
|
||||
|
||||
|
||||
class SummariesTest(test.TestCase):
|
||||
|
||||
def safe_create(self, output_dir):
|
||||
if gfile.Exists(output_dir):
|
||||
gfile.DeleteRecursively(output_dir)
|
||||
gfile.MakeDirs(output_dir)
|
||||
|
||||
def assert_scalar_summary(self, output_dir, names_to_values):
|
||||
"""Asserts that the given output directory contains written summaries.
|
||||
|
||||
Args:
|
||||
output_dir: The output directory in which to look for even tfiles.
|
||||
names_to_values: A dictionary of summary names to values.
|
||||
"""
|
||||
# The events file may have additional entries, e.g. the event version
|
||||
# stamp, so have to parse things a bit.
|
||||
output_filepath = glob.glob(os.path.join(output_dir, '*'))
|
||||
self.assertEqual(len(output_filepath), 1)
|
||||
|
||||
events = summary_iterator.summary_iterator(output_filepath[0])
|
||||
summaries_list = [e.summary for e in events if e.summary.value]
|
||||
values = []
|
||||
for item in summaries_list:
|
||||
for value in item.value:
|
||||
values.append(value)
|
||||
saved_results = {v.tag: v.simple_value for v in values}
|
||||
for name in names_to_values:
|
||||
self.assertAlmostEqual(names_to_values[name], saved_results[name])
|
||||
|
||||
def testScalarSummaryIsPartOfCollectionWithNoPrint(self):
|
||||
tensor = array_ops.ones([]) * 3
|
||||
name = 'my_score'
|
||||
prefix = 'eval'
|
||||
op = summaries.add_scalar_summary(tensor, name, prefix, print_summary=False)
|
||||
self.assertTrue(op in ops.get_collection(ops.GraphKeys.SUMMARIES))
|
||||
|
||||
def testScalarSummaryIsPartOfCollectionWithPrint(self):
|
||||
tensor = array_ops.ones([]) * 3
|
||||
name = 'my_score'
|
||||
prefix = 'eval'
|
||||
op = summaries.add_scalar_summary(tensor, name, prefix, print_summary=True)
|
||||
self.assertTrue(op in ops.get_collection(ops.GraphKeys.SUMMARIES))
|
||||
|
||||
def verify_scalar_summary_is_written(self, print_summary):
|
||||
value = 3
|
||||
tensor = array_ops.ones([]) * value
|
||||
name = 'my_score'
|
||||
prefix = 'eval'
|
||||
summaries.add_scalar_summary(tensor, name, prefix, print_summary)
|
||||
|
||||
output_dir = os.path.join(self.get_temp_dir(),
|
||||
'scalar_summary_no_print_test')
|
||||
self.safe_create(output_dir)
|
||||
|
||||
summary_op = summary.merge_all()
|
||||
|
||||
summary_writer = summary.FileWriter(output_dir)
|
||||
with self.test_session() as sess:
|
||||
new_summary = sess.run(summary_op)
|
||||
summary_writer.add_summary(new_summary, 1)
|
||||
summary_writer.flush()
|
||||
|
||||
self.assert_scalar_summary(output_dir, {
|
||||
'%s/%s' % (prefix, name): value
|
||||
})
|
||||
|
||||
def testScalarSummaryIsWrittenWithNoPrint(self):
|
||||
self.verify_scalar_summary_is_written(print_summary=False)
|
||||
|
||||
def testScalarSummaryIsWrittenWithPrint(self):
|
||||
self.verify_scalar_summary_is_written(print_summary=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test.main()
|
||||
Loading…
Reference in New Issue
Block a user