AttributeError: la capa no tiene nodos de entrada, o AttributeError: la capa nunca se ha llamado

Necesito una forma de obtener la forma del tensor de salida para cualquier tipo de capa (es decir, Dense, Conv2D, etc.) en TensorFlow. Según la documentación, hay output_shape propiedad output_shape que resuelve el problema. Sin embargo, cada vez que accedo a él obtengo AttributedError .

Aquí está el ejemplo del código que muestra el problema:

 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) 

La statement print(dense.output_shape) producirá un mensaje de error:

 AttributeError: The layer has never been called and thus has no defined output shape. 

o print(dense.output) producirá:

 AttributeError('Layer ' + self.name + ' has no inbound nodes.') AttributeError: Layer dense_1 has no inbound nodes. 

¿Hay alguna manera de corregir el error?

PD: Sé que en el ejemplo anterior puedo obtener la forma del tensor de salida a través de out.get_shape() . Sin embargo, quiero saber por output_shape propiedad output_shape no funciona y cómo puedo solucionarlo.

TL; DR

¿Cómo puedo arreglarlo? Definir una capa de entrada:

 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) 

De acuerdo con la documentación de Keras, si una capa tiene un solo nodo , puede obtener su tensor de entrada, tensor de salida, forma de entrada y forma de salida a través de:

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

Pero en el ejemplo anterior, cuando llamamos layer.output_shape u otros atributos, layer.output_shape excepciones que parecen un poco extrañas.

Si profundizamos en el código fuente , el error es causado por los nodos de entrada .

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

¿Qué son estos nodos entrantes ?

Un nodo describe la conectividad entre dos capas . Cada vez que una capa se conecta a alguna entrada nueva, se agrega un nodo a layer._inbound_nodes . Cada vez que la salida de una capa es utilizada por otra capa, se agrega un nodo a layer._outbound_nodes .

Como puede ver en lo anterior, cuando self._inbounds_nodes es None, se lanza una excepción. Esto significa que cuando una capa no está conectada a la capa de entrada o, más generalmente, ninguna de las capas anteriores está conectada a una capa de entrada, self._inbounds_nodes está vacío, lo que causó el problema.

Tenga en cuenta que x en su ejemplo, es un tensor y no una capa de entrada. Vea otro ejemplo para más aclaraciones:

 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) 

Está perfectamente bien porque la capa de entrada está definida.


Tenga en cuenta que, en su ejemplo, out es un tensor. La diferencia entre la función tf.shape() y la .shape = ( get_shape() ) es:

tf.shape(x) devuelve un tensor entero 1-D que representa la forma dinámica de x. Una forma dinámica se conocerá solo en el tiempo de ejecución del gráfico.

x.shape devuelve una tupla de Python que representa la forma estática de x. Una forma estática, conocida en tiempo de definición gráfica.

Lea más sobre la forma del tensor en: https://pgaleone.eu/tensorflow/2018/07/28/understanding-tensorflow-tensors-shape-static-dynamic/