pythontensorflowkerasdeep-learningresnet

ValueError: Inputs have incompatible shapes. Received shapes (25, 25, 64) and (75, 75, 64)


I am trying to build Resnet model for face recognition but I keep getting this error I tried searching on StackOverflow but nothing works properly I WOULD APPRECIATE THE HELP

Traceback (most recent call last):
  File "c:\Users\mahmo\Downloads\test\FaceRecognitionModel.py", line 84, in <module>
    layer1 = resnet(visible,64,3)
  File "c:\Users\mahmo\Downloads\test\FaceRecognitionModel.py", line 78, in resnet
    layer_out = Add()([conv3, data])
  File "C:\Users\mahmo\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\mahmo\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\src\layers\merging\base_merge.py", line 74, in _compute_elemwise_op_output_shape
    raise ValueError(
ValueError: Inputs have incompatible shapes. Received shapes (25, 25, 64) and (75, 75, 64)

My code is as follows for the model and layers used

bnEps = 2e-5
bnMom = 0.9
chanDim = 1

def resnet(layer_in, n_filters,s):
    data = layer_in
    stride = (s,s)
    
    #1st Convolutional Layer
    merge_input = Conv2D(n_filters, (1,1),strides = (s,s))(layer_in)        
    bn2 = BatchNormalization(axis = chanDim,epsilon=bnEps,momentum = bnMom)(merge_input)
    act2 = Activation('relu')(bn2)
    
    #2nd Convolutional Layer
    conv2 = Conv2D(n_filters, (3,3),strides= stride,use_bias = False, padding='same', kernel_initializer='he_normal')(act2)  
    bn3 = BatchNormalization(axis = chanDim,epsilon=bnEps,momentum = bnMom)(conv2)
    act3 = Activation('relu')(bn3)
    
    #3rd Convolutional layer
    conv3 = Conv2D(n_filters, (1,1),use_bias = False, kernel_initializer='he_normal')(act3)  
    
    
    data = Conv2D(n_filters,(1,1),padding = 'valid',strides = (s,s))(data) # Adjusting the input size according to 3rd convolutional layer
    data = BatchNormalization()(data)  
    # add filters, assumes filters/channels last
    layer_out = Add()([conv3, data])
    layer_out = Activation('relu')(layer_out)
    return layer_out

#define model input
visible = Input(shape=(224,224, 3))
layer1 = resnet(visible,64,3)
layer2 = resnet(layer1,128,1)
layer4 = resnet(layer2,256,1)
layer5 = resnet(layer4,256,2)
layer6 = resnet(layer5,512,2)
layer7 = resnet(layer6,512,2)
layer8 = resnet(layer7,1024,2)
layert = Dropout(0.5)(layer8)
layer9 = resnet(layert,2048,2)
layert2 = Dropout(0.5)(layer9)
layer10 = resnet(layert2,4096,2)
x = GlobalAveragePooling2D()(layer10)
x = Dropout(0.7)(x)
#flatten = Flatten()(layer9)
den = Dense(2048,activation = 'sigmoid')(x)
final = Dense(5, activation="softmax")(den)
#create model
model = Model(inputs=visible, outputs=final)

So my questions are: How to match the shapes, and why this does not work? Is it the code or something else

New error

Traceback (most recent call last):
  File "c:\Users\mahmo\Downloads\test\FaceRecognitionModel.py", line 130, in <module>
    history = model.fit(X_train,y_train,steps_per_epoch = 20,shuffle = True,epochs = 65)
  File "C:\Users\mahmo\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\mahmo\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\src\backend.py", line 5560, in categorical_crossentropy
    target.shape.assert_is_compatible_with(output.shape)
ValueError: Shapes (1, 1) and (1, 5) are incompatible

the rest of the code that could have the error

#compiling model
initial_lr = 1e-5
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
    initial_lr,
    decay_steps=10000,  # You can adjust this value based on your dataset size and batch size
    decay_rate=0.9      # You can adjust this decay rate as well
)

# Use the learning rate schedule as the optimizer
optimizer = tf.keras.optimizers.RMSprop(learning_rate=lr_schedule)
model.compile(
    loss='categorical_crossentropy',
    optimizer=optimizer,
    metrics=['accuracy'],
    run_eagerly=True
)
# summarize model
model.summary()

history = model.fit(X_train,y_train,steps_per_epoch = 20,shuffle = True,epochs = 65)
score = model.evaluate(X_train, y_train ,verbose=1)
print('Test Loss:', score[0])
print('Test accuracy:', score[1])

Solution

  • The problem is that you reduce the input dimension with the stride, and padding doesn't counter that. So both your merge_input Conv2D layer as well as your data Conv2D layer reduces your 224x224 input to 75x75 (as you can see as the second shape in your error message). But then the conv2d layer further reduces the 75x75 output from bn2 to 25x25 with stride (3x3).
    To solve that, you could either remove the stride from either the first convolution merge_inputor the second convolution conv2d, or reduce data to 25x25. Looking into resnet building blocks like this one, you can see that it uses only one stride 2 on both the normal connection and the skip connection.

    Edit: For your new error, looks like your target data is only one number, most likely label encoded. Look here. It should work when you switch to sparse categorical cross-entropy, or one-hot encode your target data. But without knowing how your data looks it is just a guess.