AttributeError:图层没有入站节点,或者AttributeError:图层从未被调用
我需要一种方法来获取TensorFlow中任何类型的层(即Dense,Conv2D等)的输出张量的形状。根据文档,有output_shape
可以解决问题的属性。但是,每次访问它都会得到AttributedError
。
这是显示问题的代码示例:
import numpy as np
import tensorflow as tf
x = np.arange(0, 8, dtype=np.float32).reshape((1, 8))
x = tf.constant(value=x, dtype=tf.float32, verify_shape=True)
dense = tf.layers.Dense(units=2)
out = dense(x)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
res = sess.run(fetches=out)
print(res)
print(dense.output_shape)
该print(dense.output_shape)
语句将产生错误消息:
AttributeError: The layer has never been called and thus has no defined output shape.
或print(dense.output)
将产生:
AttributeError('Layer ' + self.name + ' has no inbound nodes.')
AttributeError: Layer dense_1 has no inbound nodes.
有什么办法可以解决该错误?
PS:
我知道在上面的示例中,我可以通过获得输出张量的形状out.get_shape()
。但是我想知道为什么output_shape
财产不起作用以及如何解决?
-
TL; DR
我该如何解决? 定义输入层:
x = tf.keras.layers.Input(tensor=tf.ones(shape=(1, 8))) dense = tf.layers.Dense(units=2) out = dense(x) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) res = sess.run(fetches=out) print(dense.output_shape) # shape = (1, 2)
根据Keras文档,如果层具有单个 节点
,则可以通过以下方式获取其输入张量,输出张量,输入形状和输出形状:- 层输入
- 层输出
- layer.input_shape
- layer.output_shape
但是在上面的示例中,当我们调用
layer.output_shape
或其他属性时,它引发了看起来有些奇怪的异常。如果深入源代码,则错误是由 入站节点 引起的。
if not self._inbound_nodes: raise AttributeError('The layer has never been called ' 'and thus has no defined output shape.')
这些入站节点是什么?
甲 节点 描述了 两个层之间的连接 。每次将图层连接到一些新输入时,都会将一个节点添加到 layer._inbound_nodes
。每次层的输出被另一层使用时,都会将一个节点添加到 layer._outbound_nodes 。如您在上面看到的,当
self._inbounds_nodes
为None时,它将引发异常。 _ 这意味着,当一个层未连接到输入层或更普遍时,先前的所有层都没有连接到输入层,这self._inbounds_nodes
是空的,这导致了问题_。请注意,
x
在您的示例中,它是张量而不是输入层。请参阅另一个示例以获取更多说明:x = tf.keras.layers.Input(shape=(8,)) dense = tf.layers.Dense(units=2) out = dense(x) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) res = sess.run(fetches=out, feed_dict={x: np.ones(shape=(1, 8))}) print(res) print(res.shape) # shape = (1,2) print(dense.output_shape) # shape = (None,2)
很好,因为定义了输入层。
请注意,在您的示例中,
out
是张量。tf.shape()
函数和.shape
=(get_shape()
)之间的区别是:tf.shape(x)
返回表示x的动态形状的一维整数张量。动态形状仅在图执行时才知道。x.shape
返回表示x静态形状的Python元组。在图形定义时已知的静态形状。在以下网址了解更多关于张量形状的信息:https :
//pgaleone.eu/tensorflow/2018/07/28/understanding-tensorflow-tensors-shape-
static-dynamic/