The Keras functional API allows for the creation of models with multiple inputs or outputs. This allows for more complex architectures, such as models with multiple branches that converge towards a common output, or models with multiple different outputs. Here are the steps to create a multi-input or multi-output model using the functional API:
1. Import the necessary modules:
from keras.layers import Input, Dense, Concatenate
from keras.models import Model
2. Define the input layers by instantiating the ‘Input‘ class, which creates a Keras tensor:
input_1 = Input(shape=(input_dim_1,))
input_2 = Input(shape=(input_dim_2,))
Each input should be given a unique name.
3. Define the model’s layers as standalone objects, and then call them on the input tensors:
dense_1 = Dense(hidden_dim_1, activation='relu')
dense_2 = Dense(hidden_dim_2, activation='relu')
dense_3 = Dense(output_dim, activation='softmax')
hidden_1 = dense_1(input_1)
hidden_2 = dense_2(input_2)
merged = Concatenate()([hidden_1, hidden_2])
outputs = dense_3(merged)
Note that ‘Concatenate‘ is used to merge the outputs from the two hidden layers. Also, ‘output_dim‘ corresponds to the number of classes in our classification problem.
4. Define the model using the input tensors as inputs and the output tensors as outputs:
model = Model(inputs=[input_1, input_2], outputs=outputs)
Now, we can compile and train the model, as we would do for any other Keras model. The ‘fit‘ function expects a list of input arrays, one for each input, and yields a list of output arrays, one for each output.
Here is an example of a multi-output model, which predicts both the species and the size of flowers based on their images and metadata:
input_img = Input(shape=(img_width, img_height, 3), name='img_input')
input_meta = Input(shape=(metadata_dim,), name='meta_input')
x = Conv2D(32, (3,3), activation='relu')(input_img)
x = MaxPooling2D()(x)
x = Conv2D(64, (3,3), activation='relu')(x)
x = MaxPooling2D()(x)
x = Conv2D(128, (3,3), activation='relu')(x)
x = MaxPooling2D()(x)
x = Flatten()(x)
x = Dense(128, activation='relu')(x)
merged = Concatenate()([x, input_meta])
out_species = Dense(num_species, activation='softmax', name='species_output')(x)
out_size = Dense(num_sizes, activation='softmax', name='size_output')(merged)
model = Model(inputs=[input_img, input_meta], outputs=[out_species, out_size])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([train_images, train_metadata], [train_species, train_sizes], epochs=10, batch_size=32, validation_data=([val_images, val_metadata], [val_species, val_sizes]))
In this example, ‘Conv2D‘ and ‘MaxPooling2D‘ layers are used to extract features from the input images, and the metadata is concatenated with the flattened feature map. The final model has two outputs: ‘out_species‘ and ‘out_size‘.