Comment obtenir les dimensions (forme) du tenseur Tensorflow en tant que valeurs int?

88

Supposons que j'ai un tenseur Tensorflow. Comment obtenir les dimensions (forme) du tenseur sous forme de valeurs entières? Je sais qu'il existe deux méthodes tensor.get_shape()et tf.shape(tensor), mais je ne peux pas obtenir les valeurs de forme sous forme de valeurs entières int32.

Par exemple, ci-dessous, j'ai créé un tenseur 2D, et j'ai besoin d'obtenir le nombre de lignes et de colonnes int32afin que je puisse appeler reshape()pour créer un tenseur de forme (num_rows * num_cols, 1). Cependant, la méthode tensor.get_shape()renvoie des valeurs comme Dimensiontype, pas int32.

import tensorflow as tf
import numpy as np

sess = tf.Session()    
tensor = tf.convert_to_tensor(np.array([[1001,1002,1003],[3,4,5]]), dtype=tf.float32)

sess.run(tensor)    
# array([[ 1001.,  1002.,  1003.],
#        [    3.,     4.,     5.]], dtype=float32)

tensor_shape = tensor.get_shape()    
tensor_shape
# TensorShape([Dimension(2), Dimension(3)])    
print tensor_shape    
# (2, 3)

num_rows = tensor_shape[0] # ???
num_cols = tensor_shape[1] # ???

tensor2 = tf.reshape(tensor, (num_rows*num_cols, 1))    
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/ops/gen_array_ops.py", line 1750, in reshape
#     name=name)
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/framework/op_def_library.py", line 454, in apply_op
#     as_ref=input_arg.is_ref)
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 621, in convert_to_tensor
#     ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/framework/constant_op.py", line 180, in _constant_tensor_conversion_function
#     return constant(v, dtype=dtype, name=name)
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/framework/constant_op.py", line 163, in constant
#     tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape))
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/framework/tensor_util.py", line 353, in make_tensor_proto
#     _AssertCompatible(values, dtype)
#   File "/usr/local/lib/python2.7/site-packages/tensorflow/python/framework/tensor_util.py", line 290, in _AssertCompatible
#     (dtype.name, repr(mismatch), type(mismatch).__name__))
# TypeError: Expected int32, got Dimension(6) of type 'Dimension' instead.
stackoverflowuser2010
la source

Réponses:

126

Pour obtenir la forme sous forme de liste d'entiers, faites tensor.get_shape().as_list().

Pour terminer votre tf.shape()appel, essayez tensor2 = tf.reshape(tensor, tf.TensorShape([num_rows*num_cols, 1])). Ou vous pouvez directement faire tensor2 = tf.reshape(tensor, tf.TensorShape([-1, 1]))où sa première dimension peut être déduite.

yuefengz
la source
Merci, cela me permet d'appeler et de terminer tf.reshape(), mais j'aimerais vraiment obtenir num_rowset num_colssous forme d'entiers pour d'autres opérations.
stackoverflowuser2010
6
Essayer tensor.get_shape().as_list()
yuefengz
1
Ouais, ça as_list()marche. Veuillez l'ajouter à votre réponse et j'accepterai.
stackoverflowuser2010
2
Pour être complet, ce code fonctionne:num_rows, num_cols = x.get_shape().as_list()
stackoverflowuser2010
1
Agréable! J'utilisais python int () pour convertir les résultats de x.get_shape (). ie num_rows = int (x.get_shape () [1]), num_cols = int (x.get_shape () [2]), etc. Merci de m'avoir éclairé sur une meilleure façon :-)
SherylHohman
31

Une autre façon de résoudre ce problème est la suivante:

tensor_shape[0].value

Cela renverra la valeur int de l'objet Dimension.

tijmen Verhulsdonck
la source
6

pour un tenseur 2-D, vous pouvez obtenir le nombre de lignes et de colonnes comme int32 en utilisant le code suivant:

rows, columns = map(lambda i: i.value, tensor.get_shape())
Anna
la source
2
Très inélégant. Comment cela s'ajoute aux réponses déjà fournies?
rayryeng
4

Réponse compatible 2.0 : Dans Tensorflow 2.x (2.1), vous pouvez obtenir les dimensions (forme) du tenseur sous forme de valeurs entières, comme indiqué dans le code ci-dessous:

Méthode 1 (en utilisant tf.shape) :

import tensorflow as tf
c = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
Shape = c.shape.as_list()
print(Shape)   # [2,3]

Méthode 2 (en utilisant tf.get_shape()) :

import tensorflow as tf
c = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
Shape = c.get_shape().as_list()
print(Shape)   # [2,3]
Prise en charge de Tensorflow
la source
1

Une autre solution simple consiste à utiliser map()comme suit:

tensor_shape = map(int, my_tensor.shape)

Cela convertit tous les Dimensionobjets enint

Achille Huet
la source
0

Dans les versions ultérieures (testées avec TensorFlow 1.14), il existe un moyen plus numérique d'obtenir la forme d'un tenseur. Vous pouvez utiliser tensor.shapepour obtenir la forme du tenseur.

tensor_shape = tensor.shape
print(tensor_shape)
thushv89
la source