Como obter as dimensões do tensor Tensorflow (forma) como valores int?

88

Suponha que eu tenha um tensor Tensorflow. Como obtenho as dimensões (forma) do tensor como valores inteiros? Eu sei que existem dois métodos tensor.get_shape()e tf.shape(tensor), mas não consigo obter os valores da forma como int32valores inteiros .

Por exemplo, abaixo, criei um tensor 2-D e preciso obter o número de linhas e colunas int32para que possa chamar reshape()para criar um tensor de forma (num_rows * num_cols, 1). No entanto, o método tensor.get_shape()retorna valores como Dimensiontipo, não 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
fonte

Respostas:

126

Para obter a forma como uma lista de ints, faça tensor.get_shape().as_list().

Para completar sua tf.shape()chamada, tente tensor2 = tf.reshape(tensor, tf.TensorShape([num_rows*num_cols, 1])). Ou você pode fazer diretamente tensor2 = tf.reshape(tensor, tf.TensorShape([-1, 1]))onde sua primeira dimensão pode ser inferida.

Yuefengz
fonte
Obrigado, isso me permite ligar e concluir tf.reshape(), mas eu realmente gostaria de obter num_rowse num_colscomo inteiros para outras operações.
stackoverflowuser2010
6
Tentetensor.get_shape().as_list()
yuefengz
1
Sim, as_list()funciona. Adicione-o à sua resposta e aceitarei.
stackoverflowuser2010
2
Para completar, este código funciona:num_rows, num_cols = x.get_shape().as_list()
stackoverflowuser2010
1
Agradável! Eu estava usando python int () para lançar os resultados de x.get_shape (). isto é, num_rows = int (x.get_shape () [1]), num_cols = int (x.get_shape () [2]), etc. Sim, meio que um hacky para contornar aquele erro chato, mas funcionou. Obrigado por me iluminar de uma maneira melhor :-)
SherylHohman
31

Outra maneira de resolver isso é:

tensor_shape[0].value

Isso retornará o valor int do objeto Dimension.

Tijmen Verhulsdonck
fonte
6

para um tensor 2-D, você pode obter o número de linhas e colunas como int32 usando o seguinte código:

rows, columns = map(lambda i: i.value, tensor.get_shape())
Anna
fonte
2
Muito deselegante. Como isso se soma às respostas já fornecidas?
rayryeng,
4

2.0 Resposta compatível : Em Tensorflow 2.x (2.1), você pode obter as dimensões (forma) do tensor como valores inteiros, conforme mostrado no Código abaixo:

Método 1 (usando 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étodo 2 (usando 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]
Suporte Tensorflow
fonte
1

Outra solução simples é usar map()o seguinte:

tensor_shape = map(int, my_tensor.shape)

Isso converte todos os Dimensionobjetos emint

Achille Huet
fonte
0

Em versões posteriores (testadas com TensorFlow 1.14), há uma maneira mais entorpecida de obter a forma de um tensor. Você pode usar tensor.shapepara obter a forma do tensor.

tensor_shape = tensor.shape
print(tensor_shape)
thushv89
fonte