构建二分类图像分类CNN-LSTM混合模型时遇RecursionError求助
问题排查与解决方案
错误根源
你遇到的RecursionError本质是输入数据维度与模型期望不匹配:
- 用
TimeDistributed包裹CNN层的CNN-LSTM模型,要求输入是时序格式,即形状为(batch_size, timesteps, height, width, channels)的张量。 - 当前
ImageDataGenerator输出的是普通图像张量,形状为(batch_size, 64, 64, 3),缺少时间步维度,导致模型处理时触发递归溢出。 - 模型结构还存在两处错误:LSTM层的
input_shape设置完全不符合CNN输出的维度;二分类任务的输出层配置与数据不匹配。
修正步骤
1. 调整数据输入,添加时间步维度
CNN-LSTM需要时序输入,我们给每个图像样本增加一个时间步维度(这里将单张图像作为长度为1的序列),通过自定义生成器实现:
# 自定义生成器,为输入添加时间步维度 def add_timestep_generator(generator): while True: x, y = next(generator) # 从 (batch_size, 64,64,3) 转为 (batch_size, 1, 64,64,3) x = x[:, None, :, :, :] yield x, y # 替换原数据生成器 train_seq = add_timestep_generator(train) validation_seq = add_timestep_generator(validation) test_seq = add_timestep_generator(test)
2. 修正模型结构
- 移除LSTM层中错误的
input_shape参数,让Keras自动推断输入维度 - 二分类任务中,若使用
class_mode='binary',最后一层Dense需设为units=1,配合sigmoid激活;若用units=2,需将class_mode改为'categorical',并改用categorical_crossentropy损失
# 初始化模型 model = Sequential() # 用TimeDistributed包裹CNN层,适配时序输入 model.add(TimeDistributed(Convolution2D(32, (3,3), input_shape=(64,64,3), activation='relu'))) model.add(TimeDistributed(MaxPooling2D(pool_size=(2,2)))) model.add(TimeDistributed(Flatten())) # LSTM层:自动推断输入维度,无需手动指定input_shape model.add(LSTM(units=20, return_sequences=True)) model.add(LSTM(units=20)) # 全连接层 model.add(Dense(units=128, activation='relu')) # 二分类输出层:units=1 + sigmoid 匹配binary_crossentropy model.add(Dense(units=1, activation='sigmoid')) # 编译模型 model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
3. 训练模型
使用修正后的时序生成器启动训练:
history = model.fit_generator( generator=train_seq, steps_per_epoch=2, validation_data=validation_seq, epochs=5 )
额外说明
如果你的需求并非处理时序图像(如视频帧序列),只是普通图像二分类,完全无需加入LSTM和TimeDistributed层,直接使用标准CNN结构即可避免此类维度匹配问题。
内容的提问来源于stack exchange,提问作者Imdadul Haque
相关产品推荐
相关产品推荐

