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

基于CNN-LSTM的颅内出血CT分类模型准确率停滞58%的原因排查

颅内出血CT二分类:CNN-LSTM模型准确率停滞问题分析

问题背景

我正在构建基于CNN-LSTM的模型,用于CT扫描图像的颅内出血二分类任务。自定义数据生成器输出的单样本输入x形状为(512, 512, 3),标签y为单值;当batch_size设为32时,输入x的批量形状为(32, 30, 512, 512, 3)(30为时序切片数量),标签y批量形状为(32, 1)。

模型代码

model = Sequential()
model.add(TimeDistributed(Conv2D(64, (3, 3),  activation='relu'),input_shape=(None,512, 512,3)))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed(Dropout(0.3)))
model.add(TimeDistributed(Conv2D(128, (3, 3), activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed(Dropout(0.3)))
model.add(TimeDistributed(Conv2D(256, (3, 3), activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed((Dropout(0.3))))
model.add(TimeDistributed(Conv2D(512, (3, 3), activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed((Dropout(0.3))))
model.add(TimeDistributed(Conv2D(512, (3, 3), activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed((Dropout(0.3))))
model.add(TimeDistributed(Flatten()))
model.add(TimeDistributed(Dense(512, activation='relu')))
model.add(TimeDistributed(Dropout(0.3)))
model.add(Bidirectional(GRU(512,activation = 'relu', kernel_regularizer='l2')))  
model.add(Dense(1,activation='sigmoid'))

#optim = RMSprop(learning_rate=0.00001)
model.compile(loss='binary_crossentropy',
              #optimizer= SGD(lr=0.1), #momentum=0.9, decay=0.01),
              optimizer= Adam(lr=0.00001),
              #optimizer= Nadam(lr=0.001),
              metrics=['accuracy'])

训练日志

Epoch 1/5
904/904 [==============================] - 1056s 1s/step - loss: 1.4925 - accuracy: 0.5827 - val_loss: 0.7267 - val_accuracy: 0.5938
Epoch 2/5
904/904 [==============================] - 1050s 1s/step - loss: 0.6946 - accuracy: 0.5837 - val_loss: 0.6776 - val_accuracy: 0.5950
Epoch 3/5
904/904 [==============================] - 1057s 1s/step - loss: 0.6801 - accuracy: 0.5836 - val_loss: 0.6763 - val_accuracy: 0.5944
Epoch 4/5
904/904 [==============================] - 1045s 1s/step - loss: 0.6793 - accuracy: 0.5836 - val_loss: 0.6770 - val_accuracy: 0.5944
Epoch 5/5
904/904 [==============================] - 1048s 1s/step - loss: 0.6794 - accuracy: 0.5836 - val_loss: 0.6745 - val_accuracy: 0.5969

训练5个epoch后,模型准确率始终卡在58%左右,但损失值持续下降。而仅使用相同CNN架构(不含LSTM/GRU部分)的模型,准确率可达91%。数据分布情况见附图。

可能原因

  • 数据类别失衡:从准确率数值看,模型大概率在偏向预测占比更高的类别(比如占比58%的类别)。损失下降只是优化了多数类别的预测效果,少数类别的学习几乎没有进展。需要验证数据集的类别比例,若失衡严重,可采用加权损失、过采样/欠采样等方式调整。
  • GRU激活函数选型错误:当前GRU使用relu激活,而循环层通常适配tanh或sigmoid。relu的硬饱和特性容易导致梯度消失,使得GRU无法有效学习时序信息,模型退化为依赖CNN部分的低效预测器。
  • 学习率过低:当前Adam的学习率设为1e-5,对于加入GRU后的复杂模型来说,这个学习率太小,导致GRU层的权重更新极其缓慢,无法学到有效的时序特征,拖慢了整体模型的性能。
  • 时序特征无效:如果30个CT切片的时序顺序没有实际意义,或者切片间特征差异极小,GRU不仅无法提取有效信息,反而引入额外噪声和参数负担,干扰了原本CNN的有效特征学习。
  • 模型冗余与正则化过度:GRU设置了512个单元,加上前面CNN的大量参数,模型容量过大;同时Dropout和L2正则化的叠加,可能导致模型难以收敛,尤其是GRU部分的参数无法有效更新。
  • 损失与准确率脱节:损失下降但准确率不提升,可能是模型输出的概率值在接近真实标签,但还没跨过0.5的分类阈值。可以查看训练过程中的预测概率分布,调整分类阈值,或者检查损失计算与标签格式的匹配性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 23:36:21