AttributeError: เลเยอร์ไม่มีโหนดขาเข้า หรือ AttributeError: ไม่เคยมีการเรียกเลเยอร์นี้

ฉันต้องการวิธีรับรูปร่างของเอาท์พุตเทนเซอร์สำหรับเลเยอร์ทุกประเภท (เช่น Dense, Conv2D ฯลฯ) ใน TensorFlow ตามเอกสารประกอบ มีคุณสมบัติ 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.

มีวิธีแก้ไขข้อผิดพลาดหรือไม่?

ป.ล.: ฉันรู้ว่าในตัวอย่างด้านบน ฉันสามารถรับรูปร่างของเอาท์พุตเทนเซอร์ได้ทาง out.get_shape() อย่างไรก็ตาม ฉันต้องการทราบว่าเหตุใดคุณสมบัติ output_shape จึงไม่ทำงาน และฉันจะแก้ไขได้อย่างไร


person NShiny    schedule 15.01.2019    source แหล่งที่มา


คำตอบ (1)


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 หากเลเยอร์มีโหนดเดียว strong> คุณสามารถรับเทนเซอร์อินพุต เทนเซอร์เอาท์พุต รูปร่างอินพุต และรูปร่างเอาท์พุตได้โดย:

  • เลเยอร์อินพุต
  • layer.output
  • 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) ส่งคืนเทนเซอร์จำนวนเต็ม 1 มิติซึ่งแสดงถึงรูปร่างไดนามิกของ x รูปร่างไดนามิกจะทราบได้เฉพาะในเวลาดำเนินการกราฟเท่านั้น

x.shape ส่งคืนสิ่งทูเพิล Python ที่แสดงรูปร่างคงที่ของ x รูปร่างคงที่ ซึ่งทราบ ณ เวลาที่กำหนดกราฟ

อ่านเพิ่มเติมเกี่ยวกับรูปร่างเทนเซอร์ได้ที่: https://pgaleone.eu/tensorflow/2018/07/28/understand-tensorflow-tensors-shape-static-dynamic/

person Amir    schedule 15.01.2019
comment
ฉันไม่แน่ใจว่าคำตอบของคุณช่วยฉันแก้ปัญหาได้ tf.shape ทำงานร่วมกับเทนเซอร์และ tf.layers.Dense ไม่ใช่เทนเซอร์ แต่เป็นเลเยอร์ (เช่นคลาสย่อยของ tf.layers.Layer และ tf.keras.layers.Layer สำหรับแอตทริบิวต์ x.shape ฉันไม่แน่ใจว่าคุณหมายถึงอะไร ตาม เอกสารประกอบ เลเยอร์หนาแน่นไม่มีแอตทริบิวต์ดังกล่าว สำหรับรูปร่างไดนามิกนั้นไม่ใช่กรณีในตัวอย่างของฉัน ถ้าฉันจะเพิ่ม tf.shape(out).eval() ภายใน คำสั่ง with ในตัวอย่างของฉัน มันจะส่งคืน [1 2] ซึ่งหมายความว่าเทนเซอร์เอาต์พุตมีรูปร่างคงที่ - person NShiny; 16.01.2019
comment
ขอบคุณมาก! มันช่วยได้จริงๆ - person NShiny; 19.01.2019