如何在Keras模型中组合多输入?解决形状不匹配报错
问题描述
想要将四个不同形状的输入整合到单个Keras模型中,但直接执行拼接操作时触发报错。使用的代码如下:
import tensorflow as tf input1 = tf.keras.layers.Input(shape=(28, 28, 1)) input2 = tf.keras.layers.Input(shape=(28, 28, 3)) input3 = tf.keras.layers.Input(shape=(128,)) input4 = tf.keras.layers.Input(shape=(1,)) x = tf.keras.layers.Concatenate(axis=1)([input1, input2, input3, input4]) x = tf.keras.layers.Dense(2)(x) model = tf.keras.models.Model(inputs=[input1, input2, input3, input4], outputs=x)
运行后报错信息:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) /tmp/ipykernel_3447/2584043467.py in <cell line: 6>() 4 input4 = tf.keras.layers.Input(shape=(1,)) 5 ----> 6 x = tf.keras.layers.Concatenate(axis=1)([input1, input2, input3, input4]) 7 8 x = tf.keras.layers.Dense(2)(x) /usr/local/lib/python3.8/site-packages/keras/utils/traceback_utils.py in error_handler(*args, **kwargs) 65 except Exception as e: # pylint: disable=broad-except 66 filtered_tb = _process_traceback_frames(e.__traceback__) ---> 67 raise e.with_traceback(filtered_tb) from None 68 finally: 69 del filtered_tb /usr/local/lib/python3.8/site-packages/keras/layers/merging/concatenate.py in build(self, input_shape) 112 ranks = set(len(shape) for shape in shape_set) 113 if len(ranks) != 1: ---> 114 raise ValueError(err_msg) 115 # Get the only rank for the set. 116 (rank,) = ranks ValueError: A `Concatenate` layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape=[(None, 28, 28, 1), (None, 28, 28, 3), (None, 128), (None, 1)]
解决方案
报错核心原因是输入张量的维度不统一:input1、input2是4D图像张量,input3、input4是2D向量张量,直接拼接不符合Keras要求。必须先将所有输入转换为相同维度的张量,再执行拼接操作。
具体实现思路
- 处理图像类输入:通过卷积+全局池化,或者直接展平的方式,将4D图像张量转换为2D向量张量。
- 保留向量类输入:input3、input4本身已是2D张量,无需额外处理。
- 统一维度后拼接:将所有处理后的2D张量在特征轴(axis=1)拼接,再接入后续全连接层。
示例代码
方案1:卷积+池化处理图像输入
import tensorflow as tf # 定义输入 input1 = tf.keras.layers.Input(shape=(28, 28, 1)) input2 = tf.keras.layers.Input(shape=(28, 28, 3)) input3 = tf.keras.layers.Input(shape=(128,)) input4 = tf.keras.layers.Input(shape=(1,)) # 处理input1:提取图像特征并转为向量 x1 = tf.keras.layers.Conv2D(32, (3,3), activation='relu')(input1) x1 = tf.keras.layers.GlobalAveragePooling2D()(x1) # 处理input2:同input1的特征提取逻辑 x2 = tf.keras.layers.Conv2D(32, (3,3), activation='relu')(input2) x2 = tf.keras.layers.GlobalAveragePooling2D()(x2) # 拼接所有向量 concat = tf.keras.layers.Concatenate(axis=1)([x1, x2, input3, input4]) # 输出层 output = tf.keras.layers.Dense(2, activation='softmax')(concat) # 构建并查看模型 model = tf.keras.models.Model(inputs=[input1, input2, input3, input4], outputs=output) model.summary()
方案2:直接展平图像输入(轻量化处理)
如果不需要对图像做特征提取,可直接用Flatten()层将图像张量转为向量:
import tensorflow as tf # 定义输入 input1 = tf.keras.layers.Input(shape=(28, 28, 1)) input2 = tf.keras.layers.Input(shape=(28, 28, 3)) input3 = tf.keras.layers.Input(shape=(128,)) input4 = tf.keras.layers.Input(shape=(1,)) # 直接展平图像为向量 x1 = tf.keras.layers.Flatten()(input1) x2 = tf.keras.layers.Flatten()(input2) # 拼接所有向量 concat = tf.keras.layers.Concatenate(axis=1)([x1, x2, input3, input4]) # 输出层 output = tf.keras.layers.Dense(2, activation='softmax')(concat) # 构建模型 model = tf.keras.models.Model(inputs=[input1, input2, input3, input4], outputs=output)
内容的提问来源于stack exchange,提问作者stackbiz
相关产品推荐
相关产品推荐

