def testGetSetStep(self): try: self.assertIsNone(summary_ops.get_step()) summary_ops.set_step(1) # Use assertAllEqual instead of assertEqual since it works in a defun. self.assertAllEqual(1, summary_ops.get_step()) summary_ops.set_step(constant_op.constant(2)) self.assertAllEqual(2, summary_ops.get_step()) finally: # Reset to default state for other tests. summary_ops.set_step(None)
def testGetSetStep_variable_fromFunction(self): with context.eager_mode(): try: @def_function.function def set_step(step): summary_ops.set_step(step) return summary_ops.get_step() @def_function.function def get_and_increment(): summary_ops.get_step().assign_add(1) return summary_ops.get_step() mystep = variables.Variable(0) self.assertAllEqual(0, set_step(mystep)) self.assertAllEqual(0, summary_ops.get_step().read_value()) self.assertAllEqual(1, get_and_increment()) self.assertAllEqual(2, get_and_increment()) # Check that set_step() properly maintains reference to variable. del mystep self.assertAllEqual(3, get_and_increment()) finally: # Reset to default state for other tests. summary_ops.set_step(None)
def _get_step_for_v2(): """Get step for v2 summary invocation in v1. In order to invoke v2 op in `tf.compat.v1.summary`, global step needs to be set for the v2 summary writer. Returns: The step set by `tf.summary.experimental.set_step` or `tf.compat.v1.train.create_global_step`, or None is no step has been set. """ step = _summary_ops_v2.get_step() if step is not None: return step return _training_util.get_global_step()
def testGetSetStep_variable(self): with context.eager_mode(): try: mystep = variables.Variable(0) summary_ops.set_step(mystep) self.assertAllEqual(0, summary_ops.get_step().read_value()) mystep.assign_add(1) self.assertAllEqual(1, summary_ops.get_step().read_value()) # Check that set_step() properly maintains reference to variable. del mystep self.assertAllEqual(1, summary_ops.get_step().read_value()) summary_ops.get_step().assign_add(1) self.assertAllEqual(2, summary_ops.get_step().read_value()) finally: # Reset to default state for other tests. summary_ops.set_step(None)
def get_and_increment(): summary_ops.get_step().assign_add(1) return summary_ops.get_step()
def set_step(step): summary_ops.set_step(step) return summary_ops.get_step()
def scalar(name, tensor, collections=None, family=None): """Outputs a `Summary` protocol buffer containing a single scalar value. The generated Summary has a Tensor.proto containing the input Tensor. Args: name: A name for the generated node. Will also serve as the series name in TensorBoard. tensor: A real numeric Tensor containing a single value. collections: Optional list of graph collections keys. The new summary op is added to these collections. Defaults to `[GraphKeys.SUMMARIES]`. family: Optional; if provided, used as the prefix of the summary tag name, which controls the tab name used for display on Tensorboard. Returns: A scalar `Tensor` of type `string`. Which contains a `Summary` protobuf. Raises: ValueError: If tensor has the wrong shape or type. @compatibility(TF2) For compatibility purposes, when invoked in TF2 where the outermost context is eager mode, this API will check if there is a suitable TF2 summary writer context available, and if so will forward this call to that writer instead. A "suitable" writer context means that the writer is set as the default writer, and there is an associated non-empty value for `step` (see `tf.summary.SummaryWriter.as_default`, or alternatively `tf.summary.experimental.set_step`). For the forwarded call, the arguments here will be passed to the TF2 implementation of `tf.summary.scalar`, and the return value will be an empty bytestring tensor, to avoid duplicate summary writing. This forwarding is best-effort and not all arguments will be preserved. To migrate to TF2, please use `tf.summary.scalar` instead. Please check [Migrating tf.summary usage to TF 2.0](https://www.tensorflow.org/tensorboard/migrate#in_tf_1x) for concrete steps for migration. `tf.summary.scalar` can also log training metrics in Keras, you can check [Logging training metrics in Keras](https://www.tensorflow.org/tensorboard/scalars_and_keras) for detials. #### How to Map Arguments | TF1 Arg Name | TF2 Arg Name | Note | | :------------ | :-------------- | :------------------------------------- | | `name` | `name` | - | | `tensor` | `data` | - | | - | `step` | Explicit int64-castable monotonic step | : : : value. If omitted, this defaults to : : : : `tf.summary.experimental.get_step()`. : | `collections` | Not Supported | - | | `family` | Removed | Please use `tf.name_scope` instead to | : : : manage summary name prefix. : | - | `description` | Optional long-form `str` description | : : : for the summary. Markdown is supported.: : : : Defaults to empty. : @end_compatibility """ # Special case: invoke v2 op for TF2 users who have a v2 writer. if _ops.executing_eagerly_outside_functions(): # Apart from an existing writer, users need to call # `tf.summary.experimental.set_step` in order to invoke v2 API here. if _summary_ops_v2.get_step( ) is not None and _summary_ops_v2.has_default_writer(): # Defer the import to happen inside the symbol to prevent breakage due to # missing dependency. # pylint: disable=g-import-not-at-top from tensorboard.summary.v2 import scalar as scalar_v2 # TODO(b/210992280): Handle the family argument. scalar_v2(name, data=tensor) # Return an empty Tensor, which will be acceptable as an input to the # `tf.compat.v1.summary.merge()` API. return _constant_op.constant(b'') # Fall back to legacy v1 scalar implementation. if _distribute_summary_op_util.skip_summary(): return _constant_op.constant('') with _summary_op_util.summary_scope(name, family, values=[tensor]) as (tag, scope): val = _gen_logging_ops.scalar_summary(tags=tag, values=tensor, name=scope) _summary_op_util.collect(val, collections, [_ops.GraphKeys.SUMMARIES]) return val