TensorFlow implements multiple input multiple output model
Sometimes we have more than one input data, and there will be multiple input sources and multiple output sources. In this case, we obviously can't use Sequential, because Sequential can only build linear topology model, which is more suitable for pipeline model. If it is nonlinear topology, Sequential can't be used for complex topology, This is why we need to use the Function API, which will make it easier for us to deal with multiple input and multiple output.
For example, if you want to build a system that sorts custom problem work orders by priority and then transmits the work orders to the correct department, the model will have three inputs:
- Job title (text input),
- The text body of the work order (text entry), and
- Any label added by the user (category input)
This model will have two outputs:
- A priority score between 0 and 1 (scalar Sigmoid output), and
- The Department that should process the work order (Softmax output within the Department).
You can use the functional API to build this model in a few lines of code:
Define input source
There are three data input sources for the model: Title input, body input and label input
# Input source title_input = keras.Input(shape=(None,), name='title') body_input = keras.Input(shape=(None,), name='body') tags_input = keras.Input(shape=(num_tags,), name='tags')
Define relationships between layers
Firstly, the text of the title and body needs to be embedded, and then processed with the long-term and short-term network LSTM. Then, the processed feature vectors are spliced in dimension, and the feature vectors of the three input sources are spliced
title_features = Embedding(num_words, 64)(title_input) body_features = Embedding(num_words, 64)(body_input) title_features = LSTM(128)(title_features) body_features = LSTM(128)(body_features) x = Concatenate(axis=1)([title_features, body_features, tags_input])
Define output source
Two output sources are defined. The first is the prediction priority, so the density is 1. The other is the prediction part, which needs to use softmax, so the dimension is the number of departments
# output source priority_pred = Dense(1, name='priority')(x) department_pred = Dense(num_departments, name='department')(x)
Build model
You just need to specify the input and output of the model, and then keras Model will automatically build a calculation topology according to the relationship between input and output
model = keras.Model( inputs=[title_input, body_input, tags_input], outputs=[priority_pred, department_pred] )
Compilation model
Specify different loss functions for different outputs and assign different loss weights
model.compile( optimizer=keras.optimizers.RMSprop(1e-3), loss={ 'priority': keras.losses.BinaryCrossentropy(from_logits=True), 'department': keras.losses.CategoricalCrossentropy(from_logits=True) }, loss_weights=[1.0, 0.2] )
Define dataset
title_data = np.random.randint(num_words, size=(1280, 10)) body_data = np.random.randint(num_words, size=(1280, 100)) tags_data = np.random.randint(2, size=(1280, num_tags)).astype('float32') priority_targets = np.random.random(size=(1280, 1)) department_targets = np.random.randint(2, size=(1280, num_departments))
Training model
model.fit( {'title': title_data, 'body': body_data, 'tags': tags_data}, {'priority': priority_targets, 'department': department_targets}, epochs=2, batch_size=32 )
Complete code
""" * Created with PyCharm * author: Morkin * date: 2022/1/1 * time: 19:32 * describe: """ import numpy as np from tensorflow import keras from tensorflow.keras.layers import * num_tags = 12 num_words = 10000 num_departments = 4 # Input source title_input = keras.Input(shape=(None,), name='title') body_input = keras.Input(shape=(None,), name='body') tags_input = keras.Input(shape=(num_tags,), name='tags') title_features = Embedding(num_words, 64)(title_input) body_features = Embedding(num_words, 64)(body_input) title_features = LSTM(128)(title_features) body_features = LSTM(128)(body_features) x = Concatenate(axis=1)([title_features, body_features, tags_input]) # output source priority_pred = Dense(1, name='priority')(x) department_pred = Dense(num_departments, name='department')(x) model = keras.Model( inputs=[title_input, body_input, tags_input], outputs=[priority_pred, department_pred] ) keras.utils.plot_model(model, "multi_input_and_output_model.png", show_shapes=True) model.compile( optimizer=keras.optimizers.RMSprop(1e-3), loss={ 'priority': keras.losses.BinaryCrossentropy(from_logits=True), 'department': keras.losses.CategoricalCrossentropy(from_logits=True) }, loss_weights=[1.0, 0.2] ) title_data = np.random.randint(num_words, size=(1280, 10)) body_data = np.random.randint(num_words, size=(1280, 100)) tags_data = np.random.randint(2, size=(1280, num_tags)).astype('float32') priority_targets = np.random.random(size=(1280, 1)) department_targets = np.random.randint(2, size=(1280, num_departments)) model.fit( {'title': title_data, 'body': body_data, 'tags': tags_data}, {'priority': priority_targets, 'department': department_targets}, epochs=2, batch_size=32 )