You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EfficientNetB0与LSTM融合模型适配失败:输入形状不兼容求助

问题解决:EfficientNetB0与LSTM融合的输入形状不兼容问题

核心错误分析

  1. 模型输入定义错误:最终模型model1错误地将EfficientNet的输出张量Res_model作为输入,而非EfficientNet的输入层effnet.input,导致输入形状不匹配。
  2. LSTM输入与数据格式不匹配:LSTM要求输入形状为(None, 序列长度, 特征维度),当前定义的sequence_input=(150,150)与X_train=(150,150,3)的维度不兼容。
  3. 训练数据传入格式错误:多输入模型训练时,需传入对应每个输入层的数据,而非单一的(X_train,y_train)。
  4. 激活函数与损失函数不匹配:输出层用sigmoid但损失用categorical_crossentropy,二分类场景下需调整对应关系。

修正后的完整代码

import tensorflow as tf
from tensorflow.keras.layers import Input, LSTM, Concatenate, Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras.models import Model

# ---------------------- 构建EfficientNet分支 ----------------------
input_shape=(150,150,3)
# 补全缺失的右括号
effnet = EfficientNetB0(weights=None, include_top=False, input_shape=input_shape)
Res_model = effnet.output
print(Res_model.shape)  # (None, 5, 5, 1280)

# 特征提取与全连接层
x = GlobalAveragePooling2D()(Res_model)
print(x.shape)  # (None, 1280)
x = Dense(512, activation="relu")(x)
print(x.shape)  # (None, 512)
# 移除training=True,训练时模型自动处理dropout状态
x = Dropout(rate=0.5)(x)
print(x.shape)  # (None, 512)
effnet_output = Dense(32, activation='relu')(x)  # 用relu作为中间输出,避免与最终输出激活冲突
print(effnet_output.shape)  # (None, 32)

# 封装EfficientNet分支模型
effnet_model = Model(inputs=effnet.input, outputs=effnet_output)
print(effnet_model.input_shape)  # (None, 150, 150, 3)
print(effnet_model.output_shape) # (None, 32)

# ---------------------- 构建LSTM分支 ----------------------
# 根据X_train形状调整LSTM输入:将图像每行作为序列步,每行的特征为150*3=450个像素值
# LSTM输入形状为(序列长度, 特征维度)
sequence_input = Input(shape=(150, 150*3))
print(sequence_input.shape)  # (None, 150, 450)

lstm_output = LSTM(32)(sequence_input)
print(lstm_output.shape)  # (None, 32)

# ---------------------- 融合两个分支 ----------------------
concatenated = Concatenate()([effnet_output, lstm_output])
# 二分类场景下,若标签是one-hot编码用softmax+categorical_crossentropy;若为单标签用sigmoid+binary_crossentropy
output = Dense(2, activation='softmax')(concatenated)

# 最终模型的输入是两个输入层张量:effnet.input 和 sequence_input
model1 = Model(inputs=[effnet.input, sequence_input], outputs=output)

# 根据输出激活选择对应损失函数
model1.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])

# ---------------------- 数据预处理与训练 ----------------------
# 假设X_train形状为(N,150,150,3),y_train为(N,2)的one-hot编码
# 预处理LSTM输入:将图像reshape为(N,150, 150*3)
X_train_lstm = X_train.reshape(-1, 150, 150*3)

# 传入两个输入数据,对应模型的两个输入层
history = model1.fit(
    [X_train, X_train_lstm], y_train,
    batch_size=32,
    epochs=2,
    validation_split=0.1,
    verbose=1
)

关键修改说明

  • 输入层修正:将model1的输入改为[effnet.input, sequence_input],确保模型接收原始图像输入和适配LSTM的序列输入。
  • LSTM输入适配:通过reshape将原始图像转换为LSTM要求的(序列长度, 特征维度)格式,这里选择图像的高度(150)作为序列长度,每行的所有像素(150×3)作为特征维度,你可根据任务需求调整序列维度的定义(比如按通道作为序列)。
  • 训练数据传入:多输入模型训练时,需传入包含所有输入数据的列表,对应模型的每个输入层。
  • 激活与损失匹配:二分类场景下,若标签是one-hot编码,使用softmax激活+categorical_crossentropy损失;若为单标签(0/1),则改为sigmoid激活+binary_crossentropy损失。

内容的提问来源于stack exchange,提问作者Monika Kohli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:45:18