tf.Variable

TensorFlow 1 version View source on GitHub

See the variable guide.

Used in the notebooks

Used in the guide Used in the tutorials

A variable maintains shared, persistent state manipulated by a program.

The Variable() constructor requires an initial value for the variable, which can be a Tensor of any type and shape. This initial value defines the type and shape of the variable. After construction, the type and shape of the variable are fixed. The value can be changed using one of the assign methods.

v = tf.Variable(1.)
v.assign(2.)
<tf.Variable ... shape=() dtype=float32, numpy=2.0>
v.assign_add(0.5)
<tf.Variable ... shape=() dtype=float32, numpy=2.5>

The shape argument to Variable's constructor allows you to construct a variable with a less defined shape than its initial_value:

v = tf.Variable(1., shape=tf.TensorShape(None))
v.assign([[1.]])
<tf.Variable ... shape=<unknown> dtype=float32, numpy=array([[1.]], ...)>

Just like any Tensor, variables created with Variable() can be used as inputs to operations. Additionally, all the operators overloaded for the Tensor class are carried over to variables.

w = tf.Variable([[1.], [2.]])
x = tf.constant([[3., 4.]])
tf.matmul(w, x)
<tf.Tensor:... shape=(2, 2), ... numpy=
  array([[3., 4.],
         [6., 8.]], dtype=float32)>
tf.sigmoid(w + x)
<tf.Tensor:... shape=(2, 2), ...>

When building a machine learning model it is often convenient to distinguish between variables holding trainable model parameters and other variables such as a step variable used to count training steps. To make this easier, the variable constructor supports a trainable=<bool> parameter. tf.GradientTape watches trainable variables by default:

with tf.GradientTape(persistent=True) as tape:
  trainable = tf.Variable(1.)
  non_trainable = tf.Variable(2., trainable=False)
  x1 = trainable * 2.
  x2 = non_trainable * 3.
tape.gradient(x1, trainable)
<tf.Tensor:... shape=(), dtype=float32, numpy=2.0>
assert tape.gradient(x2, non_trainable) is None  # Unwatched

Variables are automatically tracked when assigned to attributes of types inheriting from tf.Module.

m = tf.Module()
m.v = tf.Variable([1.])
m.trainable_variables
(<tf.Variable ... shape=(1,) ... numpy=array([1.], dtype=float32)>,)

This tracking then allows saving variable values to training checkpoints, or to SavedModels which include serialized TensorFlow graphs.

Variables are often captured and manipulated by tf.functions. This works the same way the un-decorated function would have:

v = tf.Variable(0.)
read_and_decrement = tf.function(lambda: v.assign_sub(0.1))
read_and_decrement()
<tf.Tensor: shape=(), dtype=float32, numpy=-0.1>
read_and_decrement()
<tf.Tensor: shape=(), dtype=float32, numpy=-0.2>

Variables created inside a tf.function must be owned outside the function and be created only once:

class M(tf.Module):
  @tf.function
  def __call__(self, x):
    if not hasattr(self, "v"):  # Or set self.v to None in __init__
      self.v = tf.Variable(x)
    return self.v * x
m = M()
m(2.)
<tf.Tensor: shape=(), dtype=float32, numpy=4.0>
m(3.)
<tf.Tensor: shape=(), dtype=float32, numpy=6.0>
m.v
<tf.Variable ... shape=() dtype=float32, numpy=2.0>

See the tf.function documentation for details.

initial_value A Tensor, or Python object convertible to a Tensor, which is the initial value for the Variable. The initial value must have a shape specified unless validate_shape is set to False. Can also be a callable with no argument that returns the initial value when called. In that case, dtype must be specified. (Note that initializer functions from init_ops.py must first be bound to a shape before being used here.)
trainable If True, GradientTapes automatically watch uses of this variable. Defaults to True, unless synchronization is set to ON_READ, in which case it defaults to False.
validate_shape If False, allows the variable to be initialized with a value of unknown shape. If True, the default, the shape of initial_value must be known.
caching_device Optional device string describing where the Variable should be cached for reading. Defaults to the Variable's device. If not None, caches on another device. Typical use is to cache on the device where the Ops using the Variable reside, to deduplicate copying through Switch and other conditional statements.
name Optional name for the variable. Defaults to 'Variable' and gets uniquified automatically.
variable_def VariableDef protocol buffer. If not None, recreates the Variable object with its contents, referencing the variable's nodes in the graph, which must already exist. The graph is not changed. variable_def and the other arguments are mutually exclusive.
dtype If set, initial_value will be converted to the given type. If None, either the datatype will be kept (if initial_value is a Tensor), or convert_to_tensor will decide.
import_scope Optional string. Name scope to add to the Variable. Only used when initializing from protocol buffer.
constraint An optional projection function to be applied to the variable after being updated by an Optimizer (e.g. used to implement norm constraints or value constraints for layer weights). The function must take as input the unprojected Tensor representing the value of the variable and return the Tensor for the projected value (which must have the same shape). Constraints are not safe to use when doing asynchronous distributed training.
synchronization Indicates when a distributed a vari