简体   繁体   中英

TensorFlow: logits and labels must have the same first dimension, got logits shape [120,4] and labels shape [480]

I created an object detection model with hand written digits images, my model has two output layers first is to classification between digits, and second one is to detect/localize the bounding box coordinates of digit.

Output = [Output1, Output2]

Output1 = [0, 1, 2, 3, 4, 5, 6, 7, 8,9] (Dense layer with 10 unit)

Output2 = [x, y, w, h] (Dense layer with 4 units for bounding box coordinates)

I am facing am error regarding logits and label shape, I am not getting why this error is occurring, help me out.

This is the SS of csv file labels

Training image look like

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
import pandas as pd

data = pd.read_csv('train_label.csv')

image = data.iloc[:,0].values
label = data.iloc[:,1:].values

train = tf.data.Dataset.from_tensor_slices((image, label))

def collector(images_file, label):
    image = tf.io.read_file('train\\'+images_file)
    image = tf.image.decode_image(image, channels=1, dtype=tf.float32)

    labels = {'label': label[0], 'coordinates': label[1:]}
    return image, labels

train = train.map(collector).batch(120)

input = tf.keras.Input(shape=(75, 75, 1))
x = tf.keras.layers.Conv2D(32, kernel_size=3, activation='relu')(input)
x = tf.keras.layers.MaxPooling2D((3,3), strides=(1,1), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(64, kernel_size=3, activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((3,3), strides=(1,1), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(128, kernel_size=3, activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((3,3), strides=(1,1), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(128, activation='relu')(x)
output1 = tf.keras.layers.Dense(10, activation='softmax', name="label")(x)
output2 = tf.keras.layers.Dense(4, name="coordinates")(x)

model = tf.keras.Model(inputs=input, outputs=[output1, output2])

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

model.fit(train, batch_size=120, epochs=5, verbose=1)
Epoch 1/5
Traceback (most recent call last):
  File "D:/obj_detection_and_classification/train_model.py", line 42, in <module>
    model.fit(train, batch_size=120, epochs=5, verbose=1)
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1100, in fit
    tmp_logs = self.train_function(iterator)
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\def_function.py", line 828, in __call__
    result = self._call(*args, **kwds)
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\def_function.py", line 888, in _call
    return self._stateless_fn(*args, **kwds)
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\function.py", line 2942, in __call__
    return graph_function._call_flat(
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\function.py", line 1918, in _call_flat
    return self._build_call_outputs(self._inference_function.call(
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\function.py", line 555, in call
    outputs = execute.execute(
  File "C:\Users\Devanshu\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\execute.py", line 59, in quick_execute
    tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
tensorflow.python.framework.errors_impl.InvalidArgumentError:  logits and labels must have the same first dimension, got logits shape [120,4] and labels shape [480]
     [[node sparse_categorical_crossentropy_1/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at D:/obj_detection_and_classification/train_model.py:42) ]] [Op:__inference_train_function_1524]

Function call stack:
train_function

Change the model.compile row from "SparseCategoricalCrossentropy" to "CategoricalCrossentropy" form only. Take into account the different loss function for the coordinates as exemplified in the example code below.

And, in training verify you have correct input shapes for the data, see line model.fit(...) in the example code below:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
import pandas as pd
from tensorflow import keras
from tensorflow.keras import layers

input = tf.keras.Input(shape=(75, 75, 1))
x = tf.keras.layers.Conv2D(32, kernel_size=3, activation='relu')(input)
x = tf.keras.layers.MaxPooling2D((3,3), strides=(1,1), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(64, kernel_size=3, activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((3,3), strides=(1,1), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(128, kernel_size=3, activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((3,3), strides=(1,1), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(128, activation='relu')(x)
output1 = tf.keras.layers.Dense(10, activation='softmax', name="label")(x)
output2 = tf.keras.layers.Dense(4, name="coordinates")(x)

model = tf.keras.Model(inputs=input, outputs=[output1, output2])

model.compile(loss={"label": tf.keras.losses.CategoricalCrossentropy(from_logits=False),"coordinates": tf.keras.losses.MeanSquaredError()},
              optimizer='adam', metrics=['accuracy'])

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

#Let's create a simulated data:
x_train=tf.random.uniform((55,75,75,1))
y_train_label=tf.random.uniform((55,10))
y_train_coordinate=tf.random.uniform((55,4))
y_train=[y_train_label,y_train_coordinate]

model.fit(x_train,{"label":y_train_label, "coordinates":y_train_coordinate},batch_size=120, epochs=5, verbose=1)

#model.fit(train, batch_size=120, epochs=5, verbose=1)

...as a result you should get something like:

在此处输入图像描述

In my case I had the same error("logits and labels must have the same first dimension, got logits shape [100,2] and labels shape [300]"), I made 2 changes:

1.- I changed "SparseCategoricalCrossentropy" for that of "CategoricalCrossentropy"

2.- I changed "tf.keras.layers.Dense(2)" to "tf.keras.layers.Dense(3)"

Basically I think my error was because I was trying to introduce 3 inputs to the model since, initially, the model was only for 2 parameters (I'm just starting in AI).

import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
import numpy as np
import matplotlib.pyplot as plt


carpeta_entrenamiento = './Casos_visiónGráficos/training'
carpeta_validacion = './Casos_visiónGráficos/test'

carp_entren_gatos = './Casos_visiónGráficos/training/cat200x200'  # imagenes de gatos para pruebas
carpeta_entren_perros = './Casos_visiónGráficos/training/wild200x200'# imagenes de zorr para pruebas
carpeta_entren_caballos = './Casos_visiónGráficos/training/horse200x200'
carpeta_val_gatos = './Casos_visiónGráficos/test/catTest'  # imagenes de gatos para validacion
carpeta_val_perros = './Casos_visiónGráficos/test/wildTest' # imagenes de zorr para validacion
carpeta_val_caballos = './Casos_visiónGráficos/test/horseTest'

#Guardar el numero de datos de entrenamiento para cada cosa
num_gatos_entren = len(os.listdir(carp_entren_gatos))
num_perros_entren = len(os.listdir(carpeta_entren_perros))
num_caballos_entren = len(os.listdir(carpeta_entren_caballos))

num_gatos_val = len(os.listdir(carpeta_val_gatos))
num_perros_val = len(os.listdir(carpeta_val_perros))
num_caballos_val = len(os.listdir(carpeta_val_caballos))

total_entrenamiento = num_gatos_entren + num_perros_entren + num_caballos_entren
total_val = num_gatos_val + num_perros_val + num_caballos_val

TAMANO_LOTE = 100
TAMANO_IMG = 200

#Aumento de datos (escala, rotacion, blabla)
print("Realizando aumento de datos")
image_gen_entrenamiento = ImageDataGenerator(
      rescale=1./255,
      rotation_range=40,
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')

#Generacion de datos de entrenamiento FTW
data_gen_entrenamiento = image_gen_entrenamiento.flow_from_directory(batch_size=TAMANO_LOTE,
                                                     directory=carpeta_entrenamiento,
                                                     shuffle=True,
                                                     target_size=(TAMANO_IMG,TAMANO_IMG),
                                                     class_mode='categorical')

#Generacion de datos de validacion
image_gen_val = ImageDataGenerator(rescale=1./255)

data_gen_validacion = image_gen_val.flow_from_directory(batch_size=TAMANO_LOTE,
                                                 directory=carpeta_validacion,
                                                 target_size=(TAMANO_IMG, TAMANO_IMG),
                                                 class_mode='categorical')

#Modelo!
modelo = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(200, 200, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),

    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Conv2D(128, (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(3)
])

#Compilación
modelo.compile(optimizer='adam',
              loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),#se remplazó para 3 entradas SparseCategoricalCrossentropy
              metrics=['accuracy'])


print("Entrenando modelo...");
epocas=60
history = modelo.fit_generator(
    data_gen_entrenamiento,
    steps_per_epoch=int(np.ceil(total_entrenamiento / float(TAMANO_LOTE))),
    epochs=epocas,
    validation_data=data_gen_validacion,
    validation_steps=int(np.ceil(total_val / float(TAMANO_LOTE)))
)

print("Modelo entrenado!");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM