I have 2 models that I want to implement early-fusion with and to do this, I need to first concatenate their features. However, I get the error in the title at the Concatenate part and, even after searching in other questions/forums, I can’t seem to find how I can fix it. Are there any recommendations you can give me? Unfortunately I can’t share the image data nor give access to it.
The 1st model is a Places-365, available https://github.com/GKalliatakis/Keras-VGG16-places365 :
def VGG16_Places365(weights='places', input_shape=None, pooling=None, classes=365): img_input = Input(shape=input_shape) # Block 1 x = Conv2D(filters=64, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block1_conv1_365')(img_input) x = Conv2D(filters=64, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block1_conv2_365')(x) x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name="block1_pool_365", padding='valid')(x) # Block 2 x = Conv2D(filters=128, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block2_conv1_365')(x) x = Conv2D(filters=128, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block2_conv2_365')(x) x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name="block2_pool_365", padding='valid')(x) # Block 3 x = Conv2D(filters=256, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block3_conv1_365')(x) x = Conv2D(filters=256, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block3_conv2_365')(x) x = Conv2D(filters=256, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block3_conv3_365')(x) x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name="block3_pool_365", padding='valid')(x) # Block 4 x = Conv2D(filters=512, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block4_conv1_365')(x) x = Conv2D(filters=512, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block4_conv2_365')(x) x = Conv2D(filters=512, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block4_conv3_365')(x) x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name="block4_pool_365", padding='valid')(x) # Block 5 x = Conv2D(filters=512, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block5_conv1_365')(x) x = Conv2D(filters=512, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block5_conv2_365')(x) x = Conv2D(filters=512, kernel_size=3, strides=(1, 1), padding='same', kernel_regularizer=l2(0.0002), activation='relu', name='block5_conv3_365')(x) x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name="block5_pool_365", padding='valid')(x) inputs = img_input # Create model. model = Model(inputs, x, name='vgg16-places365') # load weights weights_path = get_file('vgg16-places365_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models') model.load_weights(weights_path) return model
The 2nd model is a VGG19 trained model with 224x224 RGB images, which is trained, saved and later on, accessed. This is how I built and designed it.
models_input_shape = (224, 224, 3) num_classes = len(pd.unique(train_dataset['T1'])) base_model = VGG19(weights='imagenet', include_top=False, input_shape=models_input_shape) for layer in base_model.layers: layer.trainable = False model = Sequential() model.add(base_model) model.add(Flatten()) model.add(Dense(256, activation='relu')) model.add(Dense(128, activation='relu')) model.add(Dense(64, activation='relu')) model.add(Dense(num_classes, activation='sigmoid')) model.compile(loss=losses.BinaryCrossentropy(), optimizer=Adam(learning_rate=0.0001), metrics= ['accuracy', Precision(), Recall()]) epochs = 2 batch_size = 32 steps_per_epoch = train_generator.n // train_generator.batch_size #validation_steps = valid_generator.n // batch_size history = model.fit( train_generator, steps_per_epoch=steps_per_epoch, epochs=epochs # ,validation_data=valid_generator, # validation_steps=validation_steps )
What I used to call the models and obtain their features and finally, get the error concatenating them:
model_vgg16_places365 = VGG16_Places365(weights='places', input_shape=(224, 224, 3)) model_365_features = model_vgg16_places365(Input(shape=(224, 224 ,3))) vgg19_model_location = 'vgg19_trained.keras' vgg19_model = load_model(vgg19_model_location) vgg19_model_features = vgg19_model(Input(shape=(224,224,3))) merged_features = Concatenate()([model_365_features, vgg19_model_features])