为什么 Tensor 的值会改变?
Why does the Tensor's value change?
# 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 从 0 变为 2。
它显示了 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)>
然后执行后变成如下: 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)>
为什么评论说"which does not mutate the original value of x"?
Chris Heald 是对的。使用 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!
由于 ndarray
的 __iadd__
就地改变数组,任何对数组的引用都会更新,所以代码打印 3
。 NumPy 数组在这方面更像是对象。
将其与不可变的 TF Tensor
s 进行比较(代码为 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
打印 2,因为 Tensor
是不可变的。所以它们更像是原始值。
然后访问原始值很简单 - 只需将其分配给其他变量(就像我对 b = a
所做的那样)。
另一种描述方式是使用列表:
l = [1]
l[0] = 2 # I can mutate the list...
l = [2] # ... or I can create a new one
# 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 从 0 变为 2。 它显示了 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)>
然后执行后变成如下: 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)>
为什么评论说"which does not mutate the original value of x"?
Chris Heald 是对的。使用 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!
由于 ndarray
的 __iadd__
就地改变数组,任何对数组的引用都会更新,所以代码打印 3
。 NumPy 数组在这方面更像是对象。
将其与不可变的 TF Tensor
s 进行比较(代码为 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
打印 2,因为 Tensor
是不可变的。所以它们更像是原始值。
然后访问原始值很简单 - 只需将其分配给其他变量(就像我对 b = a
所做的那样)。
另一种描述方式是使用列表:
l = [1]
l[0] = 2 # I can mutate the list...
l = [2] # ... or I can create a new one