将 TensorFlow 张量转换为 Numpy 数组

Fra*_*cob 8 python keras tensorflow tensorflow2.0

问题描述

我正在尝试在 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)
Run Code Online (Sandbox Code Playgroud)

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

到目前为止我尝试过的

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

1.“...所以只需在 Tensor 对象上调用 .numpy()。”:如何在 TensorFlow 中将张量转换为 numpy 数组?

所以我试过:

def custom_loss(y_true, y_pred):
    npa = y_pred.numpy()
    ...
Run Code Online (Sandbox Code Playgroud)

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

2.“使用tensorflow.Tensor.eval() to convert a tensor to an array”:如何在Python中将TensorFlow张量转换为NumPy数组

所以我试过:

def custom_loss(y_true, y_pred):
    npa = y_pred.eval(session=tf.compat.v1.Session())
    ...
Run Code Online (Sandbox Code Playgroud)

给了我我见过的最长的错误消息跟踪之一,核心是:

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) ]]
Run Code Online (Sandbox Code Playgroud)

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

3.纵观TensorFlow文档似乎有我需要的只是等待功能:tf.make_ndarray创建从张量numpy的ndarray。

所以我试过:

def custom_loss(y_true, y_pred):
    npa = tf.make_ndarray(y_pred)
    ...
Run Code Online (Sandbox Code Playgroud)

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

查看 TF 文档中的示例,他们在 proto_tensor 上使用它,因此我尝试首先转换为 proto:

def custom_loss(y_true, y_pred):
    proto_tensor = tf.make_tensor_proto(y_pred)
    npa = tf.make_ndarray(proto_tensor)
    ...
Run Code Online (Sandbox Code Playgroud)

但已经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)
    ...
Run Code Online (Sandbox Code Playgroud)

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

run*_*run 6

y_pred.numpy()在 TF 2 中工作,但AttributeError: 'Tensor' object has no attribute 'make_ndarray表明您的代码的某些部分不是在 Eager 模式下运行的,否则您将没有Tensor对象而是EagerTensor.

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

tf.config.experimental_run_functions_eagerly(True)
Run Code Online (Sandbox Code Playgroud)

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

model.compile(..., run_eagerly=True, ...)
Run Code Online (Sandbox Code Playgroud)

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