AttributeError:图层没有入站节点,或者AttributeError:图层从未被调用

发布于 2021-01-29 18:05:50

我需要一种方法来获取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财产不起作用以及如何解决?

关注者
0
被浏览
186
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    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/



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看