Reputation: 1675
# Using Python state
x = tf.zeros([10, 10])
x += 2 # This is equivalent to x = x + 2, which does not mutate the original
# value of x
print(x)
x changed from 0 to 2. It shows the following result of x = tf.zeros([10,10]):
<tf.Tensor: id=266, shape=(10, 10), dtype=float32, numpy=
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>
Then it changed to the following after executing: x += 2
<tf.Tensor: id=263, shape=(10, 10), dtype=float32, numpy=
array([[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]], dtype=float32)>
Why does the comment say "which does not mutate the original value of x"?
Upvotes: 1
Views: 248
Reputation: 975
Chris Heald is right. It's eaiest to see the difference using NumPy:
import numpy as np
a = np.array(2)
b = a # Set up an alias
a += 1 # NumPy operations are in-place - they mutate the array
print(b) # Output: 3!
Since the ndarray
's __iadd__
mutates the array in-place, any references to the array will update, so the code prints 3
. NumPy arrays are more like objects in this regard.
Compare this with TF Tensor
s, which are immutable (code is TF 2):
import tensorflow as tf
a = tf.constant(2)
b = a # Set up an alias
a += 1 # Tensor operations are not in-place - a new tensor is created
print(b) # Output: 2
That prints 2, because Tensor
is immutable. So they are more like primitive values.
Accessing the original value is then straightforward - just assign it to some other variable (like I did with b = a
).
Another way to describe this is using lists:
l = [1]
l[0] = 2 # I can mutate the list...
l = [2] # ... or I can create a new one
Upvotes: 2