A context manager that lifts ops out of control-flow scopes and function-building graphs. There is often a need to lift variable initialization ops out of control-flow scopes, function-building graphs, and gradient tapes. Entering an `init_scope` is a mechanism for satisfying these desiderata
()
| 5611 | @tf_export("init_scope") |
| 5612 | @tf_contextlib.contextmanager |
| 5613 | def init_scope(): |
| 5614 | """A context manager that lifts ops out of control-flow scopes and function-building graphs. |
| 5615 | |
| 5616 | There is often a need to lift variable initialization ops out of control-flow |
| 5617 | scopes, function-building graphs, and gradient tapes. Entering an |
| 5618 | `init_scope` is a mechanism for satisfying these desiderata. In particular, |
| 5619 | entering an `init_scope` has three effects: |
| 5620 | |
| 5621 | (1) All control dependencies are cleared the moment the scope is entered; |
| 5622 | this is equivalent to entering the context manager returned from |
| 5623 | `control_dependencies(None)`, which has the side-effect of exiting |
| 5624 | control-flow scopes like `tf.cond` and `tf.while_loop`. |
| 5625 | |
| 5626 | (2) All operations that are created while the scope is active are lifted |
| 5627 | into the lowest context on the `context_stack` that is not building a |
| 5628 | graph function. Here, a context is defined as either a graph or an eager |
| 5629 | context. Every context switch, i.e., every installation of a graph as |
| 5630 | the default graph and every switch into eager mode, is logged in a |
| 5631 | thread-local stack called `context_switches`; the log entry for a |
| 5632 | context switch is popped from the stack when the context is exited. |
| 5633 | Entering an `init_scope` is equivalent to crawling up |
| 5634 | `context_switches`, finding the first context that is not building a |
| 5635 | graph function, and entering it. A caveat is that if graph mode is |
| 5636 | enabled but the default graph stack is empty, then entering an |
| 5637 | `init_scope` will simply install a fresh graph as the default one. |
| 5638 | |
| 5639 | (3) The gradient tape is paused while the scope is active. |
| 5640 | |
| 5641 | When eager execution is enabled, code inside an init_scope block runs with |
| 5642 | eager execution enabled even when defining graph functions via |
| 5643 | tf.contrib.eager.defun. For example: |
| 5644 | |
| 5645 | ```python |
| 5646 | tf.compat.v1.enable_eager_execution() |
| 5647 | |
| 5648 | @tf.contrib.eager.defun |
| 5649 | def func(): |
| 5650 | # A defun-decorated function constructs TensorFlow graphs, |
| 5651 | # it does not execute eagerly. |
| 5652 | assert not tf.executing_eagerly() |
| 5653 | with tf.init_scope(): |
| 5654 | # Initialization runs with eager execution enabled |
| 5655 | assert tf.executing_eagerly() |
| 5656 | ``` |
| 5657 | |
| 5658 | Raises: |
| 5659 | RuntimeError: if graph state is incompatible with this initialization. |
| 5660 | """ |
| 5661 | # pylint: enable=g-doc-return-or-yield,line-too-long |
| 5662 | |
| 5663 | if context.executing_eagerly(): |
| 5664 | # Fastpath. |
| 5665 | with tape.stop_recording(): |
| 5666 | yield |
| 5667 | else: |
| 5668 | # Retrieve the active name scope: entering an `init_scope` preserves |
| 5669 | # the name scope of the current context. |
| 5670 | scope = get_default_graph().get_name_scope() |
nothing calls this directly
no test coverage detected