Tensorflow: Logits und Label müssen gleich groß sein
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
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