AttributeError:“张量”对象在 Tensorflow 2.1 中没有属性“numpy”

Posted

技术标签:

【中文标题】AttributeError:“张量”对象在 Tensorflow 2.1 中没有属性“numpy”【英文标题】:AttributeError: 'Tensor' object has no attribute 'numpy' in Tensorflow 2.1 【发布时间】:2020-06-06 09:31:28 【问题描述】:

我正在尝试在 Tensorflow 2.1 中转换 Tensorshape 属性,但出现此错误:

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

我已经检查了tf.executing eagerly()的输出是True

一点上下文:我从 TFRecords 加载 tf.data.Dataset,然后应用 map。映射函数正在尝试将数据集样本Tensor 之一的shape 属性转换为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)

这会引发错误:

dataset.map(transform, num_parallel_calls=1)

虽然这非常有效:

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

编辑:尝试访问 img.numpy() 而不是 img.shape.numpy() 会导致变压器和上面的代码中出现相同的行为。

我检查了img_shape的类型,它是&lt;class 'tensorflow.python.framework.ops.Tensor'&gt;

有人在新版本的 Tensorflow 中解决了这类问题吗?

【问题讨论】:

img 的形状完全定义了吗?如果它的形状在任一维度中包含None,则可能会发生这种情况 我编辑了我的帖子以添加更多上下文。我正在使用 tf.io.decode_png 解析 img 所以我猜这个形状是已知的,不是吗?还调用numpy()on img 而不是它的形状给了我相同的行为......奇怪的是,如果我在dataset.take() 的元素中而不是在@ 中执行此操作,所有这些都不会导致错误987654344@... 【参考方案1】:

您的代码中的问题是您不能在映射到 tf.data.Datasets 的函数内部使用 .numpy(),因为 .numpy() 是 Python 代码而不是纯 TensorFlow 代码。

当您使用my_dataset.map(my_function) 之类的函数时,您只能在my_function 函数中使用tf.* 函数。

这不是 TensorFlow 2.x 版本的错误,而是出于性能目的如何在后台生成静态图。

如果您想在映射到数据集的函数中使用自定义 Python 代码,则必须使用 tf.py_function(),文档:https://www.tensorflow.org/api_docs/python/tf/py_function。在数据集上进行映射时,确实没有其他方法可以混合 Python 代码和 TensorFlow 代码。

您也可以查阅此问题以获取更多信息;这是我几个月前问的确切问题:Is there an alternative to tf.py_function() for custom Python code?

【讨论】:

谢谢!我认为我无法将管道中的所有内容都转换为原生 tensorflow 操作,因为我需要根据张量值动态填充列表......你认为我仍然可以通过在纯 tensorflow 操作中映射所有内容来获得性能然后在另一个map 调用tf.py_func 中做动态部分? 您仍然可以获得一些性能,但我会进行基准测试以清楚地看到时间性能的差异/增益/损失。

以上是关于AttributeError:“张量”对象在 Tensorflow 2.1 中没有属性“numpy”的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“张量”对象没有属性“numpy”

AttributeError:“张量”对象没有属性“to_sparse”

AttributeError:模块“张量流”没有属性“会话”

pytorch,AttributeError:模块“火炬”没有属性“张量”

AttributeError:“张量”没有属性:“向后”

AttributeError:“元组”对象没有属性“大小”