'save signature of keras multi input Model with predict_signature_def

I am building a multi input model in the following way (simplified model)

model_heads = []
input1 = Input(shape=(batch_input_shape[1], batch_input_shape[2]))
input2 = Input(shape=(batch_input_shape[1], batch_input_shape[2]))
inputs = [input1, input2]

model_layer = Conv1D(filters=8, kernel_size=2, padding='causal', dilation_rate=1, activation='relu', input_shape=(batch_input_shape[1], batch_input_shape[2]), kernel_initializer='he_normal')(inputs[0])
model_layer = MaxPooling1D(2)(model_layer)
model_heads.append(model_layer)
model_layer = Conv1D(filters=16, kernel_size=4, padding='causal', dilation_rate=1, activation='relu', input_shape=(batch_input_shape[1], batch_input_shape[2]), kernel_initializer='he_normal')(inputs[1])
model_layer = MaxPooling1D(4)(model_layer)
model_heads.append(model_layer)
flat_out = []
for j in model_heads:
    flat_out.append(Flatten()(j))
merged = concatenate(flat_out)
merged = Dense(100, activation=self.activation)(merged)
self.model = Model(inputs=inputs, outputs=output)
            self.model.compile(loss='binary_crossentropy', optimizer=self.opt, metrics=['accuracy'])

I feed the input and run training with runs fine, but then I save the model like so:

builder = tf.saved_model.builder.SavedModelBuilder(persistencydir + '/saved.' + str(start_prediction) + "." + str(end_prediction))
signature = tf.saved_model.signature_def_utils.predict_signature_def(inputs={'the_input': self.model.input}, outputs={'the_output': self.model.output})
builder.add_meta_graph_and_variables(sess, [tf.saved_model.tag_constants.SERVING], signature_def_map={tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature})
builder.save()

This of course complains because predict_signature_def expects a tensor for inputs but receives a python list instead:

  File "/home/myname/myutils/anaconda3/envs/tmp_merge/lib/python3.6/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py", line 205, in predict_signature_def
    for key, tensor in inputs.items()}
  File "/home/myname/myutils/anaconda3/envs/tmp_merge/lib/python3.6/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py", line 205, in <dictcomp>
    for key, tensor in inputs.items()}
  File "/home/myname/myutils/anaconda3/envs/tmp_merge/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py", line 324, in new_func
    return func(*args, **kwargs)
  File "/home/myname/myutils/anaconda3/envs/tmp_merge/lib/python3.6/site-packages/tensorflow/python/saved_model/utils_impl.py", line 58, in build_tensor_info
    dtype=dtypes.as_dtype(tensor.dtype).as_datatype_enum,
AttributeError: 'list' object has no attribute 'dtype'

Is there another way I can save the signature? Alternatively is it possible to build a Model with multi input using a single Tensor composed of the original inputs (input1 and input2 in my example). All examples I've seen are similar to what I have here, but I haven't found an example that also saves the signature...



Solution 1:[1]

Based on here: https://github.com/tensorflow/tensorflow/issues/39568#issuecomment-631120656, you can do:

signature = tf.saved_model.predict_signature_def(
                        inputs = {'input1':x1,'input2':x2},
                        outputs = {'output1':y1,'output2':y2})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1