Tensorflow: Logits e Label devem ter o mesmo tamanho

Sep 03 2020

Atualmente, estou tentando um projeto no curso Tensorflow do Google / Udacity usando um conjunto de dados adquirido da seguinte forma:

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

Infelizmente, encontrei o seguinte erro:

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]

Eu olhei para outros posts, mas ainda parecia um pouco complicado de descobrir. Meu pensamento inicial é que posso estar usando a função de perda incorreta.

Aqui está o código com problemas:

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

O tamanho do lote é 100 e a dimensão de entrada é 150.150 O resumo é o seguinte: Modelo: "sequential_4"


Nº do parâmetro da forma de saída da camada (tipo)

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


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


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


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


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


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


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


flatten_4 (Flatten) (Nenhum, 18496) 0


dense_8 (Denso) (Nenhum, 512) 9470464


dense_9 (Denso) (Nenhum, 5) 2565

Params totais: 9.496.613 Params treináveis: 9.496.613 Params não treináveis: 0

Alguma ideia do que pode estar errado?

Respostas

1 MarcoCerliani Sep 03 2020 at 03:59

preste atenção ao class_mode em seu gerador

'int': significa que os rótulos são codificados como inteiros (por exemplo, para perda sparse_categorical_crossentropy). 'categórico' significa que os rótulos são codificados como um vetor categórico (por exemplo, para perda categorical_crossentropy). 'binário' significa que os rótulos (pode haver apenas 2) são codificados como escalares float32 com valores 0 ou 1 (por exemplo, para binary_crossentropy). Nenhum (sem rótulos).

parece que você precisa de 'int' em vez de 'binário' para o trem e o gerador de validação