0

I am trying to train a VGG19 model and fine tuning it. My train dataset contains 35990 images and test dataset contains 3720 images. During the training I am experiencing this error : "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"

Can anyone tell me what does it mean and how to solve it?

shape of train1_data : (35990,224,224,3) shape of test1_data : (3720,224,224,3)

Code:

from keras.applications import VGG16
vgg_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))


for layer in vgg_model.layers[:15]:
    layer.trainable = False
# Make sure you have frozen the correct layers
for i, layer in enumerate(vgg_model.layers):
    print(i, layer.name, layer.trainable)

x = vgg_model.output
x = Flatten()(x) 
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x) 
x = Dense(264, activation='relu')(x)
x = Dense(372, activation='softmax')(x) 
transfer_model = Model(inputs=vgg_model.input, outputs=x)

from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import ModelCheckpoint
lr_reduce = ReduceLROnPlateau(monitor='val_accuracy', factor=0.6, patience=8, verbose=1, mode='max', min_lr=5e-5)
checkpoint = ModelCheckpoint('vgg16_finetune.h15', monitor= 'val_accuracy', mode= 'max', save_best_only = True, verbose= 1)

from keras.optimizers import Adam
from tensorflow.keras import layers, models, Model, optimizers
learning_rate= 5e-5
transfer_model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
history = transfer_model.fit(train1_data, batch_size = 15, epochs=5, validation_data=test1_data, callbacks=[lr_reduce,checkpoint])

Here is the full traceback:

ValueError                                Traceback (most recent call last)
<ipython-input-26-8fee2cdfeca2> in <module>
      3 learning_rate= 5e-5
      4 transfer_model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
----> 5 history = transfer_model.fit(train1_data, batch_size = 15, epochs=5, validation_data=test1_data, callbacks=[lr_reduce,checkpoint])

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
   1156         # Prepare validation data.
   1157         do_validation = False
-> 1158         if validation_data:
   1159             do_validation = True
   1160             if len(validation_data) == 2:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Train1_data and Teas1_data

import cv2

train_data = []
label = []

IMG_SIZE=32

minRange = np.array([0,138,67],np.uint8)  
maxRange = np.array([255,173,133],np.uint8) 

def create_testing_data():
   
    for classs in CLASSES:  

        path = os.path.join(DATADIR,classs)  
        class_num = str(CLASSES.index(classs))          
        for img in os.listdir(path):  
                img_array = cv2.imread(os.path.join(path,img))
                new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))    
                new_array=np.array(new_array)
                #new_array=np.array(image)
                #print(np.shape(new_array))
                new_array = new_array.astype('float32')
                new_array /= 255 
                
                train_data.append(new_array)  
                label.append(class_num)
               
         
            
create_testing_data()
print(len(predicted))
print(len(train_data))
np.shape(train_data)

Traceback after adding train and test labels in fit.

from keras.optimizers import Adam
from tensorflow.keras import layers, models, Model, optimizers
learning_rate= 5e-5
transfer_model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
history = transfer_model.fit(train1_data, label, batch_size = 15, epochs=5, validation_data=(test1_data,label1), callbacks=[lr_reduce,checkpoint])




AttributeError                            Traceback (most recent call last)
<ipython-input-41-c850ac7c8c6d> in <module>
      3 learning_rate= 5e-5
      4 transfer_model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
----> 5 history = transfer_model.fit(train1_data, label, batch_size = 15, epochs=5, validation_data=(test1_data,label1), callbacks=[lr_reduce,checkpoint])

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
   1152             sample_weight=sample_weight,
   1153             class_weight=class_weight,
-> 1154             batch_size=batch_size)
   1155 
   1156         # Prepare validation data.

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
    619                 feed_output_shapes,
    620                 check_batch_axis=False,  # Don't enforce the batch size.
--> 621                 exception_prefix='target')
    622 
    623             # Generate sample-wise weight values given the `sample_weight` and

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
     97         data = data.values if data.__class__.__name__ == 'DataFrame' else data
     98         data = [data]
---> 99     data = [standardize_single_array(x) for x in data]
    100 
    101     if len(data) != len(names):

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training_utils.py in <listcomp>(.0)
     97         data = data.values if data.__class__.__name__ == 'DataFrame' else data
     98         data = [data]
---> 99     data = [standardize_single_array(x) for x in data]
    100 
    101     if len(data) != len(names):

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training_utils.py in standardize_single_array(x)
     32                 'Got tensor with shape: %s' % str(shape))
     33         return x
---> 34     elif x.ndim == 1:
     35         x = np.expand_dims(x, 1)
     36     return x

AttributeError: 'str' object has no attribute 'ndim'

Input shape error in dense layer I have removed str from the Train and test label input and converted it into np array. CODE

from keras.optimizers import Adam
from tensorflow.keras import layers, models, Model, optimizers
learning_rate= 5e-5
transfer_model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
history = transfer_model.fit(train1_data, train1_label, batch_size = 15, epochs=5, validation_data=(test1_data,test1_label), callbacks=[lr_reduce,checkpoint])

Traceback

ValueError                                Traceback (most recent call last)
<ipython-input-58-4564124fa363> in <module>
      3 learning_rate= 5e-5
      4 transfer_model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
----> 5 history = transfer_model.fit(train1_data, train1_label, batch_size = 15, epochs=5, validation_data=(test1_data,test1_label), callbacks=[lr_reduce,checkpoint])

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
   1152             sample_weight=sample_weight,
   1153             class_weight=class_weight,
-> 1154             batch_size=batch_size)
   1155 
   1156         # Prepare validation data.

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
    619                 feed_output_shapes,
    620                 check_batch_axis=False,  # Don't enforce the batch size.
--> 621                 exception_prefix='target')
    622 
    623             # Generate sample-wise weight values given the `sample_weight` and

~\Anaconda3\envs\OCR_ENV\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
    133                         ': expected ' + names[i] + ' to have ' +
    134                         str(len(shape)) + ' dimensions, but got array '
--> 135                         'with shape ' + str(data_shape))
    136                 if not check_batch_axis:
    137                     data_shape = data_shape[1:]

ValueError: Error when checking target: expected dense_10 to have 4 dimensions, but got array with shape (35990, 1)

Model Summary

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 25088)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               12845568  
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 264)               135432    
_________________________________________________________________
dense_3 (Dense)              (None, 372)               98580     
=================================================================
Total params: 27,794,268
Trainable params: 20,159,004
Non-trainable params: 7,635,264
  • "Can anyone tell me what does it mean and how to solve it?" What happened when you tried copying and pasting it [into a search engine](https://duckduckgo.com/?q=ValueError%3A+The+truth+value+of+an+array+with+more+than+one+element+is+ambiguous.+Use+a.any()+or+a.all())? – Karl Knechtel Apr 15 '21 at 23:25
  • 1
    How are you creating `train1_data` and `test1_data`? I suspect the issue lies there. You should convert to `tf.data.Dataset` instead of passing the arrays. – Aaron Keesing Apr 15 '21 at 23:26
  • I am reading the images and storing them in an array and converting it into a numpy array. – Aanand Rathore Apr 15 '21 at 23:32
  • I have googled the error and it shows that error might be of some boolean array but I have not used any such and don't know about it. – Aanand Rathore Apr 15 '21 at 23:43
  • @AanandRathore modify the the question by adding train1data, train1label, test1label and test1data – Prakash Dahal Apr 16 '21 at 00:24

2 Answers2

2

According to the docs the fit() method takes a tuple of the form (data, labels) for validation_data whereas you're providing just the NumPy array, so when it checks for validation data the comparison causes that exception. You also haven't provided training labels to fit().

Try converting your last line to

history = transfer_model.fit(train1_data, train1_labels, batch_size = 15, epochs=5, validation_data=(test1_data, test1_labels), callbacks=[lr_reduce,checkpoint])

and see if that avoids the error you're getting.

In general I recommend using tf.data.Dataset for handling datasets and inputting to the fit() function as I mentioned in an answer to another question.

EDIT: As we discussed in the comments, two other things needed to change were using int for labels instead of str:

class_num = CLASSES.index(classs)

and using sparse_categorical_crossentropy loss instead of categorical_crossentropy:

transfer_model.compile(loss="sparse_categorical_crossentropy", optimizer=Adam(lr=learning_rate), metrics=["accuracy"])
Aaron Keesing
  • 1,277
  • 10
  • 18
  • Thank you for the help. I tried giving Training Labels but the error changed to " 'str' object has no attribute 'ndim'". I have added the full traceback of the new error above. Is it occuring because of the input shape and side of the model? How can I solve this? – Aanand Rathore Apr 16 '21 at 00:10
  • I think it's because you have your labels as `str` instead of `int`. Just use `class_num = CLASSES.index(classs)` without `str`. And make the labels into a NumPy array. – Aaron Keesing Apr 16 '21 at 00:31
  • Thank you for help. It worked but the vaule error changed to " ValueError: Error when checking target: expected dense_10 to have 4 dimensions, but got array with shape (35990, 1) ". My array sizes are : train1_data = (35990,225,225,3), test1_data = (3720,224,224,3), train1_label = (35990,), test1_label = (3720,). I have tried giving shape to last dense layer as "x = Dense(372, input_shape=(35990,224,224,3), activation='softmax')(x)" nut it seems not to be working. I have added full traceback above. Is the problem in train1_data and test1_data or train1_label and test1_label? – Aanand Rathore Apr 16 '21 at 07:11
  • What does the output of `transfer_model.summary()` show? This should indicate the expected output shapes of each layer, including your finetuning layers. – Aaron Keesing Apr 16 '21 at 07:38
  • summary shows `dense_12 (Dense) (None, 372) 191862`. I think the problem is that dense layer is expecting an input with 372rows and it is getting one with 1 row? Is it correct? How to correct the mismatch? – Aanand Rathore Apr 16 '21 at 08:50
  • I have posted the whole summary. – Aanand Rathore Apr 16 '21 at 09:37
  • So one thing is to use `sparse_categorical_crossentropy` loss instead of `categorical_crossentropy` because you're giving it a single label instead of a one-hot encoding. But that seems different to the exception you described. I tried your code myself and it worked fine when using `sparse_categorical_crossentropy`, so there must be something odd you're doing with your input/validation data. – Aaron Keesing Apr 16 '21 at 10:05
  • Thank you so much for helping out @ AaronKeesing. `sparse_categorical_crossentropy` solved the problem, didn't need to change train and test array and labels further. – Aanand Rathore Apr 16 '21 at 11:33
  • I have edited my answer to include what we've discussed in the comments. – Aaron Keesing Apr 16 '21 at 13:09
0

you have a final dense layer with 372 nodes. That means you have 372 wide output. Your loss="categorical_crossentropy". So do are your labels 1 hot encoded? Are you trying to do classification? How many classes do you have?

Gerry P
  • 7,662
  • 3
  • 10
  • 20