¿Convertir un tensor en una matriz numpy en Tensorflow?
¿Cómo convertir un tensor en una matriz numpy cuando se usa Tensorflow con enlaces de Python?
TensorFlow 2.x
La ejecución ansiosa está habilitada de forma predeterminada, así que simplemente llame .numpy()
al objeto Tensor.
import tensorflow as tf
a = tf.constant([[1, 2], [3, 4]])
b = tf.add(a, 1)
a.numpy()
# array([[1, 2],
# [3, 4]], dtype=int32)
b.numpy()
# array([[2, 3],
# [4, 5]], dtype=int32)
tf.multiply(a, b).numpy()
# array([[ 2, 6],
# [12, 20]], dtype=int32)
Consulte Compatibilidad de NumPy para obtener más información. Vale la pena señalar (de los documentos),
La matriz Numpy puede compartir una memoria con el objeto Tensor. Cualquier cambio en uno puede reflejarse en el otro.
El énfasis en negrita es mío. Se puede devolver o no una copia, y este es un detalle de implementación basado en si los datos están en la CPU o en la GPU (en el último caso, se debe realizar una copia desde la GPU a la memoria del host).
Pero ¿por qué recibo el AttributeError: 'Tensor' object has no attribute 'numpy'
? .
Mucha gente ha comentado sobre este tema, hay un par de posibles razones:
- TF 2.0 no está instalado correctamente (en cuyo caso, intente reinstalarlo), o
- TF 2.0 está instalado, pero la ejecución ansiosa está deshabilitada por algún motivo. En tales casos, llame
tf.compat.v1.enable_eager_execution()
para habilitarlo o consulte a continuación.
Si Eager Execution está deshabilitado, puede crear un gráfico y luego ejecutarlo tf.compat.v1.Session
:
a = tf.constant([[1, 2], [3, 4]])
b = tf.add(a, 1)
out = tf.multiply(a, b)
out.eval(session=tf.compat.v1.Session())
# array([[ 2, 6],
# [12, 20]], dtype=int32)
Consulte también Mapa de símbolos TF 2.0 para obtener una asignación de la API antigua a la nueva.
Cualquier tensor devuelto por Session.run
o eval
es una matriz NumPy.
>>> print(type(tf.Session().run(tf.constant([1,2,3]))))
<class 'numpy.ndarray'>
O:
>>> sess = tf.InteractiveSession()
>>> print(type(tf.constant([1,2,3]).eval()))
<class 'numpy.ndarray'>
O equivalente:
>>> sess = tf.Session()
>>> with sess.as_default():
>>> print(type(tf.constant([1,2,3]).eval()))
<class 'numpy.ndarray'>
EDITAR: Ningún tensor devuelto por oSession.run
es eval()
una matriz NumPy. Los tensores dispersos, por ejemplo, se devuelven como SparseTensorValue:
>>> print(type(tf.Session().run(tf.SparseTensor([[0, 0]],[1],[1,2]))))
<class 'tensorflow.python.framework.sparse_tensor.SparseTensorValue'>
Para volver a convertir de tensor a matriz numpy, simplemente puede ejecutar .eval()
el tensor transformado.
Respecto a Tensorflow 2.x
Generalmente funciona lo siguiente, ya que la ejecución ansiosa está activada de forma predeterminada:
import tensorflow as tf
a = tf.constant([[1, 2], [3, 4]])
b = tf.add(a, 1)
print(a.numpy())
# [[1 2]
# [3 4]]
Sin embargo, dado que mucha gente parece estar publicando el error:
AttributeError: 'Tensor' object has no attribute 'numpy'
Creo que es justo mencionar que llamar tensor.numpy()
en modo gráfico no funcionará. Es por eso que estás viendo este error. Aquí hay un ejemplo simple:
import tensorflow as tf
@tf.function
def add():
a = tf.constant([[1, 2], [3, 4]])
b = tf.add(a, 1)
tf.print(a.numpy()) # throws an error!
return a
add()
Puede encontrar una explicación sencilla aquí :
Fundamentalmente, no se puede convertir un tensor de gráfico en una matriz numpy porque el gráfico no se ejecuta en Python, por lo que no hay NumPy en la ejecución del gráfico. [...]
También vale la pena echar un vistazo a los documentos de TF .
Respecto a los modelos Keras con Tensorflow 2.x
Esto también se aplica a Keras
los modelos, que están envueltos en un tf.function
valor predeterminado. Si realmente necesita ejecutar tensor.numpy()
, puede configurar el parámetro run_eagerly=True
en model.compile(*)
, pero esto influirá en el rendimiento de su modelo.