Keras多输入模型报错:4维图像输入进入fit后变为2维?
问题分析与解决方案
首先,你的报错看起来是图像维度变化导致的,但真正的问题出在BR特征分支的输入定义错误以及多输入模型的构建方式不符合Keras规范,我们一步步来拆解和修复:
核心问题解释
你看到的报错"Error when checking input: expected dense_1_input to have 3 dimensions, but got array with shape (1630, 1)",并不是图像输入的问题,而是你的BR特征分支(branch2)的输入形状设置错了:
- Keras中
input_shape参数定义的是单个样本的特征形状,而不是整个数据集的形状。你给branch2设置了input_shape=(data_num,1),这意味着模型期望每个样本是(1630,1)的3维数据,但实际每个样本的BR只是一个标量值,所以传入的BR_arr被处理成(1630,1)后,和模型期望的输入维度完全不匹配,才抛出了这个错误。 - 另外,你使用的旧版
Merge类已经被Keras弃用,推荐用函数式API来构建多输入模型,这是处理这类任务的标准方式。
具体修复步骤
1. 修正BR分支的输入形状
把branch2的定义从:
branch2 = Sequential() branch2.add(Dense(1, input_shape=(data_num,1), activation='sigmoid'))
改成:
branch2 = Sequential() branch2.add(Dense(1, input_shape=(1,), activation='sigmoid')) # 单个样本是1维标量
2. 改用函数式API构建多输入模型
旧的Merge类已经不再被支持,我们用函数式API重新构建模型,这样能更清晰地管理多个输入和分支:
# 图像输入分支 input_tensor = Input(shape=(img_width, img_height,3)) vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor) top_model = Sequential() top_model.add(Flatten(input_shape=vgg16.output_shape[1:])) branch1_output = top_model(vgg16.output) branch1 = Model(inputs=input_tensor, outputs=branch1_output) # BR特征分支(改用函数式API更清晰) branch2_input = Input(shape=(1,)) x = Dense(1, activation='sigmoid')(branch2_input) x = BatchNormalization()(x) x = Flatten()(x) branch2 = Model(inputs=branch2_input, outputs=x) # 合并两个分支 merged = Concatenate()([branch1.output, branch2.output]) # 后续全连接层 x = Dense(256, activation='relu')(merged) x = Dropout(0.5)(x) output = Dense(2, activation='softmax')(x) # 定义最终的多输入模型 model = Model(inputs=[branch1.input, branch2.input], outputs=output)
3. 规范BR数组的形状
你的BR_arr是一维数组(1630,),我们把它转换成(1630,1),让它和模型的输入形状完全匹配:
BR_arr = BR_arr.reshape(-1, 1)
4. 修正训练代码
最后用调整后的输入训练模型:
model.compile(loss='categorical_crossentropy', optimizer=optimizers.SGD(lr=1e-3, momentum=0.9), metrics=['accuracy']) # 检查输入形状(可选,用于验证) print("图像输入形状:", img_array.shape) # 应该是(1630,60,60,3) print("BR输入形状:", BR_arr.shape) # 应该是(1630,1) model.fit([img_array, BR_arr], label_arr, epochs=5, batch_size=100, verbose=1)
额外注意事项
- 你在
imgConvert函数里写的img = np.arange(1*3*60*60).reshape((60,60,3))会完全覆盖读取的图像,这应该是测试代码,记得改成实际的图像预处理逻辑! - 如果使用的是TensorFlow 2.x集成的Keras,旧的
Merge类已经被移除,必须使用函数式API的Concatenate层。 - 训练前可以打印各输入的形状,确保和模型期望的输入形状一致,避免类似的维度错误。
内容的提问来源于stack exchange,提问作者Le Trong Nghia
相关产品推荐
相关产品推荐

