aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Alexandre Passos <apassos@google.com>2018-07-24 09:35:59 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-07-24 09:43:15 -0700
commit00f9eb9c589ad3c5ce5b4dde84763553c56ad0ee (patch)
tree46009790820710b927ebd9d6828263078712a1ab
parent1b33df1814e35015953c7cba392ba2a7387ce875 (diff)
Improvement resource variable documentation.
Removes stale mentions of how to construct them from docstrings and adds a new section to the programmer's guide explaining resource handles and resource variable semantics. PiperOrigin-RevId: 205842012
-rw-r--r--tensorflow/contrib/eager/python/saver.py4
-rw-r--r--tensorflow/core/api_def/base_api/api_def_ResourceScatterNdAdd.pbtxt2
-rw-r--r--tensorflow/python/eager/backprop.py8
-rw-r--r--tensorflow/python/eager/function.py27
-rw-r--r--tensorflow/python/ops/resource_variable_ops.py17
-rw-r--r--tensorflow/python/ops/variables.py41
6 files changed, 45 insertions, 54 deletions
diff --git a/tensorflow/contrib/eager/python/saver.py b/tensorflow/contrib/eager/python/saver.py
index fdaca90fd1..d709308647 100644
--- a/tensorflow/contrib/eager/python/saver.py
+++ b/tensorflow/contrib/eager/python/saver.py
@@ -125,8 +125,8 @@ class Saver(object):
Args:
var_list: The list of variables that will be saved and restored. Either a
- list of `tfe.Variable` objects, or a dictionary mapping names to
- `tfe.Variable` objects.
+ list of `tf.Variable` objects, or a dictionary mapping names to
+ `tf.Variable` objects.
Raises:
RuntimeError: if invoked when eager execution has not been enabled.
diff --git a/tensorflow/core/api_def/base_api/api_def_ResourceScatterNdAdd.pbtxt b/tensorflow/core/api_def/base_api/api_def_ResourceScatterNdAdd.pbtxt
index 3b3a274df5..2b58969da2 100644
--- a/tensorflow/core/api_def/base_api/api_def_ResourceScatterNdAdd.pbtxt
+++ b/tensorflow/core/api_def/base_api/api_def_ResourceScatterNdAdd.pbtxt
@@ -51,7 +51,7 @@ For example, say we want to update 4 scattered elements to a rank-1 tensor to
8 elements. In Python, that update would look like this:
```python
- ref = tfe.Variable([1, 2, 3, 4, 5, 6, 7, 8])
+ ref = tf.Variable([1, 2, 3, 4, 5, 6, 7, 8], use_resource=True)
indices = tf.constant([[4], [3], [1] ,[7]])
updates = tf.constant([9, 10, 11, 12])
update = tf.scatter_nd_add(ref, indices, updates)
diff --git a/tensorflow/python/eager/backprop.py b/tensorflow/python/eager/backprop.py
index 9e0bbce4a1..da8b93dba8 100644
--- a/tensorflow/python/eager/backprop.py
+++ b/tensorflow/python/eager/backprop.py
@@ -643,10 +643,10 @@ class GradientTape(object):
Operations are recorded if they are executed within this context manager and
at least one of their inputs is being "watched".
- Trainable variables (created by `tf.contrib.eager.Variable` or
- @{tf.get_variable}, trainable=True is default in both cases) are automatically
- watched. Tensors can be manually watched by invoking the `watch` method on
- this context manager.
+ Trainable variables (created by `tf.Variable` or @{tf.get_variable},
+ trainable=True is default in both cases) are automatically watched. Tensors
+ can be manually watched by invoking the `watch` method on this context
+ manager.
For example, consider the function `y = x * x`. The gradient at `x = 3.0` can
be computed as:
diff --git a/tensorflow/python/eager/function.py b/tensorflow/python/eager/function.py
index a6906f9efd..d283a85532 100644
--- a/tensorflow/python/eager/function.py
+++ b/tensorflow/python/eager/function.py
@@ -1077,7 +1077,7 @@ def defun(func=None, compiled=False):
tf.enable_eager_execution()
def fn():
- x = tf.contrib.eager.Variable(0.0)
+ x = tf.Variable(0.0)
x.assign_add(1.0)
return x.read_value()
@@ -1094,19 +1094,18 @@ def defun(func=None, compiled=False):
```
Finally, because each input signature is bound to a unique graph, if your
- Python function constructs `tf.contrib.eager.Variable` objects, then each
- graph constructed for that Python function will reference a unique set of
- variables. To circumvent this problem, we recommend against compiling Python
- functions that create `tf.contrib.eager.Variable` objects. Instead, Python
- functions should either lexically close over `tf.contrib.eager.Variable`
- objects or accept them as arguments, preferably encapsulated in an
- object-oriented container. If you must create variables inside your Python
- function and you want each graph generated for it to reference the same set of
- variables, add logic to your Python function that ensures that variables are
- only created the first time it is called and are reused for every subsequent
- invocation; note that this is precisely what @{tf.keras.layers.Layer} objects
- do, so we recommend using them to represent variable-bearing computations
- whenever possible.
+ Python function constructs `tf.Variable` objects, then each graph constructed
+ for that Python function will reference a unique set of variables. To
+ circumvent this problem, we recommend against compiling Python functions that
+ create `tf.Variable` objects. Instead, Python functions should either
+ lexically close over `tf.Variable` objects or accept them as arguments,
+ preferably encapsulated in an object-oriented container. If you must create
+ variables inside your Python function and you want each graph generated for it
+ to reference the same set of variables, add logic to your Python function that
+ ensures that variables are only created the first time it is called and are
+ reused for every subsequent invocation; note that this is precisely what
+ @{tf.keras.layers.Layer} objects do, so we recommend using them to represent
+ variable-bearing computations whenever possible.
Args:
func: function to be compiled. If `func` is None, returns a
diff --git a/tensorflow/python/ops/resource_variable_ops.py b/tensorflow/python/ops/resource_variable_ops.py
index db071e3974..8b259b6b6b 100644
--- a/tensorflow/python/ops/resource_variable_ops.py
+++ b/tensorflow/python/ops/resource_variable_ops.py
@@ -196,15 +196,16 @@ class ResourceVariable(variables.RefVariable):
the variable are fixed. The value can be changed using one of the assign
methods.
- Just like any `Tensor`, variables created with `ResourceVariable()` can be
- used as inputs for other Ops in the graph. Additionally, all the operators
- overloaded for the `Tensor` class are carried over to variables, so you can
- also add nodes to the graph by just doing arithmetic on variables.
+ Just like any `Tensor`, variables created with
+ `tf.Variable(use_resource=True)` can be used as inputs for other Ops in the
+ graph. Additionally, all the operators overloaded for the `Tensor` class are
+ carried over to variables, so you can also add nodes to the graph by just
+ doing arithmetic on variables.
- Unlike tf.Variable, a tf.ResourceVariable has well-defined semantics. Each
+ Unlike ref-based variable, a ResourceVariable has well-defined semantics. Each
usage of a ResourceVariable in a TensorFlow graph adds a read_value operation
- to the graph. The Tensors returned by a read_value operation are guaranteed
- to see all modifications to the value of the variable which happen in any
+ to the graph. The Tensors returned by a read_value operation are guaranteed to
+ see all modifications to the value of the variable which happen in any
operation on which the read_value depends on (either directly, indirectly, or
via a control dependency) and guaranteed to not see any modification to the
value of the variable from operations that depend on the read_value operation.
@@ -218,7 +219,7 @@ class ResourceVariable(variables.RefVariable):
can cause tf.Variable and tf.ResourceVariable to behave differently:
```python
- a = tf.ResourceVariable(1.0)
+ a = tf.Variable(1.0, use_resource=True)
a.initializer.run()
assign = a.assign(2.0)
diff --git a/tensorflow/python/ops/variables.py b/tensorflow/python/ops/variables.py
index d03d93beeb..fc00ce68ae 100644
--- a/tensorflow/python/ops/variables.py
+++ b/tensorflow/python/ops/variables.py
@@ -220,27 +220,31 @@ class Variable(six.with_metaclass(VariableMetaclass,
various `Optimizer` classes use this collection as the default list of
variables to optimize.
- WARNING: tf.Variable objects have a non-intuitive memory model. A Variable is
- represented internally as a mutable Tensor which can non-deterministically
- alias other Tensors in a graph. The set of operations which consume a Variable
- and can lead to aliasing is undetermined and can change across TensorFlow
- versions. Avoid writing code which relies on the value of a Variable either
- changing or not changing as other operations happen. For example, using
- Variable objects or simple functions thereof as predicates in a `tf.cond` is
- dangerous and error-prone:
+ WARNING: tf.Variable objects by default have a non-intuitive memory model. A
+ Variable is represented internally as a mutable Tensor which can
+ non-deterministically alias other Tensors in a graph. The set of operations
+ which consume a Variable and can lead to aliasing is undetermined and can
+ change across TensorFlow versions. Avoid writing code which relies on the
+ value of a Variable either changing or not changing as other operations
+ happen. For example, using Variable objects or simple functions thereof as
+ predicates in a `tf.cond` is dangerous and error-prone:
```
v = tf.Variable(True)
tf.cond(v, lambda: v.assign(False), my_false_fn) # Note: this is broken.
```
- Here replacing tf.Variable with tf.contrib.eager.Variable will fix any
- nondeterminism issues.
+ Here replacing adding `use_resource=True` when constructing the variable will
+ fix any nondeterminism issues:
+ ```
+ v = tf.Variable(True, use_resource=True)
+ tf.cond(v, lambda: v.assign(False), my_false_fn)
+ ```
To use the replacement for variables which does
not have these issues:
- * Replace `tf.Variable` with `tf.contrib.eager.Variable`;
+ * Add `use_resource=True` when constructing `tf.Variable`;
* Call `tf.get_variable_scope().set_use_resource(True)` inside a
`tf.variable_scope` before the `tf.get_variable()` call.
"""
@@ -869,19 +873,7 @@ class RefVariable(Variable):
ValueError: If the initial value is not specified, or does not have a
shape and `validate_shape` is `True`.
RuntimeError: If eager execution is enabled.
-
- @compatibility(eager)
- `tf.Variable` is not compatible with eager execution. Use
- `tfe.Variable` instead which is compatible with both eager execution
- and graph construction. See [the TensorFlow Eager Execution
- guide](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/g3doc/guide.md#variables-and-optimizers)
- for details on how variables work in eager execution.
- @end_compatibility
"""
- if context.executing_eagerly():
- raise RuntimeError(
- "tf.Variable not supported when eager execution is enabled. "
- "Please use tf.contrib.eager.Variable instead")
self._in_graph_mode = True
if variable_def:
# If variable_def is provided, recreates the variable from its fields.
@@ -992,8 +984,7 @@ class RefVariable(Variable):
# Ensure that we weren't lifted into the eager context.
if context.executing_eagerly():
raise RuntimeError(
- "tf.Variable not supported when eager execution is enabled. "
- "Please use tf.contrib.eager.Variable instead")
+ "RefVariable not supported when eager execution is enabled. ")
with ops.name_scope(name, "Variable", [] if init_from_fn else
[initial_value]) as name: