基于频谱图与CNN的癫痫预测:模型准确率偏低及跨患者频谱图差异问题咨询
分析与优化建议
咱们先拆解下你当前的处理流程,看看哪些环节可能出了问题,再聊聊怎么解决患者间频谱图差异大的问题,以及小样本下准确率偏低的情况:
一、当前处理流程的潜在问题
1. 滤波环节的不一致性
- 你用
signal.lfilter处理带阻和高通滤波,但低通滤波用了signal.filtfilt——前者是单向滤波会引入相位偏移,后者是双向滤波无相位偏移,这会让不同频段的信号相位处理不一致,反而可能加剧患者间频谱图的差异。 - 带阻滤波针对50Hz和100Hz工频干扰,但如果部分患者数据的工频不是这个范围(比如有些地区是60Hz),滤波效果会打折扣;另外,连续两次带阻滤波后直接高通,没有考虑信号的衰减问题,可能导致有效信号被过度削弱。
2. 频谱图的归一化缺失
- 你注释掉了
normalize_color,意味着每个频谱图都是用自身的min/max做颜色映射,不同患者的信号强度天生存在差异,这会直接导致频谱图视觉上差异极大,模型很难学习到跨患者的通用癫痫发作特征。 nanpow2db把0值转成nan,但后续plt.pcolormesh处理nan时会出现色块缺失,破坏输入的一致性,影响模型训练。
3. 小样本下的模型适配问题
- 仅5例患者数据,CNN很容易过拟合到单个患者的独特特征,而不是癫痫发作的通用特征,65%的准确率大概率是模型在“记住”部分患者的模式,而不是真正具备泛化能力。
二、具体优化方案
1. 统一滤波处理逻辑
把所有滤波操作都换成filtfilt,保证信号相位一致,避免额外的差异引入:
def butter_highpass_filter(data, cutoff, fs, order=5): nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = signal.butter(order, normal_cutoff, btype='high', analog=False) y = signal.filtfilt(b, a, data) # 替换为双向滤波,消除相位偏移 return y def butter_bandstop_filter(data, lowcut, highcut, fs, order): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq i, u = signal.butter(order, [low, high], btype='bandstop') y = signal.filtfilt(i, u, data) # 替换为双向滤波 return y
另外,调整滤波顺序:先做高通滤波(过滤低频噪声),再做带阻滤波(去除工频干扰),能减少高频噪声对带阻滤波的影响。如果发现工频干扰依然明显,可以考虑用signal.iirnotch实现更精准的陷波滤波。
2. 标准化频谱图,消除患者间差异
- 全局归一化:不要每个窗口单独归一化,先统计所有训练数据(所有患者)的频谱图dB值的均值和标准差,然后对每个窗口做标准化:
(Sxx - global_mean) / global_std,或者把所有dB值压缩到固定范围(比如[-1, 1]),强制统一不同患者的频谱图尺度。 - 处理
nan值:不要直接留空,用周围值填充或全局均值替换,保证输入完整性:
def nanpow2db(y): y = np.asarray(y).astype(float) y[y == 0] = np.nan ydB = 10 * np.log10(y) # 用全局均值填充nan,避免色块缺失 ydB = np.nan_to_num(ydB, nan=np.nanmean(ydB)) return ydB
- 固定频谱图尺寸:比如只保留0-100Hz的频率范围(癫痫相关脑电信号主要集中在此),时间轴固定为4秒对应的长度,确保所有输入到CNN的图像尺寸完全一致。
3. 针对小样本的模型调整
- 数据增强:对频谱图做随机水平翻转、小角度旋转、轻微噪声注入、时间/频率轴的细微拉伸,增加样本多样性,缓解过拟合。
- 迁移学习:用预训练的CNN(比如ResNet、VGG)做特征提取,仅训练最后几层分类头,利用预训练模型的通用视觉特征,减少对小样本的依赖。
- 留一患者交叉验证:不要用随机划分训练测试集,采用留一患者交叉验证(LOPO),即每次用4例患者训练,1例患者测试,这样能更准确评估模型的跨患者泛化能力,避免模型只记住某个患者的特征。
4. 要不要增加更多滤波?
不需要盲目加滤波,先把现有滤波的一致性和归一化做好。如果做完上述优化后,频谱图仍有明显噪声(比如肌电噪声),可以考虑增加一个100Hz的低通滤波,过滤高频噪声;或者根据具体噪声来源,针对性添加滤波。
内容的提问来源于stack exchange,提问作者Sensei Munk
相关产品推荐
相关产品推荐

