logits and labels must have the same shape error in skincancer image classification

42 Views Asked by At

i am using latest tensorflow package and isic skin cancer image dataset. am completely new to this machine learning and neural nets and was trying to classify images using tensorflow neural networks and keras.

i used the code off from kaggle and changed it a bit up to suit my need for the model however the code is not running and giving me an error that i am not understanding and able to do anything as the vanialla code ran just fine.

How to resolve this error?

this is the function that i have written to make the nerural network. The code is based of from a kaggle project and i have tried to make functions which can be used to easily supply desired parameters and hyper parameters to easily train the models.

#function to select the optimizers
def select_optimizer(optimizer , lr):
    optimizers = {
      "adam": tf.keras.optimizers.Adam(learning_rate=lr),
      "sgd": tf.keras.optimizers.SGD(learning_rate=lr),
      "lion": tf.keras.optimizers.Lion(learning_rate = lr),
      "adafactor": tf.keras.optimizers.Adafactor(learning_rate = lr)}
    return optimizers[optimizer]
   
# final function that compiles the prototype model and gets the model and history    
def proto_model(n , neuron_density , num_classes , acti_functions , final_acti , lr , loss_func , optimize , epochs):
    
    model = Sequential([layers.experimental.preprocessing.Rescaling(1.0 / 255 , input_shape = (img_height , img_width , 3))])
    #initial properties of the layer of the neurons in the first element of the arrays 
    model.add(Conv2D(neuron_density[0] , 3 , padding = "same" , activation = acti_functions[0]))
    model.add(MaxPool2D())
    
    #for loop for the internal desne layer creations
    for i in range(1 , n):
        model.add(Conv2D(neuron_density[i] , 3 , padding = "same" , activation = acti_functions[i]))
        model.add(MaxPool2D())
    
    
    #final output dense layer of the neurons taken from the final layer of the arrays 
    model.add(Flatten())
    model.add(Dense(neuron_density[n-1] , activation = acti_functions[n-1]))
    model.add(Dense(units = num_classes , activation = final_acti))
    
    optimizer_algo = select_optimizer(optimize , lr)
    model.compile(optimizer = optimizer_algo, loss = loss_func,
    metrics = ['accuracy'])
     
    history = model.fit(train_ds , validation_data = val_ds , epochs = epochs)
    
    return model , history

The parameters that i have supplied :-

densities = [32 , 64 , 128 , 256 , 512 , 1024] 
acties = ["relu" , "relu" , "relu" , "relu" , "relu" , "relu"] 
fin_acti = "softmax"
n = 6
classes = 9
learning_rate = 0.001
loss_func = "BinaryCrossentropy"
optimizer = "adam"
epochs = 10
model , history = proto_model(n , densities , classes , acties , fin_acti , learning_rate , loss_func , optimizer , epochs)

The above were the exact parameters that were even in vanilla original code however this time i have made it into arrays and supplied to the function that i have created from the vanilla code.

Error that i have encountered : ValueError: logits and labels must have the same shape, received ((None, 9) vs (None, 1)).

also shows :-

Epoch 1/10
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[25], line 10
      8 optimizer = "adam"
      9 epochs = 10
---> 10 model , history = proto_model(n , densities , classes , acties , fin_acti , learning_rate , loss_func , optimizer , epochs)

Cell In[24], line 33, in proto_model(n, neuron_density, num_classes, acti_functions, final_acti, lr, loss_func, optimize, epochs)
     29 optimizer_algo = select_optimizer(optimize , lr)
     30 model.compile(optimizer = optimizer_algo, loss = loss_func,
     31 metrics = ['accuracy'])
---> 33 history = model.fit(train_ds , validation_data = val_ds , epochs = epochs)
     35 return model , history

File ~\anaconda3\Lib\site-packages\keras\src\utils\traceback_utils.py:70, in filter_traceback.<locals>.error_handler(*args, **kwargs)
     67     filtered_tb = _process_traceback_frames(e.__traceback__)
     68     # To get the full stack trace, call:
     69     # `tf.debugging.disable_traceback_filtering()`
---> 70     raise e.with_traceback(filtered_tb) from None
     71 finally:
     72     del filtered_tb

File C:\Users\SUBHOJ~1\AppData\Local\Temp\__autograph_generated_fileoc8gwbam.py:15, in outer_factory.<locals>.inner_factory.<locals>.tf__train_function(iterator)
     13 try:
     14     do_return = True
---> 15     retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
     16 except:
     17     do_return = False

ValueError: in user code:
1

There are 1 best solutions below

0
Cuartero On

As I said in comments, the error was because the model output (last layer) expected the labels in one hot encoding format. The layer had been defined as a dense layer of size (None, num_classes) (where None refers to the batch size) i.e. the labels should be in one hot encoding format. This format consists of vectors of size num_classes (one entry for each class). Thus, for the class, for example, 6, instead of having a number representing it, we have a vector of size 9 (number of classes) where position 5 (label 6) contains a 1 while the others contain 0: [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]. In reality, what this format represents is a vector where each index corresponds to the probability of each of the classes.

Tensorflow allows encoding labels in this format within the image_dataset_from_directory function using the input variable label_mode = "categorical".

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
       ...
       label_mode = "categorical"
)