How to get the dimensions of a tensor (in TensorFlow) at graph construction time?

138,442

Solution 1

Tensor.get_shape() from 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)])

Solution 2

I see most people confused about tf.shape(tensor) and tensor.get_shape() Let's make it clear:

  1. tf.shape

tf.shape is used for dynamic shape. If your tensor's shape is changable, use it. An example: a input is an image with changable width and height, we want resize it to half of its size, then we can write something like:
new_height = tf.shape(image)[0] / 2

  1. tensor.get_shape

tensor.get_shape is used for fixed shapes, which means the tensor's shape can be deduced in the graph.

Conclusion: tf.shape can be used almost anywhere, but t.get_shape only for shapes can be deduced from graph.

Solution 3

A function to access the values:

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

Example:

batch_size, num_feats = shape(logits)

Solution 4

Just print out the embed after construction graph (ops) without running:

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)

This will show the shape of the embed tensor:

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

Usually, it's good to check shapes of all tensors before training your models.

Solution 5

Let's make it simple as hell. If you want a single number for the number of dimensions like 2, 3, 4, etc., then just use tf.rank(). But, if you want the exact shape of the tensor then use 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)
Share:
138,442

Related videos on Youtube

Thoran
Author by

Thoran

I am a Civil Engineer at skin but a programmer at heart. I developed Fold Dashboard for Chrome. Doing my best to turn my unknown unknowns into known unknowns and a tiny bit of that into my knowledge.

Updated on March 29, 2022

Comments

  • Thoran
    Thoran about 2 years

    I am trying an Op that is not behaving as expected.

    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)
    

    So I need to know the dimensions of the Tensor embed. I know that it can be done at the run time but it's too much work for such a simple operation. What's the easier way to do it?

  • Thoran
    Thoran about 8 years
    While the answer I gave before you post yours was correct, your answer gives more information about the tensor than just its shape, hence, I accept it as the correct answer ;)
  • Franck Dernoncourt
    Franck Dernoncourt about 7 years
    If anyone wonders: tf.shape(c) returns a 1-D integer tensor representing the shape of c. In the example given in this answer, tf.shape(c) returns Tensor("Shape:0", shape=(2,), dtype=int32)
  • Saeid BK
    Saeid BK about 7 years
    @nobar if the dimension is None (i.e., if it is unspecified), you might need to use tf.shape(c). For example, if a = tf.placeholder(tf.int32, (None,2)), and you run tf.Session().run(tf.constant(a.get_shape().as_list()[0]), {a:[[1,2]]}) you will get error, but you can get the dimension by: tf.Session().run(tf.shape(a)[0], {a:[[1,2]]}).
  • cliffberg
    cliffberg over 6 years
    None really - I was just trying to explain it as succinctly as possible ;-)
  • Mr_and_Mrs_D
    Mr_and_Mrs_D about 6 years
    return tuple(tensor.get_shape().as_list()) if you want a tuple, or directly return the python list as in return tensor.get_shape().as_list()