如何在图构建时获取张量的维度(在 TensorFlow 中)?

Posted

技术标签:

【中文标题】如何在图构建时获取张量的维度(在 TensorFlow 中)?【英文标题】:How to get the dimensions of a tensor (in TensorFlow) at graph construction time? 【发布时间】:2016-08-26 06:23:39 【问题描述】:

我正在尝试一个不符合预期的操作。

graph = tf.Graph()
with graph.as_default():
  train_dataset = tf.placeholder(tf.int32, shape=[128, 2])
  embeddings = tf.Variable(
    tf.random_uniform([50000, 64], -1.0, 1.0))
  embed = tf.nn.embedding_lookup(embeddings, train_dataset)
  embed = tf.reduce_sum(embed, reduction_indices=0)

所以我需要知道张量 embed 的尺寸。我知道它可以在运行时完成,但是对于这样一个简单的操作来说工作量太大了。有什么更简单的方法?

【问题讨论】:

【参考方案1】:

我看到大多数人对tf.shape(tensor)tensor.get_shape() 感到困惑 让我们说清楚:

    tf.shape

tf.shape 用于动态形状。如果您的张量的形状是可变,请使用它。 举个例子:输入是一个宽度和高度可变的图像,我们想把它调整为它的一半大小,那么我们可以这样写:new_height = tf.shape(image)[0] / 2

    tensor.get_shape

tensor.get_shape 用于固定形状,表示张量的形状可以在图中推导出

结论: tf.shape 几乎可以在任何地方使用,但t.get_shape 只能用于从图形中推断出的形状。

【讨论】:

【参考方案2】:

Tensor.get_shape() 来自this post。

From documentation:

c = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
print(c.get_shape())
==> TensorShape([Dimension(2), Dimension(3)])

【讨论】:

如果有人想知道:tf.shape(c) 返回一个表示c 形状的一维整数张量。在这个答案给出的例子中,tf.shape(c) 返回Tensor("Shape:0", shape=(2,), dtype=int32) @nobar 如果维度是None(即,如果未指定),您可能需要使用tf.shape(c)。例如,如果a = tf.placeholder(tf.int32, (None,2)),并且您运行tf.Session().run(tf.constant(a.get_shape().as_list()[0]), a:[[1,2]]) ,您将得到错误,但您可以通过:tf.Session().run(tf.shape(a)[0], a:[[1,2]]) 获取维度。【参考方案3】:

访问值的函数:

def shape(tensor):
    s = tensor.get_shape()
    return tuple([s[i].value for i in range(0, len(s))])

例子:

batch_size, num_feats = shape(logits)

【讨论】:

return tuple(tensor.get_shape().as_list())如果你想要一个元组,或者直接返回python列表如return tensor.get_shape().as_list()【参考方案4】:

在构造图(ops)之后打印出嵌入而不运行:

import tensorflow as tf

...

train_dataset = tf.placeholder(tf.int32, shape=[128, 2])
embeddings = tf.Variable(
    tf.random_uniform([50000, 64], -1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_dataset)
print (embed)

这将显示嵌入张量的形状:

Tensor("embedding_lookup:0", shape=(128, 2, 64), dtype=float32)

通常,最好在训练模型之前检查所有张量的形状。

【讨论】:

虽然我在您发布之前给出的答案是正确的,但您的答案提供了有关张量的更多信息而不仅仅是它的形状,因此,我接受它作为正确答案;)【参考方案5】:

让我们让它变得简单。如果您想要像2, 3, 4, etc., 这样的维度数使用单个数字,则只需使用tf.rank()。但是,如果您想要张量的确切形状,请使用tensor.get_shape()

with tf.Session() as sess:
   arr = tf.random_normal(shape=(10, 32, 32, 128))
   a = tf.random_gamma(shape=(3, 3, 1), alpha=0.1)
   print(sess.run([tf.rank(arr), tf.rank(a)]))
   print(arr.get_shape(), ", ", a.get_shape())     


# for tf.rank()    
[4, 3]

# for tf.get_shape()
Output: (10, 32, 32, 128) , (3, 3, 1)

【讨论】:

【参考方案6】:

方法 tf.shape 是 TensorFlow 的静态方法。但是,Tensor 类也有 get_shape 方法。见

https://www.tensorflow.org/api_docs/python/tf/Tensor#get_shape

【讨论】:

真的没有 - 我只是想尽可能简洁地解释它;-)

以上是关于如何在图构建时获取张量的维度(在 TensorFlow 中)?的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow低阶API—— 张量

如何在 Tensorflow 中对无维度的张量进行切片

PyTorch 张量是如何实现的?

如何连接具有 2 个不同维度的 2d 张量

如何在 Keras / Tensorflow 中将(无,)批量维度重新引入张量?

如何更新匹配维度向量的张量