¿Cómo puedo convertir un tensor en una matriz numpy en TensorFlow?

181

¿Cómo convertir un tensor en una matriz numpy cuando se usa Tensorflow con enlaces de Python?

mathetes
fuente

Respuestas:

134

Cualquier tensor devuelto por Session.runo evales 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'>

EDIT: No cualquier tensor devuelto por Session.runo eval()es 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'>
Lenar Hoyt
fuente
AttributeError: el módulo 'tensorflow' no tiene atributo 'Sesión'
Jürgen K.
77

Para volver a convertir de tensor a matriz numpy, simplemente puede ejecutar .eval()en el tensor transformado.

Rafał Józefowicz
fuente
55
para aclarar: yourtensor.eval ()
mrk
12
Obtengo ValueError: Cannot evaluate tensor using 'eval()': No default session is registered. Use 'with sess.as_default()' or pass an explicit session to 'eval(session=sess)'¿Esto se puede usar solo durante una sesión de decenas de flujo?
Eduardo Pignatelli
@EduardoPignatelli Me funciona en Theano sin trabajo adicional. No estoy seguro acerca de tf.
BallpointBen
55
@EduardoPignatelli necesita ejecutar la .eval()llamada al método desde una sesión: sess = tf.Session(); with sess.as_default(): print(my_tensor.eval())
duhaime
Al usar esto, obtengo un error como AttributeError: el objeto 'Tensor' no tiene el atributo 'eval'
Aakash aggarwal
72

TensorFlow 2.x

Eager Execution está habilitada de forma predeterminada, por lo que solo debe llamar .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)

Vale la pena señalar (de los documentos),

La matriz Numpy puede compartir memoria con el objeto Tensor. Cualquier cambio en uno puede reflejarse en el otro.

El énfasis en negrita es mío. Una copia puede o no ser devuelta, y este es un detalle de implementación.


Si Eager Execution está deshabilitado, puede crear un gráfico y luego ejecutarlo a través de 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)

Ver también TF 2.0 Symbols Map para una asignación de la API antigua a la nueva.

cs95
fuente
2
¿Cómo hacer esto DENTRO de una función tf?
mathtick
@mentalmushroom No se pudo encontrar una documentación, pero se menciona en el manual de personalizaciones . Se pueden encontrar más detalles en la fuente .
nish-ant
55
Recibo el siguiente error en TF 2.0: "El objeto 'Tensor' no tiene atributo 'numpy'"
Will.Evo
@ Will.Evo es posible que haya deshabilitado la ejecución ansiosa antes de ejecutar esto. Verifique la segunda mitad de mi respuesta donde puede usar eval().
cs95
2
No, no desactivé la ansiosa ejecución. Todavía obtengo AttributeError: el objeto 'Tensor' no tiene atributo 'numpy'
Geoffrey Anderson
6

Necesitas:

  1. codificar el tensor de imagen en algún formato (jpeg, png) a tensor binario
  2. evaluar (ejecutar) el tensor binario en una sesión
  3. convertir el binario para transmitir
  4. alimentar a la imagen PIL
  5. (opcional) muestra la imagen con matplotlib

Código:

import tensorflow as tf
import matplotlib.pyplot as plt
import PIL

...

image_tensor = <your decoded image tensor>
jpeg_bin_tensor = tf.image.encode_jpeg(image_tensor)

with tf.Session() as sess:
    # display encoded back to image data
    jpeg_bin = sess.run(jpeg_bin_tensor)
    jpeg_str = StringIO.StringIO(jpeg_bin)
    jpeg_image = PIL.Image.open(jpeg_str)
    plt.imshow(jpeg_image)

Esto funcionó para mí. Puedes probarlo en un cuaderno de ipython. Simplemente no olvides agregar la siguiente línea:

%matplotlib inline
Gooshan
fuente
4

Quizás puedas probar este método:

import tensorflow as tf
W1 = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
array = W1.eval(sess)
print (array)
lovychen
fuente
2

He enfrentado y resuelto la conversión de tensor-> ndarray en el caso específico de los tensores que representan imágenes (adversarias), obtenidas con la biblioteca / tutoriales de cleverhans .

Creo que mi pregunta / respuesta ( aquí ) puede ser un ejemplo útil también para otros casos.

Soy nuevo con TensorFlow, el mío es una conclusión empírica:

Parece que el método tensor.eval () puede necesitar, para tener éxito, también el valor de los marcadores de posición de entrada . Tensor puede funcionar como una función que necesita sus valores de entrada (proporcionados en feed_dict) para devolver un valor de salida, por ejemplo

array_out = tensor.eval(session=sess, feed_dict={x: x_input})

Tenga en cuenta que el nombre del marcador de posición es x en mi caso, pero supongo que debe encontrar el nombre correcto para el marcador de posición de entrada . x_inputes un valor escalar o matriz que contiene datos de entrada.

En mi caso también proporcionar sessera obligatorio.

Mi ejemplo también cubre la parte de visualización de imágenes matplotlib , pero esto es OT.

Fabiano Tarlao
fuente
1

Un ejemplo simple podría ser,

    import tensorflow as tf
    import numpy as np
    a=tf.random_normal([2,3],0.0,1.0,dtype=tf.float32)  #sampling from a std normal
    print(type(a))
    #<class 'tensorflow.python.framework.ops.Tensor'>
    tf.InteractiveSession()  # run an interactive session in Tf.

n ahora si queremos que este tensor a se convierta en una matriz numpy

    a_np=a.eval()
    print(type(a_np))
    #<class 'numpy.ndarray'>

¡Tan sencillo como eso!

Saurabh Kumar
fuente
//no es para comentar en python. Por favor edite su respuesta.
Vlad
0

Puede usar la función de backend keras.

import tensorflow as tf
from tensorflow.python.keras import backend 

sess = backend.get_session()
array = sess.run(< Tensor >)

print(type(array))

<class 'numpy.ndarray'>

¡Espero que ayude!

Ebin Zacharias
fuente