• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15
16"""Tensor summaries for exporting information about a model.
17
18See the @{$python/summary} guide.
19
20@@FileWriter
21@@FileWriterCache
22@@tensor_summary
23@@scalar
24@@histogram
25@@audio
26@@image
27@@text
28@@merge
29@@merge_all
30@@get_summary_description
31@@PluginAsset
32@@get_plugin_asset
33@@get_all_plugin_assets
34"""
35
36from __future__ import absolute_import
37from __future__ import division
38from __future__ import print_function
39
40from google.protobuf import json_format as _json_format
41
42# exports Summary, SummaryDescription, Event, TaggedRunMetadata, SessionLog
43# pylint: disable=unused-import
44from tensorflow.core.framework.summary_pb2 import Summary
45from tensorflow.core.framework.summary_pb2 import SummaryDescription
46from tensorflow.core.util.event_pb2 import Event
47from tensorflow.core.util.event_pb2 import SessionLog
48from tensorflow.core.util.event_pb2 import TaggedRunMetadata
49# pylint: enable=unused-import
50
51from tensorflow.python.eager import context as _context
52from tensorflow.python.framework import dtypes as _dtypes
53from tensorflow.python.framework import ops as _ops
54from tensorflow.python.ops import gen_logging_ops as _gen_logging_ops
55from tensorflow.python.ops import summary_op_util as _summary_op_util
56
57# exports tensor-related summaries
58# pylint: disable=unused-import
59from tensorflow.python.ops.summary_ops import tensor_summary
60# pylint: enable=unused-import
61
62# exports text
63# pylint: disable=unused-import
64from tensorflow.python.summary.text_summary import text_summary as text
65# pylint: enable=unused-import
66
67# exports FileWriter, FileWriterCache
68# pylint: disable=unused-import
69from tensorflow.python.summary.writer.writer import FileWriter
70from tensorflow.python.summary.writer.writer_cache import FileWriterCache
71# pylint: enable=unused-import
72
73from tensorflow.python.util import compat as _compat
74from tensorflow.python.util.all_util import remove_undocumented
75from tensorflow.python.util.tf_export import tf_export
76
77
78@tf_export('summary.scalar')
79def scalar(name, tensor, collections=None, family=None):
80  """Outputs a `Summary` protocol buffer containing a single scalar value.
81
82  The generated Summary has a Tensor.proto containing the input Tensor.
83
84  Args:
85    name: A name for the generated node. Will also serve as the series name in
86      TensorBoard.
87    tensor: A real numeric Tensor containing a single value.
88    collections: Optional list of graph collections keys. The new summary op is
89      added to these collections. Defaults to `[GraphKeys.SUMMARIES]`.
90    family: Optional; if provided, used as the prefix of the summary tag name,
91      which controls the tab name used for display on Tensorboard.
92
93  Returns:
94    A scalar `Tensor` of type `string`. Which contains a `Summary` protobuf.
95
96  Raises:
97    ValueError: If tensor has the wrong shape or type.
98  """
99  with _summary_op_util.summary_scope(
100      name, family, values=[tensor]) as (tag, scope):
101    # pylint: disable=protected-access
102    val = _gen_logging_ops._scalar_summary(tags=tag, values=tensor, name=scope)
103    _summary_op_util.collect(val, collections, [_ops.GraphKeys.SUMMARIES])
104  return val
105
106
107@tf_export('summary.image')
108def image(name, tensor, max_outputs=3, collections=None, family=None):
109  """Outputs a `Summary` protocol buffer with images.
110
111  The summary has up to `max_outputs` summary values containing images. The
112  images are built from `tensor` which must be 4-D with shape `[batch_size,
113  height, width, channels]` and where `channels` can be:
114
115  *  1: `tensor` is interpreted as Grayscale.
116  *  3: `tensor` is interpreted as RGB.
117  *  4: `tensor` is interpreted as RGBA.
118
119  The images have the same number of channels as the input tensor. For float
120  input, the values are normalized one image at a time to fit in the range
121  `[0, 255]`.  `uint8` values are unchanged.  The op uses two different
122  normalization algorithms:
123
124  *  If the input values are all positive, they are rescaled so the largest one
125     is 255.
126
127  *  If any input value is negative, the values are shifted so input value 0.0
128     is at 127.  They are then rescaled so that either the smallest value is 0,
129     or the largest one is 255.
130
131  The `tag` in the outputted Summary.Value protobufs is generated based on the
132  name, with a suffix depending on the max_outputs setting:
133
134  *  If `max_outputs` is 1, the summary value tag is '*name*/image'.
135  *  If `max_outputs` is greater than 1, the summary value tags are
136     generated sequentially as '*name*/image/0', '*name*/image/1', etc.
137
138  Args:
139    name: A name for the generated node. Will also serve as a series name in
140      TensorBoard.
141    tensor: A 4-D `uint8` or `float32` `Tensor` of shape `[batch_size, height,
142      width, channels]` where `channels` is 1, 3, or 4.
143    max_outputs: Max number of batch elements to generate images for.
144    collections: Optional list of ops.GraphKeys.  The collections to add the
145      summary to.  Defaults to [_ops.GraphKeys.SUMMARIES]
146    family: Optional; if provided, used as the prefix of the summary tag name,
147      which controls the tab name used for display on Tensorboard.
148
149  Returns:
150    A scalar `Tensor` of type `string`. The serialized `Summary` protocol
151    buffer.
152  """
153  with _summary_op_util.summary_scope(
154      name, family, values=[tensor]) as (tag, scope):
155    # pylint: disable=protected-access
156    val = _gen_logging_ops._image_summary(
157        tag=tag, tensor=tensor, max_images=max_outputs, name=scope)
158    _summary_op_util.collect(val, collections, [_ops.GraphKeys.SUMMARIES])
159  return val
160
161
162@tf_export('summary.histogram')
163def histogram(name, values, collections=None, family=None):
164  # pylint: disable=line-too-long
165  """Outputs a `Summary` protocol buffer with a histogram.
166
167  Adding a histogram summary makes it possible to visualize your data's
168  distribution in TensorBoard. You can see a detailed explanation of the
169  TensorBoard histogram dashboard
170  [here](https://www.tensorflow.org/get_started/tensorboard_histograms).
171
172  The generated
173  [`Summary`](https://www.tensorflow.org/code/tensorflow/core/framework/summary.proto)
174  has one summary value containing a histogram for `values`.
175
176  This op reports an `InvalidArgument` error if any value is not finite.
177
178  Args:
179    name: A name for the generated node. Will also serve as a series name in
180      TensorBoard.
181    values: A real numeric `Tensor`. Any shape. Values to use to
182      build the histogram.
183    collections: Optional list of graph collections keys. The new summary op is
184      added to these collections. Defaults to `[GraphKeys.SUMMARIES]`.
185    family: Optional; if provided, used as the prefix of the summary tag name,
186      which controls the tab name used for display on Tensorboard.
187
188  Returns:
189    A scalar `Tensor` of type `string`. The serialized `Summary` protocol
190    buffer.
191  """
192  with _summary_op_util.summary_scope(
193      name, family, values=[values],
194      default_name='HistogramSummary') as (tag, scope):
195    # pylint: disable=protected-access
196    val = _gen_logging_ops._histogram_summary(
197        tag=tag, values=values, name=scope)
198    _summary_op_util.collect(val, collections, [_ops.GraphKeys.SUMMARIES])
199  return val
200
201
202@tf_export('summary.audio')
203def audio(name, tensor, sample_rate, max_outputs=3, collections=None,
204          family=None):
205  # pylint: disable=line-too-long
206  """Outputs a `Summary` protocol buffer with audio.
207
208  The summary has up to `max_outputs` summary values containing audio. The
209  audio is built from `tensor` which must be 3-D with shape `[batch_size,
210  frames, channels]` or 2-D with shape `[batch_size, frames]`. The values are
211  assumed to be in the range of `[-1.0, 1.0]` with a sample rate of
212  `sample_rate`.
213
214  The `tag` in the outputted Summary.Value protobufs is generated based on the
215  name, with a suffix depending on the max_outputs setting:
216
217  *  If `max_outputs` is 1, the summary value tag is '*name*/audio'.
218  *  If `max_outputs` is greater than 1, the summary value tags are
219     generated sequentially as '*name*/audio/0', '*name*/audio/1', etc
220
221  Args:
222    name: A name for the generated node. Will also serve as a series name in
223      TensorBoard.
224    tensor: A 3-D `float32` `Tensor` of shape `[batch_size, frames, channels]`
225      or a 2-D `float32` `Tensor` of shape `[batch_size, frames]`.
226    sample_rate: A Scalar `float32` `Tensor` indicating the sample rate of the
227      signal in hertz.
228    max_outputs: Max number of batch elements to generate audio for.
229    collections: Optional list of ops.GraphKeys.  The collections to add the
230      summary to.  Defaults to [_ops.GraphKeys.SUMMARIES]
231    family: Optional; if provided, used as the prefix of the summary tag name,
232      which controls the tab name used for display on Tensorboard.
233
234  Returns:
235    A scalar `Tensor` of type `string`. The serialized `Summary` protocol
236    buffer.
237  """
238  with _summary_op_util.summary_scope(
239      name, family=family, values=[tensor]) as (tag, scope):
240    # pylint: disable=protected-access
241    sample_rate = _ops.convert_to_tensor(
242        sample_rate, dtype=_dtypes.float32, name='sample_rate')
243    val = _gen_logging_ops._audio_summary_v2(
244        tag=tag, tensor=tensor, max_outputs=max_outputs,
245        sample_rate=sample_rate, name=scope)
246    _summary_op_util.collect(val, collections, [_ops.GraphKeys.SUMMARIES])
247  return val
248
249
250@tf_export('summary.merge')
251def merge(inputs, collections=None, name=None):
252  # pylint: disable=line-too-long
253  """Merges summaries.
254
255  This op creates a
256  [`Summary`](https://www.tensorflow.org/code/tensorflow/core/framework/summary.proto)
257  protocol buffer that contains the union of all the values in the input
258  summaries.
259
260  When the Op is run, it reports an `InvalidArgument` error if multiple values
261  in the summaries to merge use the same tag.
262
263  Args:
264    inputs: A list of `string` `Tensor` objects containing serialized `Summary`
265      protocol buffers.
266    collections: Optional list of graph collections keys. The new summary op is
267      added to these collections. Defaults to `[]`.
268    name: A name for the operation (optional).
269
270  Returns:
271    A scalar `Tensor` of type `string`. The serialized `Summary` protocol
272    buffer resulting from the merging.
273
274  Raises:
275    RuntimeError: If called with eager mode enabled.
276
277  @compatibility(eager)
278  Not compatible with eager execution. To write TensorBoard
279  summaries under eager execution, use `tf.contrib.summary` instead.
280  @end_compatbility
281  """
282  # pylint: enable=line-too-long
283  if _context.in_eager_mode():
284    raise RuntimeError(
285        'Merging tf.summary.* ops is not compatible with eager execution. '
286        'Use tf.contrib.summary instead.')
287  name = _summary_op_util.clean_tag(name)
288  with _ops.name_scope(name, 'Merge', inputs):
289    # pylint: disable=protected-access
290    val = _gen_logging_ops._merge_summary(inputs=inputs, name=name)
291    _summary_op_util.collect(val, collections, [])
292  return val
293
294
295@tf_export('summary.merge_all')
296def merge_all(key=_ops.GraphKeys.SUMMARIES, scope=None):
297  """Merges all summaries collected in the default graph.
298
299  Args:
300    key: `GraphKey` used to collect the summaries.  Defaults to
301      `GraphKeys.SUMMARIES`.
302    scope: Optional scope used to filter the summary ops, using `re.match`
303
304  Returns:
305    If no summaries were collected, returns None.  Otherwise returns a scalar
306    `Tensor` of type `string` containing the serialized `Summary` protocol
307    buffer resulting from the merging.
308
309  Raises:
310    RuntimeError: If called with eager execution enabled.
311
312  @compatibility(eager)
313  Not compatible with eager execution. To write TensorBoard
314  summaries under eager execution, use `tf.contrib.summary` instead.
315  @end_compatbility
316  """
317  if _context.in_eager_mode():
318    raise RuntimeError(
319        'Merging tf.summary.* ops is not compatible with eager execution. '
320        'Use tf.contrib.summary instead.')
321  summary_ops = _ops.get_collection(key, scope=scope)
322  if not summary_ops:
323    return None
324  else:
325    return merge(summary_ops)
326
327
328@tf_export('summary.get_summary_description')
329def get_summary_description(node_def):
330  """Given a TensorSummary node_def, retrieve its SummaryDescription.
331
332  When a Summary op is instantiated, a SummaryDescription of associated
333  metadata is stored in its NodeDef. This method retrieves the description.
334
335  Args:
336    node_def: the node_def_pb2.NodeDef of a TensorSummary op
337
338  Returns:
339    a summary_pb2.SummaryDescription
340
341  Raises:
342    ValueError: if the node is not a summary op.
343
344  @compatibility(eager)
345  Not compatible with eager execution. To write TensorBoard
346  summaries under eager execution, use `tf.contrib.summary` instead.
347  @end_compatbility
348  """
349
350  if node_def.op != 'TensorSummary':
351    raise ValueError("Can't get_summary_description on %s" % node_def.op)
352  description_str = _compat.as_str_any(node_def.attr['description'].s)
353  summary_description = SummaryDescription()
354  _json_format.Parse(description_str, summary_description)
355  return summary_description
356
357
358_allowed_symbols = [
359    'Summary', 'SummaryDescription', 'Event', 'TaggedRunMetadata', 'SessionLog',
360]
361
362remove_undocumented(__name__, _allowed_symbols)
363