Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError: 'Tensor' object has no attribute 'numpy' in Tensorflow 2.1

I am trying to convert the shape property of a Tensor in Tensorflow 2.1 and I get this error:

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

I already checked that the output of tf.executing eagerly() is True,

A bit of context: I load a tf.data.Dataset from a TFRecords, then I apply a map. The maping function is trying to convert the shape property of one of the dataset sample Tensor to numpy:

def _parse_and_decode(serialized_example):
    """ parse and decode each image """
    features = tf.io.parse_single_example(
        serialized_example,
        features={
            'encoded_image': tf.io.FixedLenFeature([], tf.string),
            'kp_flat': tf.io.VarLenFeature(tf.int64),
            'kp_shape': tf.io.FixedLenFeature([3], tf.int64),
        }
    )
    image = tf.io.decode_png(features['encoded_image'], dtype=tf.uint8)
    image = tf.cast(image, tf.float32)

    kp_shape = features['kp_shape']

    kp_flat = tf.sparse.to_dense(features['kp_flat'])
    kp = tf.reshape(kp_flat, kp_shape)

    return image, kp


def read_tfrecords(records_dir, batch_size=1):
    # Read dataset from tfrecords
    tfrecords_files = glob.glob(os.path.join(records_dir, '*'))
    dataset = tf.data.TFRecordDataset(tfrecords_files)
    dataset = dataset.map(_parse_and_decode, num_parallel_calls=batch_size)
    return dataset


def transform(img, labels):
    img_shape = img.shape  # type: <class 'tensorflow.python.framework.ops.Tensor'>`
    img_shape = img_shape.numpy()  # <-- Throws the error
    # ...    

dataset = read_tfrecords(records_dir)

This throws the error:

dataset.map(transform, num_parallel_calls=1)

While this perfecly works:

for img, labels in dataset.take(1):
    print(img.shape.numpy())

Edit: trying to access the img.numpy() instead of img.shape.numpy() results in the same behavior in the tranformer and the codde just above.

I checked the type of img_shape and it is <class 'tensorflow.python.framework.ops.Tensor'>.

Has anyone solved this sort of issue in new versions of Tensorflow?

like image 945
Nick Skywalker Avatar asked Feb 21 '20 23:02

Nick Skywalker


1 Answers

The problem in your code is that you cannot use .numpy() inside functions that are mapped onto tf.data.Datasets, because .numpy() is Python code not pure TensorFlow code.

When you use a function like my_dataset.map(my_function), you can only use tf.* functions inside your my_function function.

This is not a bug of TensorFlow 2.x versions, but rather on how static graphs are generated behind the scenes for performance purposes.

If you want to use custom Python code inside a function which you map on your dataset, you have to use tf.py_function(), docs: https://www.tensorflow.org/api_docs/python/tf/py_function. There is really no other way to mix Python code and TensorFlow code when mapping on a dataset.

You can also consult this question for further information; it's the exact question that I asked a couple of months ago: Is there an alternative to tf.py_function() for custom Python code?

like image 109
Timbus Calin Avatar answered Oct 20 '22 16:10

Timbus Calin