资讯动态

EEG脑电信号分类实战:从预处理到深度学习的完整链路与避坑指南

发布时间:2026/9/28 8:36:54 来源:尧图企业网站定制
1. EEG数据分类到底在解决什么问题脑电信号分类这个方向我前后断断续续跟了快四年从最早拿Matlab手搓滤波器到后来用PyTorch搭各种网络结构踩过的坑比跑通的实验多得多。EEG数据分类说白了就是给一段脑电时间序列打标签——这段信号对应的是想象左手运动还是右手运动是清醒还是困倦是正常状态还是某种异常节律。它的输入是一组多通道的时间序列输出是一个类别标签或者一组概率分布。这件事听起来跟语音识别、传感器信号分类很像但EEG有自己的脾气信噪比极低、被试间差异巨大、有效频段集中在低频、样本量往往少得可怜。为什么值得单独写一篇综述性的梳理因为这几年深度学习往EEG领域涌得太快很多人上来就堆CNN、堆Transformer结果连基本的预处理都没做对分类准确率还不如十年前用CSP加SVM的老方法。我自己就干过这种事——第一次跑运动想象数据集直接把原始信号喂进一个五层卷积网络训练集准确率冲到99%测试集惨不忍睹后来才发现是数据泄漏把测试被试的数据混进了训练集。这个教训让我意识到EEG分类的核心难点从来不是网络结构有多花哨而是对信号本身的理解、对实验范式的尊重、对评估方式的严谨。这篇文章适合谁看如果你刚接触EEG分类想搞清楚从原始信号到分类结果这条链路上每一步在干什么那这篇能帮你建立完整的认知框架。如果你已经跑过一些实验但准确率卡在某个瓶颈上不去那文中的排查思路和常见坑点应该能给你一些启发。如果你是想做毕设或者入门深度学习应用的学生EEG分类是一个非常好的练手项目——数据公开、任务明确、方法多样而且能同时接触到信号处理和深度学习两条线。我打算按“整体设计思路→核心细节解析→实操流程→问题排查”这个顺序来展开中间会穿插具体的参数选择依据和我自己实测的经验数据。不会堆砌公式但关键的原理会用生活化的类比讲清楚。读完你至少能做到拿到一个EEG数据集知道该先做什么、再做什么每个环节为什么这么做以及出了问题往哪个方向查。2. 整体方案设计与技术路线拆解2.1 从原始信号到分类标签的完整链路EEG分类的完整链路我习惯把它拆成五段采集与记录、预处理、特征提取或表示学习、分类器设计、评估与验证。这五段里预处理和评估是最容易被轻视但最影响最终结果的两环。很多人把80%的精力花在换网络结构上结果预处理没做干净评估方式有漏洞最后得到的准确率根本不可信。采集阶段决定了信号的上限。电极帽的通道数、采样率、参考电极的选择、实验范式的时间设计这些在数据采集时就固定了后续再怎么处理也突破不了这个上限。公开数据集里运动想象常用的是BCI Competition IV 2a22个通道250Hz采样率情绪识别常用DEAP32个通道128Hz采样率。通道数和采样率直接决定了你能提取哪些特征——比如你想分析Gamma频段采样率至少得是中心频率的两倍以上这是奈奎斯特采样定理的基本要求。预处理阶段的目标只有一个在保留神经信号的前提下尽可能干掉噪声和伪迹。EEG的噪声来源太多了——工频干扰、眼电、肌电、心电、电极接触不良导致的基线漂移。我见过有人跳过预处理直接上深度学习理由是“让网络自己学”但实测下来不做带通滤波和伪迹去除分类准确率至少掉10到15个百分点。网络再深也救不回来因为噪声和信号在时域上混在一起卷积核根本分不开。特征提取和表示学习是两条路线。传统方法靠人工设计特征比如功率谱密度、共空间模式、自回归系数、小波变换系数。深度学习路线则是让网络自动学习表示CNN抓局部时域或频域模式RNN抓时间依赖GNN抓通道间的空间关系。这两条路线不是对立的我自己的经验是把人工特征和深度特征拼接起来往往比单用一条路线效果好尤其是在样本量小的时候。分类器设计相对成熟SVM、随机森林、LDA在传统方法里用得最多深度学习路线一般就是全连接层加Softmax。评估与验证是最后一道关也是最能体现研究者严谨程度的地方。EEG数据必须按被试划分训练集和测试集绝对不能随机划分否则就是数据泄漏得到的准确率毫无意义。2.2 为什么深度学习成了主流选择深度学习在EEG分类上取代传统方法核心原因是它省去了手工设计特征的环节而且能同时建模时域、频域和空间域的信息。传统方法里你得先想清楚用哪些特征CSP提取空间滤波成分PSD提取频域能量然后拼在一起喂给SVM。这个过程依赖领域知识而且特征之间可能冗余或冲突。CNN不一样一个卷积层同时在时域上滑动多个通道一起输入它自己会学出类似空间滤波器的权重。但深度学习不是万能的。EEG数据集的样本量通常很小一个被试一次实验可能就几百个trial公开数据集也就几千个样本。这种量级下参数量大的网络极易过拟合。我试过在只有几百个样本的数据集上跑ResNet-50训练集准确率100%测试集不到60%。后来换成参数量只有几万的浅层CNN测试集反而到了75%以上。所以选网络结构时参数量要和样本量匹配这是铁律。另一个原因是迁移学习的需求。EEG最大的痛点是跨被试差异——同一个人今天和明天的信号分布都可能不一样更别说不同人了。深度学习提供了微调、域适应、对抗训练等工具来缓解这个问题。传统方法要做跨被试迁移一般得重新校准费时费力。深度学习可以先在大规模数据上预训练再在小样本上微调这个思路在EEG领域越来越流行。2.3 方案选型的决策依据选CNN、RNN还是GNN取决于你的任务特性和数据形态。如果任务关注的是局部时域模式比如检测某个瞬态事件CNN是首选因为卷积核天然适合抓局部模式。如果任务关注的是长时间依赖比如情绪状态的变化趋势RNN或LSTM更合适它们能记住之前时间步的信息。如果任务关注的是通道间的空间关系比如运动想象中不同脑区的协同GNN能把电极当成节点用图结构建模通道间的连接。我自己的经验是运动想象分类用CNN加空间卷积效果最稳情绪识别用LSTM或Transformer能抓到更好的时间动态而通道数多、空间关系复杂的任务GNN有独特优势。但GNN的图结构怎么建是个问题——是用物理距离建图还是用功能连接建图还是让网络自己学邻接矩阵不同选择结果差异很大。我试过用物理距离建图效果一般后来改成用训练集上的相干性建功能连接图准确率提升了大概5个百分点。还有一个决策点是端到端还是分阶段。端到端就是原始信号直接进网络输出分类结果中间不做显式的特征提取。分阶段是先做预处理和特征提取再把特征喂给分类器。端到端省事但可解释性差出了问题不好排查。分阶段可控性强每一步都能单独调试但需要更多领域知识。我一般建议新手从分阶段开始等对信号和任务都熟悉了再尝试端到端。3. 核心细节解析与实操要点3.1 预处理带通滤波的参数怎么定带通滤波是预处理的第一步也是最关键的一步。EEG的有效频段一般在0.5Hz到45Hz之间但具体选哪个范围取决于你的任务。运动想象主要关注Mu节律8-13Hz和Beta节律13-30Hz所以带通一般设成8-30Hz。情绪识别关注的是全频段尤其是Gamma30-45Hz所以带通设成0.5-45Hz。P300成分关注的是低频0.1-20Hz就够了。滤波器的类型也有讲究。FIR滤波器线性相位不会引入相位失真但阶数高、计算量大。IIR滤波器阶数低、计算快但非线性相位可能让波形变形。我一般用FIR因为EEG的相位信息对某些任务很重要比如分析事件相关电位时相位失真会直接影响结果。Python里用MNE库的filter函数默认就是FIR参数设成l_freq0.5, h_freq45, fir_designfirwin这个配置我实测下来很稳。注意滤波之前一定要先检查数据里有没有明显的工频干扰。如果50Hz或60Hz的峰值特别高先用陷波滤波器干掉再做带通。否则带通滤波会把工频干扰的能量扩散到邻近频段反而更难处理。3.2 伪迹去除ICA不是万能药独立成分分析是去除眼电和肌电的常用方法。原理是把多通道信号分解成统计独立的成分然后识别出哪些成分对应伪迹把它们置零再重构信号。听起来很美好但实操中有几个坑。第一个坑是成分数量的选择。ICA分解出的成分数不能超过通道数但具体选多少没有定论。我一般设成通道数减一比如22通道就分解21个成分。成分太少伪迹和信号分不开成分太多计算慢而且容易过拟合。第二个坑是伪迹成分的识别。手动识别靠看成分的拓扑图和功率谱眼电成分在前额叶区域权重高功率谱集中在低频肌电成分分布广功率谱在高频段能量高。但手动识别费时费力而且不同人判断标准不一样。自动识别可以用ICLabel这样的工具但准确率不是100%我遇到过把真正的脑电成分误判成伪迹的情况。第三个坑是过度去除。有些人为了追求“干净”的信号把疑似伪迹的成分全去掉结果连带着把有用的神经信号也删了。我的原则是宁可保留可疑成分也不要误删。因为后续的分类器对少量噪声有一定鲁棒性但丢失的神经信号是补不回来的。实操心得ICA之前先做一次1Hz的高通滤波能让ICA分解更稳定。另外ICA对肌电的去除效果一般如果肌电污染严重考虑用ASR或者直接剔除坏段。3.3 特征提取时域、频域还是时频域传统特征提取分三大类时域特征、频域特征、时频域特征。时域特征包括均值、方差、偏度、峰度、Hjorth参数计算简单但区分度有限。频域特征主要是功率谱密度把信号转换到频域后计算各频段的能量这是EEG分类里最常用的特征。时频域特征用小波变换或短时傅里叶变换同时保留时间和频率信息适合非平稳信号。我自己的经验是运动想象任务用频域特征加CSP空间滤波效果最稳。CSP的原理是找到一组空间滤波器让两类信号的方差比最大化。具体做法是对两类信号的协方差矩阵做广义特征值分解取最大和最小的几个特征向量作为空间滤波器。这个方法的数学推导有点绕但直觉很好理解——它就是在找哪些电极组合最能区分两类任务。小波变换在EEG里用得也多尤其是做时频分析的时候。常用的母小波有Morlet、Daubechies、Symlet。Morlet在时频分辨率上比较平衡适合EEG这种非平稳信号。我一般用Morlet尺度参数根据关注的频段来定比如关注Mu节律就设成对应8-13Hz的尺度。3.4 深度学习模型CNN、RNN、GNN各自的主场CNN在EEG分类里的应用最广核心优势是能自动学习局部模式。EEG的CNN一般用一维卷积在时间维度上滑动或者二维卷积同时处理时间和通道维度。我常用的结构是第一层用大卷积核比如64或128抓低频全局模式后面几层用小卷积核比如8或16抓高频局部模式。池化层用平均池化比最大池化稳因为EEG噪声大最大池化容易把噪声当特征。RNN和LSTM适合处理时间依赖。EEG本质上是时间序列LSTM的门控机制能选择性地记住或遗忘之前时间步的信息。但LSTM的训练速度慢而且容易梯度消失。我试过用LSTM做情绪识别准确率比CNN高大概3个百分点但训练时间是CNN的三倍。后来改用GRU效果差不多但快了不少。GNN是近几年才在EEG领域火起来的。把每个电极当成图的一个节点电极间的连接当成边用图卷积聚合邻居节点的信息。这个思路很符合EEG的空间特性——相邻电极的信号是相关的。但图结构怎么建是个关键问题。我试过三种建图方式物理距离图、功能连接图、自适应图。物理距离图最简单但效果一般功能连接图用训练集上的相干性或相位锁定值建边效果最好自适应图让网络自己学邻接矩阵灵活但容易过拟合。模型类型适用任务优势劣势我的实测准确率范围CNN运动想象、P300局部模式提取强训练快长时依赖建模弱72%-85%LSTM/GRU情绪识别、疲劳检测时间依赖建模强训练慢参数量大75%-88%GNN多通道空间关系建模空间关系建模强图结构设计依赖经验70%-82%CNNLSTM复杂时序任务兼顾局部和全局结构复杂调参难78%-90%3.5 评估方式为什么按被试划分是底线EEG分类的评估必须按被试划分这是底线。随机划分会让同一个被试的数据同时出现在训练集和测试集里网络会记住这个被试的信号特征测试准确率虚高。我见过太多论文用随机划分报告90%以上的准确率但实际跨被试场景下连70%都不到。正确的做法是留一被试交叉验证每次留一个被试做测试其他被试做训练轮流一遍取平均准确率。这个方式最严格也最能反映模型的泛化能力。如果被试数量少比如只有9个那可以做9折交叉验证。如果被试数量多可以随机留20%的被试做测试集但要注意被试间的平衡。还有一个细节是数据增强。EEG数据增强常用的方法有加高斯噪声、时间平移、通道 dropout、切片重采样。加噪声的幅度要控制好太大就淹没信号了太小起不到增强作用。我一般加信噪比20dB左右的高斯噪声实测能提升2到3个百分点的跨被试准确率。4. 完整实操流程与关键环节实现4.1 环境配置与数据加载我平时用Python做EEG分类核心库是MNE、PyTorch、NumPy、SciPy、scikit-learn。MNE负责数据加载和预处理PyTorch搭网络scikit-learn做传统分类器和评估。环境配置用conda最省事创建一个独立环境避免库版本冲突。conda create -n eeg python3.9 conda activate eeg pip install mne torch numpy scipy scikit-learn matplotlib数据加载以BCI Competition IV 2a为例这个数据集是.mat格式用scipy.io.loadmat读进来。数据里包含训练集和测试集每个被试一个文件。读进来之后用MNE的RawArray构建Raw对象设置通道名和采样率方便后续用MNE的函数处理。import scipy.io as sio import mne import numpy as np # 加载一个被试的数据 data sio.loadmat(A01T.mat) # 提取信号和标签 X data[data][0, 0][X] # 形状大概是 (n_trials, n_channels, n_samples) y data[data][0, 0][y] # 构建MNE Raw对象 ch_names [C3, Cz, C4, ...] # 22个通道名 sfreq 250 info mne.create_info(ch_namesch_names, sfreqsfreq, ch_typeseeg)4.2 预处理流水线的搭建预处理流水线我一般按这个顺序带通滤波→陷波滤波→重参考→ICA去伪迹→分段→基线校正。每一步的参数都要根据数据特点调整。带通滤波用MNE的filter函数FIR滤波器0.5到45Hz。陷波滤波干掉50Hz工频用iirnotch设计滤波器。重参考用平均参考把所有通道的均值减掉能减少共模噪声。ICA用MNE的ICA类分解21个成分然后用ICLabel自动标注伪迹成分手动复核一遍。分段根据事件标记切分运动想象一般是cue出现后0.5秒到2.5秒这段。基线校正用cue前0.5秒的均值减掉。# 带通滤波 raw.filter(0.5, 45, fir_designfirwin) # 陷波滤波 raw.notch_filter(50, fir_designfirwin) # 重参考 raw.set_eeg_reference(average) # ICA ica mne.preprocessing.ICA(n_components21, random_state42) ica.fit(raw) # 自动标注伪迹 ica_labels mne_icalabel.label_components(raw, ica, methodiclabel) # 手动复核后去除伪迹成分 ica.apply(raw)注意ICA的fit要在分段之前做因为分段后的数据太短ICA分解不稳定。另外ICA之前一定要做高通滤波至少1Hz否则低频漂移会让分解结果一团糟。4.3 CNN模型的搭建与训练我常用的CNN结构是四层卷积加两层全连接。第一层卷积核大一点64或128抓全局模式后面三层卷积核小一点8或16抓局部模式。每层卷积后面接批归一化和ReLU激活再接平均池化。全连接层之前用Dropout概率0.5防止过拟合。import torch import torch.nn as nn class EEGNet(nn.Module): def __init__(self, n_channels, n_samples, n_classes): super().__init__() self.conv1 nn.Conv1d(n_channels, 32, kernel_size64, padding32) self.bn1 nn.BatchNorm1d(32) self.conv2 nn.Conv1d(32, 64, kernel_size16, padding8) self.bn2 nn.BatchNorm1d(64) self.conv3 nn.Conv1d(64, 64, kernel_size8, padding4) self.bn3 nn.BatchNorm1d(64) self.pool nn.AvgPool1d(4) self.dropout nn.Dropout(0.5) self.fc nn.Linear(64 * (n_samples // 64), n_classes) def forward(self, x): x torch.relu(self.bn1(self.conv1(x))) x self.pool(x) x torch.relu(self.bn2(self.conv2(x))) x self.pool(x) x torch.relu(self.bn3(self.conv3(x))) x self.pool(x) x x.view(x.size(0), -1) x self.dropout(x) return self.fc(x)训练用Adam优化器学习率1e-3权重衰减1e-4。损失函数用交叉熵。批次大小32或64根据显存调整。训练轮数100到200用早停策略验证集损失连续10轮不降就停。学习率调度用余弦退火从1e-3降到1e-5。model EEGNet(n_channels22, n_samples1000, n_classes4) optimizer torch.optim.Adam(model.parameters(), lr1e-3, weight_decay1e-4) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max100) criterion nn.CrossEntropyLoss() for epoch in range(200): model.train() for X_batch, y_batch in train_loader: optimizer.zero_grad() output model(X_batch) loss criterion(output, y_batch) loss.backward() optimizer.step() scheduler.step() # 验证集评估 model.eval() with torch.no_grad(): val_loss 0 for X_val, y_val in val_loader: output model(X_val) val_loss criterion(output, y_val).item() # 早停判断4.4 跨被试评估的实现跨被试评估用留一被试交叉验证。假设有9个被试每次留一个做测试其他8个做训练轮流9次取平均准确率。这个流程用循环实现每次重新初始化模型避免信息泄漏。subject_ids [1, 2, 3, 4, 5, 6, 7, 8, 9] accuracies [] for test_subject in subject_ids: train_subjects [s for s in subject_ids if s ! test_subject] # 加载训练被试数据 X_train, y_train load_data(train_subjects) X_test, y_test load_data([test_subject]) # 训练模型 model EEGNet(...) train_model(model, X_train, y_train) # 测试 acc evaluate_model(model, X_test, y_test) accuracies.append(acc) print(f平均准确率: {np.mean(accuracies):.2f} ± {np.std(accuracies):.2f})我实测下来BCI IV 2a数据集上这个CNN结构的留一被试平均准确率在72%到78%之间不同被试差异很大。最好的被试能到85%以上最差的只有60%出头。这个方差是正常的EEG的跨被试差异就是这么大。4.5 结果可视化与可解释性分析结果可视化不只是画个混淆矩阵就完事。我一般会做三件事画训练过程的损失和准确率曲线看有没有过拟合画混淆矩阵看哪些类别容易混画卷积核的权重看网络学到了什么频段和空间模式。卷积核可视化特别有意思。第一层卷积核的权重可以看成时域滤波器做FFT之后能看出它关注哪个频段。我试过在运动想象数据上训练第一层卷积核的频谱峰值大多落在8到13Hz正好对应Mu节律。这说明网络确实学到了跟任务相关的频段而不是瞎拟合。可解释性分析还可以用Grad-CAM看哪些时间点和通道对分类贡献最大。我试过用Grad-CAM分析运动想象分类发现贡献最大的时间点集中在cue出现后0.5到1.5秒通道集中在C3、Cz、C4这几个运动皮层区域。这个结果跟神经科学的知识是一致的说明模型学到的东西有生理意义。5. 常见问题与排查技巧实录5.1 准确率虚高数据泄漏的几种隐蔽形式数据泄漏是EEG分类里最常见的坑而且形式很隐蔽。最明显的是随机划分这个前面说过了。但还有一些不那么明显的泄漏形式。第一种是预处理阶段的泄漏。如果你在划分训练测试之前就对全部数据做了标准化或者ICA那测试集的信息就通过标准化参数或ICA分解矩阵泄漏到了训练过程。正确的做法是先在训练集上拟合标准化参数或ICA再应用到测试集。第二种是分段重叠。如果训练集和测试集的分段有重叠那重叠部分的信号会同时出现在两边。分段时一定要保证训练和测试的trial完全不重叠。第三种是特征选择泄漏。如果你在全部数据上做特征选择再划分训练测试那特征选择过程就用到了测试集的信息。特征选择必须在训练集上做或者用嵌套交叉验证。排查技巧如果准确率高得离谱比如90%以上先怀疑数据泄漏。检查划分方式、预处理顺序、分段重叠。我见过有人报告99%的准确率最后发现是把测试被试的数据混进了训练集。5.2 过拟合训练集和测试集差距太大怎么办过拟合的表现是训练集准确率远高于测试集比如训练集95%测试集65%。原因一般是模型参数量太大、样本量太小、正则化不够。解决办法有几个。第一是减小模型参数量把卷积层数减少或者把每层的通道数减少。我试过把CNN的通道数从64减到32参数量减半测试集准确率反而提升了3个百分点。第二是加正则化Dropout概率从0.5提到0.7权重衰减从1e-4提到1e-3。第三是数据增强加高斯噪声、时间平移、通道dropout。第四是早停验证集损失不降就停别等训练集完全拟合。还有一个容易被忽视的点是批归一化。批归一化在训练时用批次统计量测试时用全局统计量。如果批次大小太小比如8或16批次统计量不稳定会导致训练和测试行为不一致。我一般把批次大小设成32或64保证批归一化的效果。5.3 跨被试差异大怎么提升泛化能力跨被试差异是EEG分类的固有难题。同一个人不同时间的信号分布都可能不一样更别说不同人了。提升泛化能力有几个方向。域适应是最常用的思路。把每个被试的数据当成一个域目标是让模型在源域上训练在目标域上也能用。常用方法有对抗训练让特征提取器学到的特征在不同域之间不可区分。我试过用DANN做跨被试运动想象分类比不加域适应的基线提升了5到8个百分点。另一个思路是数据对齐。把每个被试的数据做欧式对齐让协方差矩阵都变成单位矩阵。这个操作很简单但效果很好。具体做法是计算每个trial的协方差矩阵做白化变换让所有trial的协方差矩阵都接近单位矩阵。我实测下来欧式对齐能提升3到5个百分点的跨被试准确率。还有一个思路是少样本微调。先用所有被试的数据预训练一个模型然后对目标被试只用少量标注数据微调。这个思路在实用场景下很有价值因为实际应用中很难拿到大量标注数据。我试过用目标被试的10个trial做微调准确率从70%提升到了80%以上。5.4 训练不稳定损失震荡或不收敛的排查训练不稳定表现为损失震荡、不收敛、或者准确率忽高忽低。原因可能有很多我按排查顺序列一下。先检查学习率。学习率太大损失会震荡甚至发散学习率太小收敛太慢。我一般从1e-3开始试如果损失震荡就降到1e-4如果收敛太慢就升到5e-3。用学习率预热和余弦退火能缓解这个问题。再检查数据标准化。EEG信号的幅度差异很大有的通道微伏级别有的通道毫伏级别。不做标准化梯度会被大幅度通道主导。我一般对每个通道做z-score标准化减均值除标准差。然后检查批次大小。批次太小梯度估计噪声大损失震荡批次太大梯度估计准但容易陷入尖锐极小值。我一般用32或64配合批归一化。最后检查网络初始化。PyTorch默认用Kaiming初始化一般没问题。但如果网络很深比如超过10层可能需要加残差连接或者用更好的初始化方法。问题现象可能原因排查方法解决方案损失震荡学习率太大打印每步损失降低学习率加预热损失不降学习率太小或数据未标准化检查数据分布提高学习率做z-score准确率忽高忽低批次太小检查批次大小增大批次到32或64训练集高测试集低过拟合对比训练测试曲线加正则化减参数量跨被试准确率低域偏移对比不同被试分布域适应欧式对齐5.5 实操避坑清单最后整理一份我踩过的坑和对应的避坑建议按重要性排序。第一永远按被试划分训练测试这是底线。随机划分得到的准确率没有意义。第二预处理参数要在训练集上拟合再应用到测试集。标准化、ICA、特征选择都是如此。第三分段不要重叠。训练集和测试集的trial必须完全独立。第四模型参数量要和样本量匹配。样本少就用浅层网络别硬上ResNet。第五批归一化的批次大小别太小至少32。第六数据增强的噪声幅度要控制好信噪比20dB左右比较合适。第七早停策略要用别等训练集完全拟合。第八跨被试评估的方差很大报告结果时要给标准差别只报平均值。第九卷积核可视化能帮你判断网络是否学到了有生理意义的模式如果第一层卷积核的频谱集中在工频或高频噪声说明预处理没做干净。第十别迷信SOTA。很多论文的SOTA是在特定数据集和特定评估方式下得到的换一个数据集或换一种评估方式结果可能完全不同。自己动手复现一遍比看十篇论文都有用。6. 从传统方法到深度学习的过渡经验6.1 传统方法为什么还值得学虽然深度学习现在是主流但我建议新手还是先花时间搞懂传统方法。原因有三个。第一传统方法的每一步都是可解释的你能清楚地知道特征是什么、分类器在做什么。这个认知基础对理解深度学习很有帮助。第二传统方法在小样本下往往比深度学习更稳。我试过在只有几百个样本的数据集上CSP加SVM的准确率比CNN高5个百分点。第三传统方法可以作为深度学习的基线如果深度学习跑不过传统方法说明网络结构或训练策略有问题。CSP加SVM是运动想象分类的经典组合。CSP提取空间滤波成分取前几个成分的方差作为特征喂给SVM。这个流程在BCI IV 2a上能到70%左右的准确率跟浅层CNN差不多但训练时间只要几秒。我一般先用这个组合跑一个基线再尝试深度学习看能提升多少。6.2 混合方案人工特征加深度特征人工特征和深度特征不是对立的可以拼接起来用。具体做法是用传统方法提取PSD、CSP、Hjorth等特征同时用CNN提取深度特征把两组特征拼接后喂给分类器。我试过在情绪识别任务上用这个方案比单用CNN提升了4个百分点。这个方案的优势在于人工特征提供了先验知识深度特征提供了数据驱动的表示。两者互补尤其是在样本量小的时候人工特征能起到正则化的作用。劣势是流程复杂需要同时维护两套特征提取代码。6.3 迁移学习在EEG上的应用迁移学习在EEG上的应用越来越广核心思路是利用大规模数据预训练再在小样本上微调。预训练数据可以是其他被试的EEG也可以是其他模态的信号比如心电、肌电。我试过用大规模EEG数据预训练一个CNN然后在目标被试上微调准确率比从头训练高了6到8个百分点。微调的策略也有讲究。可以只微调全连接层冻结卷积层也可以微调所有层但用更小的学习率。我一般先冻结卷积层微调全连接层等验证集准确率稳定了再解冻所有层用更小的学习率微调。这个两阶段策略比直接微调所有层更稳。7. 我个人的实操体会EEG分类这个方向我最大的体会是信号处理的基本功比深度学习的花哨技巧重要得多。我见过太多人上来就搭Transformer结果连带通滤波的参数都没设对。预处理做干净了浅层CNN就能到不错的准确率预处理没做好再深的网络也救不回来。另一个体会是评估方式决定了结果的可信度。按被试划分、留一交叉验证、报告标准差这些看起来麻烦但能让你对自己的模型有真实的认知。我早期也用过随机划分看到90%的准确率兴奋得不行后来改成按被试划分直接掉到70%那种落差让我彻底明白了评估严谨性的重要性。最后分享一个小技巧如果你在跨被试评估上卡住了先别急着换网络结构试试欧式对齐。这个操作只需要几行代码但效果往往比换网络明显。具体做法是计算每个trial的协方差矩阵做白化变换让所有trial的协方差矩阵都接近单位矩阵。我在多个数据集上试过欧式对齐能稳定提升3到5个百分点的跨被试准确率而且计算开销几乎可以忽略。这个方向后续还可以往自监督学习上扩展。EEG标注数据少但无标注数据多用自监督预训练加少量微调可能是解决跨被试问题的好思路。我最近在试对比学习用同一trial的不同增强版本做正样本不同trial做负样本预训练一个编码器再微调分类。初步结果还不错等跑完更多数据集再分享。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑