两个keras多输入多输出模型如何进行拼接?

问题遇到的现象和发生背景

我有两个双输入双输出的模型,其中A模型的输出正好是B模型的输入(维度匹配),B模型预先训练进行了冻结,通过load_model的方式加载。现在如何使用keras.models.Model()方法进行连接呢?

问题相关代码,请勿粘贴截图
# 模型构建
inputs = keras.Input(shape=(32,), name="phase")
x = layers.Reshape((4, 8, 1))(inputs)
x = layers.Conv2D(filters=32, kernel_size=(2, 2), strides=1)(x)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU()(x)
x = layers.Conv2D(filters=64, kernel_size=(1, 1), strides=1)(x)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU()(x)
x = layers.Flatten()(x)
x = layers.Dropout(0.5)(x)
x = layers.Dense(256, activation='relu')(x)
outputs = layers.Dense(32)(x)

predictor = keras.Model(inputs, outputs, name="forward_resnet")

predictor.summary()

plot_model(predictor, to_file=logdir + 'predictor.png', show_shapes=True)

# 加载前向预测模型
base_model = keras.models.load_model(pra_path + '/parallel_predict_model/DNN.h5')
base_model.summary()
for i, layer in enumerate(base_model.layers):  # 冻结正向模型
    layer.trainable = False

# 保存模型的路径
logdir = pra_path + '/parallel_tandem_model/'
if not os.path.exists(logdir):
    os.mkdir(logdir)
output_model_file = os.path.join(logdir, "DNN.h5")

# 构造反向预测模型
abs_input = keras.layers.Input(shape=(16,), name='abs_input')
x = tf.keras.layers.Dense(64, activation='relu')(abs_input)
x = tf.keras.layers.Dense(128, activation='relu')(x)
x = tf.keras.layers.Dense(256, activation='relu')(x)

phi_input = keras.layers.Input(shape=(16,), name='phi_input')
y = tf.keras.layers.Dense(64, activation='relu')(phi_input)
y = tf.keras.layers.Dense(128, activation='relu')(y)
y = tf.keras.layers.Dense(256, activation='relu')(y)

merge_l = layers.Concatenate()([x, y])
x1 = layers.Dense(128, activation='relu')(merge_l)
theta_output = layers.Dense(6, activation='sigmoid', name='theta_output')(x1)

y1 = layers.Dense(128, activation='relu')(merge_l)
phi_output = layers.Dense(10, activation='sigmoid', name='phi_output')(y1)

forword_model = keras.models.Model(inputs=[abs_input, phi_input], outputs=[theta_output, phi_output])

# 模型拼接

theta_input = base_model.get_layer('theta_input')

theta_input = forword_model([abs_input, phi_input])[0]

phi_input = base_model.get_layer('phi_input')

phi_input = forword_model([abs_input, phi_input])[1]

abs_output = base_model.get_layer('abs_output')
abs_output = base_model(forword_model([abs_input, phi_input]))[0]

phi_output = base_model.get_layer('phi_output')
phi_output = base_model(forword_model([abs_input, phi_input]))[1]

new_model = keras.models.Model(inputs=[abs_input, phi_input], outputs=[abs_output, phi_output])

new_model.summary()

plot_model(new_model, to_file=logdir + 'predictor.png', show_shapes=True)


运行结果及报错内容

Traceback (most recent call last):
  File "/home/rof315/dyh_error_predict/parallel_tandem_model.py", line 97, in <module>
    phi_input = forword_model([abs_input, phi_input])[1]
  File "/home/software/anaconda3/envs/tf2.0/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/base_layer.py", line 822, in __call__
    outputs = self.call(cast_inputs, *args, **kwargs)
  File "/home/software/anaconda3/envs/tf2.0/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/network.py", line 717, in call
    convert_kwargs_to_constants=base_layer_utils.call_context().saving)
  File "/home/software/anaconda3/envs/tf2.0/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/network.py", line 891, in _run_internal_graph
    output_tensors = layer(computed_tensors, **kwargs)
  File "/home/software/anaconda3/envs/tf2.0/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/base_layer.py", line 822, in __call__
    outputs = self.call(cast_inputs, *args, **kwargs)
  File "/home/software/anaconda3/envs/tf2.0/lib/python3.6/site-packages/tensorflow_core/python/keras/layers/core.py", line 1128, in call
    rank = len(inputs.shape)
AttributeError: 'InputLayer' object has no attribute 'shape'

Process finished with exit code 1

img

我的解答思路和尝试过的方法

尝试使用Model()方法拼接,但是有bug,具体体现在B模型不是layer的类,但是要跟layer进行拼接

我想要达到的结果

A模型的输出正好是B模型的输入(维度匹配),B模型预先训练进行了冻结

Concatenate(axis=-1, name='merge')([A, B])应该可以,用过的,我用的是双流网络融合

比较建议的是你写个函数或者类,而不是简单的行堆砌;

model = Sequential()
model.add(A)
model.add(B)
XXXXX

使用Keras对多个模型进行拼接
https://blog.csdn.net/weixin_39393430/article/details/105592374