it-swarm.com.de

Kann die Länge von Shape mit unbekanntem Rang nicht annehmen

Ich habe ein neuronales Netzwerk aus einem tf.data-Datengenerator und einem tf.keras-Modell wie folgt (eine vereinfachte Version, weil es zu lang wäre):

dataset = ...

Ein tf.data.Dataset-Objekt, das mit der next_x-Methode den get_next für den x_train-Iterator aufruft, und für die next_y-Methode den get_next für den y_train-Iterator. Jedes Label ist ein (1, 67)-Array in einer Hot-Form.

Schichten:

input_tensor = tf.keras.layers.Input(shape=(240, 240, 3))  # dim of x
output = tf.keras.layers.Flatten()(input_tensor)
output= tf.keras.Dense(67, activation='softmax')(output)  # 67 is the number of classes

Modell:

model = tf.keras.models.Model(inputs=input_tensor, outputs=prediction)
model.compile(optimizer=tf.train.AdamOptimizer(), loss=tf.losses.softmax_cross_entropy, metrics=['accuracy'])
model.fit_generator(gen(dataset.next_x(), dataset.next_y()), steps_per_epochs=100)

gen ist wie folgt definiert:

def gen(x, y):
    while True:
        yield(x, y)

Mein Problem ist, wenn ich versuche, es auszuführen, bekomme ich einen Fehler im model.fit-Teil:

ValueError: Cannot take the length of Shape with unknown rank.

Irgendwelche Ideen werden geschätzt!

7
Cna

Könnten Sie eine längere Stack-Spur posten? Ich denke, Ihr Problem könnte mit diesem kürzlich aufgetretenen Tensorflow-Problem zusammenhängen:

https://github.com/tensorflow/tensorflow/issues/24520

Es gibt auch eine einfache PR, die das Problem behebt (noch nicht zusammengeführt). Probieren Sie es vielleicht selbst aus.

EDIT

Hier ist der PR: Open tensorflow/python/keras/engine/training_utils.py

folgendes ersetzen (Zeile 232):

  if (x.shape is not None
      and len(x.shape) == 1

mit diesem:

  if tensor_util.is_tensor(x):
    x_shape_ndims = x.shape.ndims if x.shape is not None else None
  else:
    x_shape_ndims = len(x.shape)

  if (x_shape_ndims == 1
1
Ciprian

Ich habe herausgefunden, was falsch war. Eigentlich muss ich run nächste Charge in einem tf.Session geben, bevor ich es gebe . So funktioniert es (ich schreibe nicht den Rest des Codes, da er gleich bleibt)

model.fit_generator(gen(), steps_per_epochs=100)

def gen():
    with tf.Session() as sess:
        next_x = dataset.next_x()
        next_y = dataset.next_y()
        while True:
            x_batch = sess.run(next_x)
            y_batch = sess.run(next_y)
            yield x_batch, y_batch
0
Cna

Für das Problem Cannot take the length of Shape with unknown rank Habe ich dank der obigen Antwort das Problem durch Hinzufügen von output_shape Zu from_generator gemäß diesem Issue-Kommentar gelöst.

In meinem Fall habe ich Dataset.from_generator Für die Datensatz-Pipeline verwendet.

Vor:

Dataset.from_generator(_generator_factory, 
                       output_types=(tf.float32, tf.int8))

Arbeitscode für mich:

Dataset.from_generator(_generator_factory, 
                       output_types = (tf.float32, tf.int8),
                       output_shapes = (
                           tf.TensorShape([2, 224, 224, 3]), 
                           tf.TensorShape([1,])
                       ))

Ebenfalls gefunden in diesem offiziellen Datensatz von tensorflow ist Folgendes angegeben:

...

Das Argument output_shapes Ist nicht erforderlich, wird jedoch dringend empfohlen, da viele Tensorflow-Operationen keine Tensoren mit unbekanntem Rang unterstützen. Wenn die Länge einer bestimmten Achse unbekannt oder variabel ist, setzen Sie sie in den output_shapes auf None.

...

0
Max