Tensorflow: Logits und Label müssen gleich groß sein

Sep 03 2020

Ich versuche derzeit ein Projekt im Tensorflow-Kurs von Google / Udacity mit einem Datensatz, der wie folgt erfasst wurde:

_URL = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"

zip_file = tf.keras.utils.get_file(origin=_URL,
                                   fname="flower_photos.tgz",
                                   extract=True)

Leider bin ich auf folgenden Fehler gestoßen:

InvalidArgumentError:  logits and labels must have the same first dimension, got logits shape [100,5] and labels shape [500]
     [[node sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at <ipython-input-43-02964d57939c>:8) ]] [Op:__inference_test_function_3591]

Ich habe mir andere Beiträge angesehen, aber es schien immer noch etwas schwierig, das herauszufinden. Mein erster Gedanke ist, dass ich möglicherweise die falsche Verlustfunktion verwende.

Hier ist der Code, der auf Probleme stößt:

image_gen = ImageDataGenerator(rescale = 1./255, horizontal_flip=True, zoom_range=0.5, rotation_range=45, width_shift_range=0.15, height_shift_range=0.15)

train_data_gen = image_gen.flow_from_directory(batch_size=BATCH_SIZE, directory = train_dir, shuffle=True, target_size=(IMG_SHAPE,IMG_SHAPE),class_mode='binary')

image_gen = ImageDataGenerator(rescale = 1./255)

val_data_gen = image_gen.flow_from_directory(batch_size=BATCH_SIZE, directory = val_dir, shuffle=True, target_size=(IMG_SHAPE,IMG_SHAPE))


model = tf.keras.models.Sequential([
                                    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150,150,3)),
                                    tf.keras.layers.MaxPooling2D(2,2),
                                    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
                                    tf.keras.layers.MaxPooling2D(2,2),
                                    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
                                    tf.keras.layers.MaxPooling2D(2,2),
                                    tf.keras.layers.Dropout(0.5),
                                    tf.keras.layers.Flatten(),
                                    tf.keras.layers.Dense(512, activation='relu'),
                                    tf.keras.layers.Dense(5),
                                    
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
model.summary()

Die Stapelgröße beträgt 100 und die Eingabedimension 150.150. Die Zusammenfassung lautet wie folgt: Modell: "sequential_4"


Ebene (Typ) Ausgabeform Parameter #

conv2d_12 (Conv2D) (Keine, 148, 148, 16) 448


max_pooling2d_12 (MaxPooling (Keine, 74, 74, 16) 0


conv2d_13 (Conv2D) (Keine, 72, 72, 32) 4640


max_pooling2d_13 (MaxPooling (Keine, 36, 36, 32) 0


conv2d_14 (Conv2D) (Keine, 34, 34, 64) 18496


max_pooling2d_14 (MaxPooling (Keine, 17, 17, 64) 0


dropout_4 (Dropout) (Keine, 17, 17, 64) 0


flatten_4 (Flatten) (Keine, 18496) 0


dicht_8 (dicht) (keine, 512) 9470464


dicht_9 (dicht) (keine, 5) 2565

Gesamtzahl der Parameter: 9.496.613 Trainierbare Parameter: 9.496.613 Nicht trainierbare Parameter: 0

Irgendwelche Gedanken darüber, was falsch sein könnte?

Antworten

1 MarcoCerliani Sep 03 2020 at 03:59

Achten Sie auf class_mode in Ihrem Generator

'int': bedeutet, dass die Beschriftungen als Ganzzahlen codiert sind (z. B. für den Verlust von sparse_categorical_crossentropy). 'kategorial' bedeutet, dass die Beschriftungen als kategorialer Vektor codiert sind (z. B. für den Verlust von kategorialer Kreuzentropie). 'binär' bedeutet, dass die Beschriftungen (es können nur 2 sein) als float32-Skalare mit den Werten 0 oder 1 codiert sind (z. B. für binary_crossentropy). Keine (keine Etiketten).

Es scheint, dass Sie sowohl für den Zug- als auch für den Validierungsgenerator 'int' anstelle von 'binary' benötigen