TensorFlow tutorial says that at creation time we need to specify the shape of tensors. That shape automatically becomes the shape of the tensor. It also says that TensorFlow provides advanced mechanisms to reshape variables. How can I do that? Any code example?
6 回答
类是创建变量的tf.Variable
推荐方法,但它限制了您在创建变量后更改其形状的能力。
如果您需要更改变量的形状,您可以执行以下操作(例如,对于 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.
请注意,此功能不在记录的公共 API 中,因此可能会发生变化。如果您确实发现自己需要使用此功能,请告诉我们,我们可以研究一种方法来支持它向前发展。
查看 TensorFlow 文档中的shape-and-shaping。它描述了可用的不同形状转换。
最常见的函数可能是tf.reshape,它类似于它的 numpy 等效函数。只要元素的数量保持不变,它就允许您指定所需的任何形状。文档中提供了一些示例。
文档显示了重塑的方法。他们是:
- 重塑
- 挤压(从张量的形状中删除尺寸为 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(tf.placeholder(tf.float32))
在 tensorflow 1.2.1 中无效
在 python 外壳中:
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)
您可以通过传递自己的 init 函数来创建具有任何形状的变量。
另一种方式:
var = tf.get_varible('my-name', initializer=init, shape=(1,1))
您可以传递tf.constant
或任何init
返回 numpy 数组的函数。提供的形状将不会被验证。输出形状是您的真实数据形状。
正如 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]
tf.Variable
: 使用shape
参数None
1.14 中添加了一个允许指定未知形状的功能。
如果shape
是None
,则使用初始形状值。
如果shape
指定,则将其用作形状并允许具有None
.
例子:
var = tf.Variable(array, shape=(None, 10))
这允许稍后分配具有与上述形状匹配的形状的值(例如,轴 0 中的任意形状)
var.assign(new_value)