Come ottenere le dimensioni (forma) del tensore di Tensorflow come valori int?


90

Supponiamo che io abbia un tensore di Tensorflow. Come ottengo le dimensioni (forma) del tensore come valori interi? So che esistono due metodi tensor.get_shape()e tf.shape(tensor), ma non riesco a ottenere i valori della forma come int32valori interi .

Ad esempio, di seguito ho creato un tensore 2-D e ho bisogno di ottenere il numero di righe e colonne in int32modo da poter chiamare reshape()per creare un tensore di forma (num_rows * num_cols, 1). Tuttavia, il metodo tensor.get_shape()restituisce i valori come Dimensiontipo, non come 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.

Risposte:


129

Per ottenere la forma come un elenco di int, fai tensor.get_shape().as_list().

Per completare la tf.shape()chiamata, prova tensor2 = tf.reshape(tensor, tf.TensorShape([num_rows*num_cols, 1])). Oppure puoi fare direttamente tensor2 = tf.reshape(tensor, tf.TensorShape([-1, 1]))dove la sua prima dimensione può essere dedotta.


Grazie, questo mi consente di chiamare e completare tf.reshape(), ma mi piacerebbe davvero ottenere num_rowse num_colscome numeri interi per altre operazioni.
stackoverflowuser2010

6
Provatensor.get_shape().as_list()
yuefengz

1
Sì, as_list()funziona. Aggiungilo alla tua risposta e accetterò.
stackoverflowuser2010

2
Per completezza, questo codice funziona:num_rows, num_cols = x.get_shape().as_list()
stackoverflowuser2010

1
Bello! Stavo usando python int () per eseguire il cast dei risultati di x.get_shape (). cioè num_rows = int (x.get_shape () [1]), num_cols = int (x.get_shape () [2]), ecc. Sì, un po 'un hacky per aggirare questo fastidioso errore, ma ha funzionato. Grazie per avermi illuminato in un modo migliore :-)
SherylHohman

31

Un altro modo per risolvere questo problema è come questo:

tensor_shape[0].value

Ciò restituirà il valore int dell'oggetto Dimension.


6

per un tensore 2-D, puoi ottenere il numero di righe e colonne come int32 usando il codice seguente:

rows, columns = map(lambda i: i.value, tensor.get_shape())

2
Molto inelegante. In che modo questo si aggiunge alle risposte già fornite?
Rayryeng

4

2.0 Risposta compatibile : In Tensorflow 2.x (2.1), puoi ottenere le dimensioni (forma) del tensore come valori interi, come mostrato nel codice seguente:

Metodo 1 (utilizzando 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]

Metodo 2 (utilizzando 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]

c'è qualche differenza tra i due metodi?
gota


1

Un'altra semplice soluzione è usare map()come segue:

tensor_shape = map(int, my_tensor.shape)

Questo converte tutti gli Dimensionoggetti inint


0

Nelle versioni successive (testate con TensorFlow 1.14) c'è un modo più simile a un torpore per ottenere la forma di un tensore. Puoi usare tensor.shapeper ottenere la forma del tensore.

tensor_shape = tensor.shape
print(tensor_shape)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.