将TensorFlow张量转换为Numpy数组

问题描述:

我正在尝试在TensorFlow 2.3.0中编写自定义损失函数.要计算损失,我需要将y_pred参数转换为numpy数组.但是,即使似乎有TensorFlow函数也无法将其从<class 'tensorflow.python.framework.ops.Tensor'>转换为numpy数组.

I am trying to write a custom loss function in TensorFlow 2.3.0. To calculate the loss, I need the y_pred parameter to be converted to a numpy array. However, I can't find a way to convert it from <class 'tensorflow.python.framework.ops.Tensor'> to numpy array, even though there seem to TensorFlow functions to do so.

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'>

gives the error message: AttributeError: 'Tensor' object has no attribute 'make_ndarray after printing the type of the y_pred parameter: <class 'tensorflow.python.framework.ops.Tensor'>

寻找解决方案时,我发现这似乎是一个普遍的问题,并且有一些建议,但到目前为止它们对我没有用:

Looking for a solution I found this seems to be a common issue and there a couple of suggestions, but they did not work for me so far:

1. " ...因此只需在Tensor对象上调用.numpy().":如何转换张量到TensorFlow中的一个numpy数组中?

1. " ... so just call .numpy() on the Tensor object.": 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()将张量转换为数组":

2. "Use tensorflow.Tensor.eval() to convert a tensor to an array": 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())
    ...

为我提供了我见过的最长的错误消息之一,其核心是:

giving me one of the longest trace of error messages I ever have seen with the core being:

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兼容性函数感觉不太适应未来,因此无论如何我都不太喜欢这种方法.

also having to call TensorFlow Compatibility Functions from Version 1.x does not feel very future-proof, so I do not like this approach too much anyhow.

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

3. Looking at the TensorFlow Docs there seemed to be the function I needed just waiting: tf.make_ndarray Create a numpy ndarray from a tensor.

所以我尝试了:

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

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

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

Looking at the example in the TF documentation they use this on a proto_tensor, so I tried converting to a proto first:

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.

也尝试首先创建一个常数张量会产生相同的错误:

Also trying to make a const tensor first gives the same error:

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)
    ...

关于此的更多文章,但似乎它们都回到了这三个基本概念上.期待您的建议!

There are many more posts around this but it seems they are all coming back to these three basic ideas. Looking forward to your suggestions!

y_pred.numpy()可在TF 2中使用,但AttributeError: 'Tensor' object has no attribute 'make_ndarray指示您的代码中有某些部分未在Eager模式下运行,否则您将无法运行一个Tensor对象,但是一个EagerTensor.

y_pred.numpy() works in TF 2 but AttributeError: 'Tensor' object has no attribute 'make_ndarray indicates that there are parts of your code that you are not running in Eager mode as you would otherwise not have a Tensor object but an EagerTensor.

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

To enable Eager Mode, put this at the beginning of your code before anything in the graph is built:

tf.config.experimental_run_functions_eagerly(True)

第二,在编译模型时,添加以下参数:

Second, when you compile your model, add this parameter:

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

现在,您正在急切模式"下执行,并且所有变量实际上都包含可以打印和使用的值.请注意,切换到急切"模式可能需要对代码进行其他调整(有关概述,请参见此处 ).

Now you're executing in Eager Mode and all variables actually hold values that you can both print and work with. Be aware that switching to Eager mode might require additional adjustments to your code (see here for an overview).