AttributeError: Layer has no inbound nodes, or AttributeError: The layer has never been called

后端 未结 1 2117
北荒
北荒 2020-12-06 13:58

I need a way to get the shape of output tensor for any type of layer (i.e. Dense, Conv2D, etc) in TensorFlow. According to documentation, there is output_shape

相关标签:
1条回答
  • 2020-12-06 14:44

    TL;DR

    How can I fix it? Define an input layer:

    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)
    

    Accordint to Keras documentation, if a layer has a single node, you can get its input tensor, output tensor, input shape and output shape via:

    • layer.input
    • layer.output
    • layer.input_shape
    • layer.output_shape

    But in the above example, when we call layer.output_shape or other attributes, it throws exceptions that seem a bit strange.

    If we go deep in the source code, the error caused by inbound nodes.

    if not self._inbound_nodes:
      raise AttributeError('The layer has never been called '
                           'and thus has no defined output shape.')
    

    What these inbound nodes are?

    A Node describes the connectivity between two layers. Each time a layer is connected to some new input, a node is added to layer._inbound_nodes. Each time the output of a layer is used by another layer, a node is added to layer._outbound_nodes.

    As you can see in the above, when self._inbounds_nodes is None it throws an exception. This means when a layer is not connected to the input layer or more generally, none of the previous layers are connected to an input layer, self._inbounds_nodes is empty which caused the problem.

    Notice that x in your example, is a tensor and not an input layer. See another example for more clarification:

    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)
    

    It is perfectly fine because the input layer is defined.


    Note that, in your example, out is a tensor. The difference between the tf.shape() function and the .shape =(get_shape()) is:

    tf.shape(x) returns a 1-D integer tensor representing the dynamic shape of x. A dynamic shape will be known only at graph execution time.

    x.shape returns a Python tuple representing the static shape of x. A static shape, known at graph definition time.

    Read more about tensor shape at: https://pgaleone.eu/tensorflow/2018/07/28/understanding-tensorflow-tensors-shape-static-dynamic/

    0 讨论(0)
提交回复
热议问题