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 中转换 Tensor
的 shape
属性,但出现此错误:
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
的类型,它是<class 'tensorflow.python.framework.ops.Tensor'>
。
有人在新版本的 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:模块“张量流”没有属性“会话”