【问题标题】:error in converting tensor to numpy array将张量转换为 numpy 数组时出错
【发布时间】:2020-03-20 02:45:03
【问题描述】:

我正在尝试将作为张量的 input_image 转换为 numpy 数组。按照已经回答的问题here 和其他几个建议使用 input_image.eval() 或等效的 sess.run() 进行此转换的问题,我做了同样的事情,但它会引发错误,并且显然需要 sess.run() 的 feed_dict 值。但由于在这里我不是试图运行依赖于未知值的操作,所以我认为这里不需要 feed_dict,因为我在这里所做的只是转换。

此外,为了检查,我还尝试使用相同的方法转换其正上方的 tf.constant([1,2,3]) 值,尽管其数据类型与 input_image 相同,但它仍成功编译。这是我的代码,它是较大脚本的一部分:

def call(self, x):
    input_image = Input(shape=(None, None, 3))
    print(input_image.shape)
    print(type(tf.constant([1,2,3])))
    print(type(input_image))
    print(type(K.get_session().run(tf.constant([1,2,3]))))
    print(type(K.get_session().run(input_image)))

这是错误:

(?, ?, ?, 3)
<class 'tensorflow.python.framework.ops.Tensor'>
<class 'tensorflow.python.framework.ops.Tensor'>
<class 'numpy.ndarray'>
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/client/session.py", line 1365, in _do_call
    return fn(*args)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/client/session.py", line 1350, in _run_fn
    target_list, run_metadata)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/client/session.py", line 1443, in _call_tf_sessionrun
    run_metadata)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
  (0) Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,?,?,3]
     [[{{node input_1}}]]
     [[input_1/_1051]]
  (1) Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,?,?,3]
     [[{{node input_1}}]]
0 successful operations.
0 derived errors ignored.

我想知道为什么前者会起作用而后者不会。

【问题讨论】:

    标签: python-3.x numpy tensorflow keras tensor


    【解决方案1】:

    没有将符号张量“转换”为 numpy 数组这样的事情,因为后者无法保存与前者相同类型的信息。

    当您使用eval()session.run() 时,您所做的是评估 一个符号表达式以获得数值结果,这是一个numpy 数组,但这不是一个转换。评估表达式可能需要也可能不需要额外的输入数据(这就是 feed_dict 的用途),具体取决于表达式。

    计算常量 (tf.constant) 不需要任何输入数据,但计算其他表达式确实需要输入数据,因此您不能将其“转换”为 numpy 数组。

    【讨论】:

      【解决方案2】:

      只是补充(或详细说明)@MatiasValdenegro 所说的话,

      TensorFlow 遵循称为图形执行(或定义-然后-运行)的方法。换句话说,当你编写一个 TensorFlow 程序时,它定义了一个称为数据流图的东西,它显示了你定义的操作是如何相互关联的。然后根据您所追求的结果执行该图的点点滴滴。

      让我们考虑两个例子。 (我正在切换到一个简单的 TensorFlow 程序而不是 Keras 位,因为它使事情更清楚 - 毕竟 K.get_session() 返回一个 Session 对象)。

      示例 1

      假设你有以下程序。

      import tensorflow as tf
      
      a = tf.placeholder(shape=[2,2], dtype=tf.float32)
      b = tf.constant(1, dtype=tf.float32)
      c = a * b
      
      # Wrong: This is what you're doing essentially when you do sess.run(input_image)
      with tf.Session() as sess:
          print(sess.run(c))
      
      # Right: You need to feed values that c is dependent on
      with tf.Session() as sess:
          print(sess.run(c, feed_dict={a: np.array([[1,2],[2,3]])}))
      
      

      只要结果张量(例如c)依赖于placeholder,您就无法执行它并在不将值提供给所有相关占位符的情况下获得结果。

      示例 2

      当您定义 tf.constant(1) 时,它不依赖于任何东西。换句话说,您不需要feed_dict,可以直接在其上运行eval()sess.run()

      更新:进一步解释为什么需要 input_image 的 feed_dict

      TLDR:您需要一个 feed_dict,因为您生成的 Tensor 是由 Input 层生成的。

      你的input_image 基本上是你通过向Input 层提供一些东西而得到的张量。通常在 Keras 中,您不会接触到内部占位符级别的详细信息。但是您可以通过使用model.fit()model.evaluate() 来做到这一点。通过分析this line可以看到Keras的Input层其实使用了占位符。

      希望我清楚地表明您确实需要向占位符输入一个值,以成功评估Input 层的输出。因为那基本上是一个占位符。

      更新 2:如何向 Input 层提供数据

      因此,您可以通过以下方式将feed_dict 与 Keras Input 层一起使用。无需定义 shape 参数,而是直接将占位符传递给 tensor 参数,这将绕过层中的内部占位符创建。

      from tensorflow.keras.layers import InputLayer
      import numpy as np
      import tensorflow.keras.backend as K
      
      x = tf.placeholder(shape=[None, None, None, 3], dtype=tf.float32)
      input_image = Input(tensor=x)
      arr = np.array([[[[1,1,1]]]])
      print(arr.shape)
      print(K.get_session().run(input_image, feed_dict={x: arr}))
      

      【讨论】:

      • 请看一下上面的代码,我做了一些修改让我的观点更清楚。
      • @conjuring 更新了我的答案。如果您需要对更新答案中的某些内容进行更多说明,请告诉我。
      猜你喜欢
      • 1970-01-01
      • 2020-12-10
      • 2021-10-17
      • 2018-11-28
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      • 1970-01-01
      相关资源
      最近更新 更多