AttributeError: 层没有入站节点,或 AttributeError: 该层从未被调用过 [英] AttributeError: Layer has no inbound nodes, or AttributeError: The layer has never been called

查看:22
本文介绍了AttributeError: 层没有入站节点,或 AttributeError: 该层从未被调用过的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种方法来获取 TensorFlow 中任何类型层(即 Dense、Conv2D 等)的输出张量的形状.根据文档,有 output_shape 属性可以解决这个问题.但是,每次我访问它时,我都会收到 AttributedError.

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 property which solves the problem. However every time I access it I get AttributedError.

这是显示问题的代码示例:

Here is code sample showing the problem:

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) 语句会产生错误信息:

The print(dense.output_shape) statement will produce error message:

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.

有什么办法可以修复这个错误吗?

Is there any way to fix the error?

附注:我知道在上面的例子中,我可以通过 out.get_shape() 获得输出张量的形状.但是我想知道为什么 output_shape 属性不起作用以及如何修复它?

P.S.: I know that in example above I can get shape of output tensor via out.get_shape(). However I want to know why output_shape property doesn't work and how I can fix it?

推荐答案

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 文档,如果一个层有一个 节点,您可以通过以下方式获取其输入张量、输出张量、输入形状和输出形状:


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

但是在上面的例子中,当我们调用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.')

这些入站节点 是?

节点描述了两层之间的连接.每次将一个层连接到某个新输入时,一个节点被添加到layer._inbound_nodes.每次一层的输出被另一层使用时,一个节点被添加到layer._outbound_nodes.

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.

如上所示,当 self._inbounds_nodes 为 None 时,它​​会引发异常.这意味着当一个层没有连接到输入层或更一般地,前面的层都没有连接到输入层时,self._inbounds_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.

请注意,示例中的 x 是张量而不是输入层.请参阅另一个示例以获得更多说明:

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.

请注意,在您的示例中,out 是一个张量.tf.shape() 函数和 .shape =(get_shape()) 的区别在于:

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) 返回一个表示动态的一维整数张量x 的形状.只有在图形执行时才能知道动态形状.

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 返回一个表示静态的 Python 元组x 的形状.静态形状,在图形定义时已知.

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

在以下位置阅读有关张量形状的更多信息:https://pgaleone.eu/tensorflow/2018/07/28/understanding-tensorflow-tensors-shape-static-dynamic/

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

这篇关于AttributeError: 层没有入站节点,或 AttributeError: 该层从未被调用过的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆