将 TensorFlow 张量转换为 Numpy 数组

Converting TensorFlow tensor into Numpy array

问题描述

我正在尝试在 TensorFlow 2.3.0 中编写自定义损失函数。为了计算损失,我需要将 y_pred 参数转换为 numpy 数组。但是,我找不到将它从 <class 'tensorflow.python.framework.ops.Tensor'> 转换为 numpy 数组的方法,即使 TensorFlow 函数似乎可以这样做。

代码示例

def custom_loss(y_true, y_pred):
    print(type(y_pred))
    npa = y_pred.make_ndarray()
    ...
    

if __name__ == '__main__':
    ...
    model.compile(loss=custom_loss, optimizer="adam")
    model.fit(x=train_data, y=train_data, epochs=10)

给出错误信息:AttributeError: 'Tensor' object has no attribute 'make_ndarray 打印 y_pred 参数的类型后:<class 'tensorflow.python.framework.ops.Tensor'>

到目前为止我尝试了什么

寻找解决方案,我发现这似乎是一个常见问题,并且有一些建议,但到目前为止它们对我不起作用:

1. “...所以只需在 Tensor 对象上调用 .numpy()。”:How can I convert a tensor into a numpy array in TensorFlow?

所以我尝试了:

def custom_loss(y_true, y_pred):
    npa = y_pred.numpy()
    ...

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

2。 “使用 tensorflow.Tensor.eval() 将张量转换为数组”:How to convert a TensorFlow tensor to a NumPy array in Python

所以我尝试了:

def custom_loss(y_true, y_pred):
    npa = y_pred.eval(session=tf.compat.v1.Session())
    ...

这是我见过的最长的错误消息之一,核心是:

InvalidArgumentError: 2 root error(s) found.
      (0) Invalid argument: You must feed a value for placeholder tensor 'functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource' with dtype resource
         [[node functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource (defined at main.py:303) ]]
         [[functional_1/cropping2d/strided_slice/_1]]
      (1) Invalid argument: You must feed a value for placeholder tensor 'functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource' with dtype resource
         [[node functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource (defined at main.py:303) ]]

还必须从版本 1.x 调用 TensorFlow 兼容性函数感觉不太适合未来,所以无论如何我不太喜欢这种方法。

3。查看 TensorFlow 文档,似乎有我需要等待的功能:tf.make_ndarray 从张量创建一个 numpy ndarray。

所以我尝试了:

def custom_loss(y_true, y_pred):
    npa = tf.make_ndarray(y_pred)
    ...

给我 AttributeError: 'Tensor' object has no attribute 'tensor_shape'

查看 TF 文档中的示例,他们在 proto_tensor 上使用了它,所以我首先尝试转换为原型:

def custom_loss(y_true, y_pred):
    proto_tensor = tf.make_tensor_proto(y_pred)
    npa = tf.make_ndarray(proto_tensor)
    ...

tf.make_tensor_proto(y_pred) 已经引发错误:TypeError: Expected any non-tensor type, got a tensor instead.

同样尝试首先创建一个 const 张量给出同样的错误:

def custom_loss(y_true, y_pred):
    a = tf.constant(y_pred)
    proto_tensor = tf.make_tensor_proto(a)
    npa = tf.make_ndarray(proto_tensor)
    ...

关于这个的帖子还有很多,但似乎他们都回到了这三个基本思想上。期待您的建议!

y_pred.numpy() 在 TF 2 中工作,但 AttributeError: 'Tensor' object has no attribute 'make_ndarray 表示你的代码中有部分你不是 运行 在 Eager 模式下,否则你不会有 Tensor 对象而是一个 EagerTensor.

要启用急切模式,请在构建图表中的任何内容之前将其放在代码的开头:

tf.config.experimental_run_functions_eagerly(True)

其次,当你编译你的模型时,添加这个参数:

model.compile(..., run_eagerly=True, ...)

现在您正在 Eager 模式下执行,所有变量实际上都包含您可以打印和使用的值。请注意,切换到 Eager 模式可能需要对您的代码进行额外调整(请参阅 here 了解概述)。