如何更改 TensorFlow 中变量的形状?
How can I change the shape of a variable in TensorFlow?
TensorFlow tutorial 表示在创建时我们需要指定张量的形状。该形状自动成为张量的形状。它还说 TensorFlow 提供了重塑变量的高级机制。我怎样才能做到这一点?有代码示例吗?
查看 TensorFlow 文档中的 shapes-and-shaping。它描述了可用的不同形状转换。
最常见的函数可能是 tf.reshape,它类似于它的 numpy 等价物。它允许您指定您想要的任何形状,只要元素的数量保持不变即可。文档中提供了一些示例。
Documentation shows 重塑方法。他们是:
- 重塑
- 挤压(从张量的形状中删除大小为 1 的维度)
- expand_dims(添加大小为 1 的维度)
以及获取张量的 shape
、size
、rank
的一系列方法。可能最常用的是 reshape
,这里是一个带有几个边缘情况 (-1) 的代码示例:
import tensorflow as tf
v1 = tf.Variable([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
v2 = tf.reshape(v1, [2, 6])
v3 = tf.reshape(v1, [2, 2, -1])
v4 = tf.reshape(v1, [-1])
# v5 = tf.reshape(v1, [2, 4, -1]) will fail, because you can not find such an integer for -1
v6 = tf.reshape(v1, [1, 4, 1, 3, 1])
v6_shape = tf.shape(v6)
v6_squeezed = tf.squeeze(v6)
v6_squeezed_shape = tf.shape(v6_squeezed)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
a, b, c, d, e, f, g = sess.run([v2, v3, v4, v6, v6_shape, v6_squeezed, v6_squeezed_shape])
# print all variables to see what is there
print e # shape of v6
print g # shape of v6_squeezed
tf.Variable
class 是创建变量的推荐方法,但它会限制您在创建变量后更改其形状的能力。
如果需要更改变量的形状,可以执行以下操作(例如,对于 32 位浮点张量):
var = tf.Variable(tf.placeholder(tf.float32))
# ...
new_value = ... # Tensor or numpy array.
change_shape_op = tf.assign(var, new_value, validate_shape=False)
# ...
sess.run(change_shape_op) # Changes the shape of `var` to new_value's shape.
请注意,此功能不在文档 public API 中,因此可能会更改。如果您确实发现自己需要使用此功能,请告诉我们,我们可以研究一种方法来支持它向前发展。
tf.Variable(tf.placeholder(tf.float32))
在 tensorflow 1.2.1 中无效
在 python shell:
import tensorflow as tf
tf.Variable(tf.placeholder(tf.float32))
您将获得:
ValueError: initial_value must have a shape specified: Tensor("Placeholder:0", dtype=float32)
更新:如果加上validate_shape=False
,就不会报错了。
tf.Variable(tf.placeholder(tf.float32), validate_shape=False)
如果 tf.py_func
符合您的要求:
def init():
return numpy.random.rand(2,3)
a = tf.pyfun(init, [], tf.float32)
您可以通过传递自己的初始化函数来创建具有任何形状的变量。
另一种方式:
var = tf.get_varible('my-name', initializer=init, shape=(1,1))
您可以传递 tf.constant
或 returns numpy 数组的任何 init
函数。提供的形状将不会被验证。输出形状是您的真实数据形状。
tf.Variable
:将 shape
参数与 None
一起使用
1.14 中的 feature was added 允许指定未知形状。
如果 shape
为 None
,则使用初始形状值。
如果指定shape
,则用作形状并允许有None
。
示例:
var = tf.Variable(array, shape=(None, 10))
这允许稍后分配具有与上述形状匹配的形状的值(例如,轴 0 中的任意形状)
var.assign(new_value)
正如 Mayou36 所说,您现在可以在首次声明后更改变量形状。这是一个工作示例:
v = tf.Variable([1], shape=tf.TensorShape(None), dtype=tf.int32)
tf.print(v)
v.assign([1, 1, 1])
tf.print(v)
这输出:
[1]
[1 1 1]
TensorFlow tutorial 表示在创建时我们需要指定张量的形状。该形状自动成为张量的形状。它还说 TensorFlow 提供了重塑变量的高级机制。我怎样才能做到这一点?有代码示例吗?
查看 TensorFlow 文档中的 shapes-and-shaping。它描述了可用的不同形状转换。
最常见的函数可能是 tf.reshape,它类似于它的 numpy 等价物。它允许您指定您想要的任何形状,只要元素的数量保持不变即可。文档中提供了一些示例。
Documentation shows 重塑方法。他们是:
- 重塑
- 挤压(从张量的形状中删除大小为 1 的维度)
- expand_dims(添加大小为 1 的维度)
以及获取张量的 shape
、size
、rank
的一系列方法。可能最常用的是 reshape
,这里是一个带有几个边缘情况 (-1) 的代码示例:
import tensorflow as tf
v1 = tf.Variable([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
v2 = tf.reshape(v1, [2, 6])
v3 = tf.reshape(v1, [2, 2, -1])
v4 = tf.reshape(v1, [-1])
# v5 = tf.reshape(v1, [2, 4, -1]) will fail, because you can not find such an integer for -1
v6 = tf.reshape(v1, [1, 4, 1, 3, 1])
v6_shape = tf.shape(v6)
v6_squeezed = tf.squeeze(v6)
v6_squeezed_shape = tf.shape(v6_squeezed)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
a, b, c, d, e, f, g = sess.run([v2, v3, v4, v6, v6_shape, v6_squeezed, v6_squeezed_shape])
# print all variables to see what is there
print e # shape of v6
print g # shape of v6_squeezed
tf.Variable
class 是创建变量的推荐方法,但它会限制您在创建变量后更改其形状的能力。
如果需要更改变量的形状,可以执行以下操作(例如,对于 32 位浮点张量):
var = tf.Variable(tf.placeholder(tf.float32))
# ...
new_value = ... # Tensor or numpy array.
change_shape_op = tf.assign(var, new_value, validate_shape=False)
# ...
sess.run(change_shape_op) # Changes the shape of `var` to new_value's shape.
请注意,此功能不在文档 public API 中,因此可能会更改。如果您确实发现自己需要使用此功能,请告诉我们,我们可以研究一种方法来支持它向前发展。
tf.Variable(tf.placeholder(tf.float32))
在 tensorflow 1.2.1 中无效
在 python shell:
import tensorflow as tf
tf.Variable(tf.placeholder(tf.float32))
您将获得:
ValueError: initial_value must have a shape specified: Tensor("Placeholder:0", dtype=float32)
更新:如果加上validate_shape=False
,就不会报错了。
tf.Variable(tf.placeholder(tf.float32), validate_shape=False)
如果 tf.py_func
符合您的要求:
def init():
return numpy.random.rand(2,3)
a = tf.pyfun(init, [], tf.float32)
您可以通过传递自己的初始化函数来创建具有任何形状的变量。
另一种方式:
var = tf.get_varible('my-name', initializer=init, shape=(1,1))
您可以传递 tf.constant
或 returns numpy 数组的任何 init
函数。提供的形状将不会被验证。输出形状是您的真实数据形状。
tf.Variable
:将 shape
参数与 None
1.14 中的 feature was added 允许指定未知形状。
如果 shape
为 None
,则使用初始形状值。
如果指定shape
,则用作形状并允许有None
。
示例:
var = tf.Variable(array, shape=(None, 10))
这允许稍后分配具有与上述形状匹配的形状的值(例如,轴 0 中的任意形状)
var.assign(new_value)
正如 Mayou36 所说,您现在可以在首次声明后更改变量形状。这是一个工作示例:
v = tf.Variable([1], shape=tf.TensorShape(None), dtype=tf.int32)
tf.print(v)
v.assign([1, 1, 1])
tf.print(v)
这输出:
[1]
[1 1 1]