How to convert a tensor into a numpy array when using Tensorflow with Python bindings?

0

12 Answers

TensorFlow 2.x

Eager Execution is enabled by default, so just call .numpy() on the Tensor object.

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) 

See NumPy Compatibility for more. It is worth noting (from the docs),

Numpy array may share a memory with the Tensor object. Any changes to one may be reflected in the other.

Bold emphasis mine. A copy may or may not be returned, and this is an implementation detail based on whether the data is in CPU or GPU (in the latter case, a copy has to be made from GPU to host memory).

But why am I getting the AttributeError: 'Tensor' object has no attribute 'numpy'?.
A lot of folks have commented about this issue, there are a couple of possible reasons:

  • TF 2.0 is not correctly installed (in which case, try re-installing), or
  • TF 2.0 is installed, but eager execution is disabled for some reason. In such cases, call tf.compat.v1.enable_eager_execution() to enable it, or see below.

If Eager Execution is disabled, you can build a graph and then run it through 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)

See also TF 2.0 Symbols Map for a mapping of the old API to the new one.

12

Any tensor returned by Session.run or eval is a NumPy array.

>>> print(type(tf.Session().run(tf.constant([1,2,3])))) <class 'numpy.ndarray'> 

Or:

>>> sess = tf.InteractiveSession() >>> print(type(tf.constant([1,2,3]).eval())) <class 'numpy.ndarray'> 

Or, equivalently:

>>> sess = tf.Session() >>> with sess.as_default(): >>> print(type(tf.constant([1,2,3]).eval())) <class 'numpy.ndarray'> 

EDIT: Not any tensor returned by Session.run or eval() is a NumPy array. Sparse Tensors for example are returned as SparseTensorValue:

>>> print(type(tf.Session().run(tf.SparseTensor([[0, 0]],[1],[1,2])))) <class 'tensorflow.python.framework.sparse_tensor.SparseTensorValue'> 
3

To convert back from tensor to numpy array you can simply run .eval() on the transformed tensor.

6

Regarding Tensorflow 2.x

The following generally works, since eager execution is activated by default:

import tensorflow as tf a = tf.constant([[1, 2], [3, 4]]) b = tf.add(a, 1) print(a.numpy()) # [[1 2] # [3 4]] 

However, since a lot of people seem to be posting the error:

AttributeError: 'Tensor' object has no attribute 'numpy' 

I think it is fair to mention that calling tensor.numpy() in graph mode will not work. That is why you are seeing this error. Here is a simple example:

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() 

A simple explanation can be found here:

Fundamentally, one cannot convert a graph tensor to numpy array because the graph does not execute in Python - so there is no NumPy at graph execution. [...]

It is also worth taking a look at the TF docs.

Regarding Keras models with Tensorflow 2.x

This also applies to Keras models, which are wrapped in a tf.function by default. If you really need to run tensor.numpy(), you can set the parameter run_eagerly=True in model.compile(*), but this will influence the performance of your model.

You need to:

  1. encode the image tensor in some format (jpeg, png) to binary tensor
  2. evaluate (run) the binary tensor in a session
  3. turn the binary to stream
  4. feed to PIL image
  5. (optional) displaythe image with matplotlib

Code:

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) 

This worked for me. You can try it in a ipython notebook. Just don't forget to add the following line:

%matplotlib inline 

Maybe you can try,this method:

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) 

I have faced and solved the tensor->ndarray conversion in the specific case of tensors representing (adversarial) images, obtained with cleverhans library/tutorials.

I think that my question/answer (here) may be an helpful example also for other cases.

I'm new with TensorFlow, mine is an empirical conclusion:

It seems that tensor.eval() method may need, in order to succeed, also the value for input placeholders. Tensor may work like a function that needs its input values (provided into feed_dict) in order to return an output value, e.g.

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

Please note that the placeholder name is x in my case, but I suppose you should find out the right name for the input placeholder. x_input is a scalar value or array containing input data.

In my case also providing sess was mandatory.

My example also covers the matplotlib image visualization part, but this is OT.

I was searching for days for this command.

This worked for me outside any session or somthing like this.

# you get an array = your tensor.eval(session=tf.compat.v1.Session()) an_array = a_tensor.eval(session=tf.compat.v1.Session()) 

You can convert a tensor in tensorflow to numpy array in the following ways.

First: Use np.array(your_tensor)

Second: Use your_tensor.numpy

1

You can use keras backend function.

import tensorflow as tf from tensorflow.python.keras import backend sess = backend.get_session() array = sess.run(< Tensor >) print(type(array)) <class 'numpy.ndarray'> 

I hope it helps!

A simple example could be,

 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 now if we want this tensor a to be converted into a numpy array

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

As simple as that!

1

If you see there is a method _numpy(), e.g for an EagerTensor simply call the above method and you will get an ndarray.