Tensorflow: i log e l'etichetta devono avere le stesse dimensioni

Sep 03 2020

Attualmente sto tentando un progetto nel corso Tensorflow di Google / Udacity utilizzando un set di dati acquisito come segue:

_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)

Sfortunatamente, ho riscontrato il seguente errore:

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]

Ho guardato altri post, ma mi sembrava ancora un po 'complicato da capire. Il mio pensiero iniziale è che potrei utilizzare la funzione di perdita errata.

Ecco il codice che presenta problemi:

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()

La dimensione del batch è 100 e la dimensione di input è 150,150 Il riepilogo è il seguente: Modello: "sequential_4"


Layer (tipo) Output Shape Param #

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


max_pool2d_12 (MaxPooling (Nessuno, 74, 74, 16) 0


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


max_pool2d_13 (MaxPooling (Nessuno, 36, 36, 32) 0


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


max_pool2d_14 (MaxPooling (Nessuno, 17, 17, 64) 0


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


flatten_4 (Flatten) (Nessuno, 18496) 0


dense_8 (Dense) (Nessuno, 512) 9470464


dense_9 (Dense) (Nessuno, 5) 2565

Parametri totali: 9.496.613 Parametri addestrabili: 9.496.613 Parametri non allenabili: 0

Qualche idea su cosa potrebbe esserci di sbagliato?

Risposte

1 MarcoCerliani Sep 03 2020 at 03:59

presta attenzione a class_mode nel tuo generatore

'int': significa che le etichette sono codificate come numeri interi (ad es. per la perdita di sparse_categorical_crossentropy). "categorico" significa che le etichette sono codificate come un vettore categoriale (ad esempio per la perdita categorica_crossentropica). 'binario' significa che le etichette (possono essercene solo 2) sono codificate come scalari float32 con valori 0 o 1 (ad esempio per binary_crossentropy). Nessuno (nessuna etichetta).

sembra che tu abbia bisogno di 'int' invece di 'binary' sia per il treno che per il generatore di convalida