DEAP数据集情绪识别实战:从EEG预处理到分类模型全流程
2026/8/31 22:20:03 网站建设 项目流程

简介:本资源是一套基于DEAP数据集的情绪识别分类项目实现,面向人工智能、脑机接口与情感计算方向的学习者与研究者,适用于情绪状态建模、生理信号特征提取与多模态分类算法实践。压缩包共46个文件,包含28个Java源码文件(涵盖数据预处理、特征工程、SVM/RF等分类器实现)、5个训练数据文件(book.train、dvd.train等按领域划分的标注样本)、7个.zbak备份配置文件,以及README.md、LICENSE等工程元信息,整体大小为9.56MB,结构完整且具备可复现性。已有215人学习下载,适合初学者理解DEAP数据集加载流程与端到端分类 pipeline,亦可作为课程设计或科研原型快速迭代基础。项目目录清晰分层,src下按包组织代码,train文件按类别分离,便于调试与扩展模型。 做情绪识别的人,十有八九绕不开DEAP这个数据集。它不像CV那边ImageNet那样人人皆知,但在情感计算、脑机接口、人机交互这几个圈子里,只要提到“用生理信号做情绪分类”,大家的第一反应基本就是它。这次我把自己在复现情绪分类项目sentimentclassify master分支上的完整过程整理出来——从数据集下载、预处理、特征提取到模型训练和评估,踩过的坑、验证过的参数、能直接拿走用的代码,都会写到。希望给正在做DEAP数据集分类或者相关课程设计的朋友一些可复现的参考。

1. 为什么是DEAP:情绪识别数据集的选型逻辑

1.1 情绪识别研究到底需要什么样的数据

情绪识别不是简单的分类问题,它牵扯到情绪模型、信号模态、时间分辨率、个体差异等一堆问题。早期研究喜欢用图片或视频刺激诱发情绪,然后用主观量表打分作为标签,同时采集面部表情、语音、姿态等行为信号。但行为信号容易被伪装,比如一个人表面微笑,内心可能毫无波动,所以大家逐渐转向更底层的生理信号——特别是脑电EEG和外围生理信号。DEAP(Database for Emotion Analysis using Physiological Signals)正是这样一个多模态生理情绪数据库,它把EEG、眼电、肌电、皮电、呼吸、温度等信号和主观评分一起提供出来,可以说是这个方向的“标准教材”。

DEAP设计上有几个特点让它很适合做分类任务。第一,样本量在同类数据集里算比较可观的——32名被试,每人40段一分钟音乐视频刺激,总共1280个有效试验;第二,标签是连续评分制,valence(效价)、arousal(唤醒度)、dominance(支配度)、liking(喜好度)都是1到9的主观打分,既可以转成二分类,也可以做三分类甚至回归;第三,除了EEG还提供了外周生理信号,方便做多模态融合实验。这些特性让DEAP在各种论文里频繁出现,也让我们做算法的人有统一的benchmark可以对比结果。

如果你刚接触这个领域,可能会困惑“为什么非要用情绪维度而不是离散标签”。这里解释一下。情绪心理学里有两派主流模型:一类是离散模型,把情绪分成快乐、悲伤、愤怒、恐惧等基本类别;另一类是维度模型,认为所有情绪都分布在valence(正负)、arousal(激活强度)、dominance(控制感)这几个连续轴上。维度模型的好处是能表达细腻的情绪梯度,也更容易映射到生理信号的变化规律。DEAP采用的是维度模型,所以你在做分类时,不需要硬编码固定几个情绪名,而是判断当前信号在高/低valence轴上的得分,这更接近实际场景。

1.2 和SEED、MAHNOB-HCI等数据集的横向对比

提到可选数据集,大家比较关注SEED和MAHNOB-HCI。SEED也是EEG情绪数据集,但它只有15个被试,80个视频片段,EEG用的是62通道的ESI系统,没有外周信号,诱发的是离散情绪标签(正/中/负),和DEAP的连续维度标签路数不同。MAHNOB-HCI有30个被试,包含EEG、眼动、视频、音频,更侧重多模态交互场景,但数据不完整、预处理难度大,上手成本高。相比之下,DEAP的优势是模态全、被试多、评分维度丰富、预处理流程在社区里已经非常成熟,适合用来验证新的分类算法。如果只是入门或者做算法对比,DEAP是平衡性最好的选择。

另外,DEAP还提供了一个“无表情视频”的子集,也就是部分被试没有采集面部视频,只保留了生理信号,方便研究者在不需要处理视频的情况下使用。这一点在做数据筛选时要注意,否则容易把空视频当成坏数据。我见过有人用MATLAB加载后,发现某个被试的video数据是空数组,其实不是数据损坏,而是官方设计如此。如果你计划做音视频特征融合,要提前确认哪些被试带有面部视频,避免中途踩坑。

选型这块我个人的经验是:先想清楚你要回答什么问题。如果只关心EEG信号里的情绪编码机制,那SEED和DEAP都行,但DEAP的维度评分更细腻;如果要多模态融合或做可穿戴场景,DEAP的外周信号就非常关键。至于MAHNOB-HCI,我建议等基础流程跑通后再去挑战,因为它的预处理文档需要额外花时间啃。

2. 下载DEAP数据集的每一步,以及我踩过的坑

2.1 官网注册与数据格式确认

DEAP数据集由伦敦玛丽女王大学维护,官方下载地址需要通过填写申请表单后获取下载链接。申请时一般要填姓名、机构、用途,这个流程主要是为了统计使用群体,基本第二天就能收到邮件。我当时填的是“科研用途”,很快通过了。邮件里会给几个下载文件:DEAP_Preprocessed_4.0.zip(大概3GB)以及对应的.rar版本。解压后能看到 data_preprocessed_matlab 和 data_original_matlab 两个主要文件夹。大部分研究用的都是 data_preprocessed_matlab,里面每个被试一个 .mat 文件,比如 s01.mat。每个文件里是一个 40 x 40 x 8064 的三维数组,含义是:40个试验 × 40个通道 × 63秒×128Hz采样后的数据点。是的,预处理版本已经做了128Hz下采样,原始数据是512Hz。

这里有个很重要的细节:很多教程会直接告诉你.loadmat,但没有提醒你数组维度的顺序。我第一次读数据时想当然地以为第一个维度是通道,结果后面处理逻辑全乱了。DEAP的.mat结构里,第一个维度是试验序号,第二个维度是通道,第三个维度是时间采样点。所以 s01.mat 的 shape 是 (40, 40, 8064),不是 (40, 8064, 40)。这个顺序会直接影响你写切片代码,比如“取所有试验的EEG通道”应该是 data[:, :32, :],而不是 data[:32, :, :]。建议拿到数据后第一步就把shape打印出来,形成肌肉记忆。

官方邮件里还可能包含 participant_ratings.csv 和 video_metadata.csv。前者记录每个被试对每个视频的四个评分维度,后者是40个视频的元信息。如果邮件里没有,也可以从官网单独下载,或者去项目社区的网盘镜像找。我建议把评分文件单独放在一个“labels”目录里,因为后面特征提取和分类都要用它。

2.2 文件校验和常见下载中断问题

下载过程中最头疼的是大文件传输中断。3GB的压缩包容易在网速波动时损坏,解压到一半报错“unexpected end of data”。我遇到过两次,后来发现最好用支持断点续传的下载工具,或者让浏览器下载时保持网络稳定。拿到压缩包后不要急着解压,先做个完整性校验。官方没有提供MD5,但你可以解压后直接读取数组shape来验证,如果能load s01.mat到内存且数组维度符合 40×40×8064,基本就是完整的。

如果你是MacOS或者Linux环境,解压 .zip 直接用 unzip 就可以;但如果拿到的是 .rar,记得用 unar 或者安装 p7zip,避免中文路径乱码。Windows下用WinRAR解压一般没问题。我当时在Linux服务器上操作,用Python的 scipy.io.loadmat 读取时,发现有的.mat文件被识别成v7.3格式,需要额外用 hdf5storage 库。DEAP官方的.mat是老版本格式,scipy可以直接读,但如果你从其他渠道拿到新导出的版本,就要做兼容处理。我的项目代码里封装了一个 load_deap_mat() 函数,自动判断是dict还是hdf5,减少环境依赖带来的问题。

另外,对于国内网络,直接下载大文件可能不太稳定。我比较推荐的做法是找一下国内高校或实验室的镜像资源,或者用网盘中转。但无论从哪个渠道下载,下载完一定要做同样的shape校验,因为有些渠道分享的文件可能被二次压缩或者缺失被试。我的习惯是解压后跑一遍脚本,统计 s01.mat 到 s32.mat 是否全部存在,以及每个文件的数组shape是否一致。这一步虽然简单,但能省掉后面很多莫名其妙的报错。

2.3 标签文件与刺激信息的对应

除了原始信号,DEAP还提供了 participant_ratings.csv,记录了每个被试对每个视频的四个维度评分以及视频的ID、序号。每个被试的评分文件里,40行代表40个试验,后四列依次是valence、arousal、dominance、liking。很多新手直接把 s01.mat 的40个试验和ratings的顺序对应,这是对的,因为数组的第一个维度就是试验顺序,和ratings文件的行号一致。但有个坑:participant_ratings.csv 里的被试顺序不一定和你预想的 s01, s02 对应,我建议载入之后先打印前几行确认一下被试编号和评分数值,再开始批量处理。

有些论文会把dominance或liking忽略,只用valence/arousal,因为这两维是核心情绪维度。做二分类时,常见做法是取评分的中值(比如5)作为阈值,大于等于5为高,小于5为低。这个阈值不是唯一的,但DEAP相关研究普遍采用中位分割,方便横向对比。如果你打算做三分类,可以把评分分为低(1-3)、中(4-6)、高(7-9)三段,但三分类的准确率通常会低于二分类,因为中间类边界模糊,对特征区分度要求更高。

关于刺激视频的ID,DEAP官方文档里写了40个视频是从某个音乐视频库中选取的,ID不连续,但这个细节对标签影响不大。真正要注意的是:如果你下载到的版本是“front view video”和“top view video”分离的,需要确认和生理信号的试验序号是否仍然一一对应。我用的预处理版本不含视频,所以这个问题不突出,但如果你做多模态融合,一定记得把视频文件名、被试编号、试验序号三方对齐,不能只靠文件列表顺序。

3. 原始脑电信号预处理:从.mat文件到干净的分段数据

3.1 通道布局和采样频率的理解

DEAP预处理版本数据是40×40×8064,第二维40个通道中,前32通道是EEG,按照国际10-20系统排列,从Fp1开始;后8个通道是外周信号,依次是EOG(眼电)、EMG(肌电)、GSR(皮电)、呼吸、脉搏、体温等。不同论文对后8个通道的索引描述不完全一致,最稳妥的方法是看DEAP自带的技术报告,或者读数据集里的channel_location信息。如果你打算只用EEG,直接切片 data[:, :32, :];如果想用多模态,保留后8通道,但要注意这些外周信号量纲差异很大,特征融合前必须做z-score归一化。

采样频率这块,预处理版是128Hz,通过官方的带通滤波和降采样得到,做特征提取时不用再重采样。63秒的数据总共有8064个点,很好算:128Hz × 63秒 = 8064。前3秒是基线静息状态,后60秒是视频刺激阶段。很多研究直接去掉前3秒,只保留后60秒;也有的用前3秒做基线校正。我两种都试过,后者在分类准确率上通常能提升1到2个百分点,原理是去除了个体静息状态的差异。不过基线校正也增加了计算量,如果只是快速跑通流程,可以先跳过。

我在实际处理中会先对每个被试的数据建立一个统一的数据结构:一个dict存储EEG数组、外周数组、标签数组、被试ID、试验ID。这样做的好处是,后续特征提取时不需要反复从原始.mat文件读取,可以一次性缓存到内存或磁盘。DEAP的数据量不大,32个被试全部载入内存大概占1GB左右,普通机器完全扛得住。如果内存紧张,可以按被试分批处理,特征提取后再合并。

3.2 伪迹去除和滤波的实际操作

EEG信号最麻烦的是眼电伪迹和肌肉伪迹。虽然官方预处理版本已经做了带通滤波(4-45Hz),但残余的眼电影响依然存在。我的做法是:先把每个试验的EEG通道做0.5到45Hz的零相位带通滤波(用scipy的butter + filtfilt),然后对所有试验拼起来跑ICA,剔除与眼电通道相关性高的独立成分。但是要注意,DEAP每个试验只有60秒,ICA需要足够的数据量才稳定,我建议把所有被试、所有试验的EEG通道拼接起来做一次ICA,或者至少对单个被试的40个试验拼接后做ICA,不要在单个试验上跑ICA。

如果只是为了快速跑通流程,可以跳过ICA,只用带通滤波,因为后续特征提取用的是频段能量(theta、alpha、beta、gamma),眼电主要影响低频部分,0.5-4Hz区域本来就会被过滤掉。也就是说,滤波后直接分段,在绝大多数分类任务里结果已经够用。ICA会显著提升模型泛化能力,但计算成本高,需要结合自己的算力决定。我自己的服务器是4核CPU,对32个被试全部做ICA大概需要半小时,属于能接受的范围。

滤波参数方面,我会用 scipy.signal.butter(4, [0.5, 45], btype='bandpass', fs=128) 然后 filtfilt 做零相位滤波。不要直接在高频上做,因为DEAP预处理版已经是4-45Hz带通,如果你再用45Hz低通,会进一步削弱gamma频段信息。如果需要保留gamma,可以把上限设为45Hz,但如果做MNE处理,经常默认50Hz低通,这会导致gamma频段特征减弱。建议根据你要提取的特征频段来决定滤波范围。

3.3 分段、基线校正与样本组织

预处理后的数据每个被试有40个试验,每个试验是63秒。我采用两种常见策略:一是直接用一个试验作为一样本,这样每个被试只有40个样本,1280个总样本,训练数据可能不够;二是滑动窗口分段,比如用4秒窗口、2秒步长,60秒刺激段大概可以切出29个窗口,这样每个样本都保留时间上下文,数据量也大幅增加。但要注意,同一试验切出的窗口高度相关,训练集和测试集不能随机打乱,否则会导致数据泄漏。正确做法是:按被试划分训练/验证集,或者至少在划分窗口时保证同一试验的所有窗口在同一集合中。

基线校正怎么做?我常用的方法是:对于每个通道,计算前3秒基线的平均值,然后用刺激段的每个采样点减去这个平均值,再做除法归一化。这样能消除个体间静息态脑电水平差异。如果你用差分熵特征,校不校正的影响会小一些,但如果是直接输入原始波形给深度学习模型,基线校正基本是必须的。另外,如果使用滑动窗口,基线校正要在分段之前完成,否则每个窗口都会包含不同比例的基线噪声。

分段后的数据组织我建议保存成npy或npz格式,加快后续读取。比如每个窗口存成一个 (40, 512) 的矩阵,其中512就是4秒×128Hz。这样的样本量大概是多少?60秒刺激段用2秒步长切,大概29个窗口,但最后一个窗口可能不足4秒,我会直接丢弃不足的尾部。这样每个被试有40×29=1160个窗口,32个被试约37000个样本。对于SVM和随机森林来说,样本量已经非常充足了。

4. sentimentclassify核心:特征提取与分类模型搭建

4.1 特征选择的逻辑和具体实现

在这个项目里,特征提取我主要用了三类:频段功率谱密度(PSD)、微分熵(DE)和Hjorth参数。EEG情绪识别领域,比较经典的研究表明,theta(4-8Hz)、alpha(8-13Hz)、beta(13-30Hz)、gamma(30-45Hz)四个频段的能量变化和情绪效价、唤醒度有较强的相关性。用scipy计算PSD不算复杂,先对每个通道每个分段做Welch估计,然后分别求四个频段的平均功率。微分熵是香农熵在连续信号上的延伸,对于服从高斯分布的信号,微分熵等于 log(2πeσ²)/2,其中σ是信号标准差。实际中常用带通滤波后信号的方差来近似,计算效率高,很多DEAP论文都将DE作为特征。

Hjorth参数包含活动度、移动度和复杂度,用来描述信号的时域统计特性。虽然它的区分能力不如频带特征,但胜在计算快、维度低,可以用来做多视图融合。我在项目里将这三类特征拼接成一个特征向量:每个通道4个频段PSD(4维)+ 每个通道4个频段DE(4维)+ 3个Hjorth参数(3维),共11维每通道。如果只用前32个EEG通道,就是352维;如果把40个通道全用上,就是440维。这个维度下,传统的SVM和随机森林都能很快训练。

特征提取的代码我封装成了类,输入是窗口数据矩阵 (n_channels, n_samples),输出是特征向量。为了加速,批量处理时会先用numpy的fft计算PSD,再利用PSD结果求频段能量,避免重复计算。代码里我特意加了一个verbose参数,方便在Jupyter里观察处理进度。因为DEAP的数据处理流程长,如果你一次性把预处理和特征提取都跑完,中间没有任何日志输出,会让人很慌。

4.2 标签设定与数据划分

前面提到用评分中值为阈值做二分类。具体到sentimentclassify项目,我同时训练了valence和arousal两个二分类器。对于每个样本窗口,它的标签来自于被试对该视频的评分。这里一定要清楚:同一个试验的所有窗口共享同一个标签,所以不能按窗口随机划分数据集,否则同一试验的窗口会同时出现在训练和测试里,导致结果虚假偏高。我采用按试验划分的GroupKFold,也就是一个试验的所有窗口要么都在训练集,要么都在验证集。这样才能反映模型面对新刺激时的表现。

DEAP是被试内设计,同一个人的40个试验对应40个不同视频,所以可以按试验划分,也可以按被试划分。按被试划分更严格,能测试模型的跨个体泛化能力,但难度明显更高,准确率会掉不少。我的项目里两种模式都实现了,默认是按试验划分的5折交叉验证,因为这样和参考文献结果更可比。如果你打算做跨被试实验,建议在代码里设置group_by='subject',然后在GroupKFold的groups参数里传被试ID。

阈值的选择也会影响模型性能。中位分割是最常见的,但DEAP中有的被试评分偏乐观,平均分远超5,这时候如果统一用5来二分,高/低类别就可能不平衡。我写了一个compute_median_split()函数,先统计每个被试的评分分布,然后打印出正负样本比例,方便你决定是否改用被试内中位数。我通常用全体被试的中位数做统一阈值,这样便于和别人对比;如果你更关注个体差异,可以用被试内阈值。

4.3 模型选型:SVM、随机森林与PyTorch小网络

分类模型方面,我对比了三种:线性SVM、随机森林、一个简单的两层全连接网络。为什么先用SVM?因为特征维度几百维,样本量(用窗口之后大概3万多个样本)并不算大,线性SVM已经有非常成熟的理论和实现,训练快、参数少,适合作为baseline。随机森林则能自动捕捉特征交互,且对归一化不敏感,作为第二个参考。

实际的准确率大致范围是这样的:在DEAP上做valence二分类,大多数论文在75%到85%之间,arousal也类似。我自己跑的线性SVM大约在77%~82%,随机森林能够到80%左右,两层全连接网络略微提升到82%~84%。这里要注意,不同预处理、分段方式、被试划分策略会带来很大差异,所以不要纠结小数点,关键是同一流程下对比方法才有意义。比如我试过把窗口长度从4秒改成6秒,准确率会提升1%左右,但样本量减少三分之一。

深度学习网络我的做法是:输入层接352维特征,中间两个全连接层,分别为128和64,激活函数ReLU,输出层2分类,加Dropout(0.5)。训练用Adam,学习率1e-3,batch size 256,早停在10轮内验证集loss不下降。这个结构很小,CPU都能跑,但效果已经足够好。如果想进一步提升,可以换成LSTM或Transformer处理原始时序,但数据量和算力需求会大幅上升。我在项目里用PyTorch实现了这个简单模型,训练一个fold大概只需要2分钟。

5. 结果评估与复现细节:准确率之外还要看什么

5.1 评价指标的坑:不平衡与随机种子

DEAP的valence和arousal评分中位数分割后,正负样本比例通常接近1比1,但具体到每个被试会略有偏差。如果你只用准确率,很容易忽略少数类被牺牲的问题。我建议同时看F1-score和AUC。二分类的AUC对阈值不敏感,更能反映模型排序能力。我在项目里统一输出 accuracy、precision、recall、F1、AUC 五行指标,训练时早停也以F1为准。

随机种子在DEAP任务里影响比想象中大。因为样本划分方式多,对照组之间的差异可能完全来自种子差异。我反复测过,同一流程换不同随机种子,准确率波动可以达到2到3个百分点。所以论文里如果只报告单次结果,可信度是存疑的。我在项目里默认使用42作为种子,并且把数据划分函数封装好,保证任何人clone后跑出来的结果一致。这个可复现性,对开源项目来说非常重要。

曾经有位同学跑完项目后跟我说准确率比我的低5个百分点,我排查后发现是他用了新的scikit-learn版本,GroupKFold的分组方式在高版本里不会乱序,但SVM的默认随机状态不同,导致结果不同。后来我在代码里显式设置所有模型的random_state=42,并且把版本号写进requirements里,这个问题才消停。所以做实验的时候,最好把环境依赖固定住,否则后续很难定位是算法问题还是版本问题。

5.2 特征重要性分析和冗余性

随机森林模型可以输出特征重要性,我看了下贡献最大的特征基本集中在gamma频段的微分熵、beta频段PSD,以及前额叶和颞叶通道。这也印证了DEAP相关研究里“高频活动与情绪唤醒度相关”的结论。但特征重要性不能直接当作因果关系,因为特征之间高度共线,比如PSD和DE本来就源于同一段信号。在部署到低功耗设备时,可以只保留top50特征,准确率下降通常不到1个百分点,这为后续边缘端应用提供了一条压缩路径。

如果你的特征维度更高,可以做PCA或LDA降维。但在我这个项目里,352维已经不算高,直接用原始特征就行。如果用了滑动窗口,特征之间会存在时间相关性,这时候用PCA可能反而会把时间结构抹掉,所以要根据任务灵活选择。我在项目里加入了一个--feature_reduction参数,可选 pca 或 none,方便对比实验。

另一个容易被忽略的问题是特征归一化。SVM对特征尺度很敏感,我建议在进入SVM之前做StandardScaler;随机森林和神经网络对尺度不敏感,但神经网络内部仍然建议做归一化,因为能加速收敛。DEAP里不同通道的信号幅值差异很大,尤其是GSR和EEG的量纲完全不同,如果不归一化,SVM的权重会被大幅值通道主导。我在项目里把归一化和特征提取写在一个Pipeline里,避免未来复用代码时遗漏这一步。

5.3 复现项目时常见的坑:版本依赖与数据路径

有人clone了sentimentclassify仓库后跑不起来,我排查发现有几个高频问题:一是scipy版本过新,导致loadmat时对某些结构数组字段名做了改动;二是没有安装hdf5storage,读取.mat文件报错;三是数据集路径和配置里的相对路径不一致。我的建议是:严格看 requirements.txt,创建干净环境,然后从 config.py 里设置DEAP文件夹路径。读取数据后用我提供的 sanity_check() 函数打印数组shape,这一步能解决90%的启动问题。我在项目里把数据处理、特征提取、训练、评估都拆成了独立模块,方便在Jupyter里交互调试,也方便命令行一键运行。

还有一次,用户反馈说加载标签时列名对不上,因为他下载的participant_ratings.csv是从另一个镜像拿到的,列名是英文全称而不是简称。我在代码里用索引提取后四列而不是列名,这样即使列名略有不同也能兼容。如果你要自己改代码,记住最稳妥的方式是读成DataFrame后打印.columns,别用肉眼去猜。

6. 从实验室到真实场景:模型部署与后续扩展

6.1 实时情绪识别系统的基本架构

DEAP是离线研究数据集,但很多人最终目标是想做一个实时的情绪识别demo。基于这个项目,我搭了一个简单的实时识别链路:采集端用便宜的单通道EEG设备,比如NeuroSky或者OpenBCI,先把信号按4秒滑动窗口缓存,然后做同样的0.5-45Hz滤波和分段,特征提取直接复用项目里的FeatureExtractor模块,用训练好的SVM模型做预测。这里有个关键差异:实时采集的通道数量可能只有1到4个,而模型训练时用了32个EEG通道,直接套用会维度不匹配。

解决办法有两个:一是重训一个适用于少量通道的模型;二是用特征投影,把单通道特征映射到空间模板上,但这非常 hack,效果不可控。我实际建议是使用支持少量电极的公开预训练模型,或者自己采集少量数据做迁移学习,把DEAP学到的频段特征先冻结,再加一个适配层微调。这也是情绪识别落地里比较现实的路线。我尝试过用OpenBCI的4个前额电极重训模型,valence准确率大概60%左右,明显低于32通道,说明通道数对性能影响很大。

实时系统的另一个问题是延迟。如果窗口长度是4秒,那么你至少要等4秒才能输出一次结果,这在应用里可能太慢。可以改成1秒窗口+3秒重叠,但特征稳定性会下降。折中的方案是计算累积统计量,比如最近5秒的平均特征,这样既保证响应速度,又能平滑噪声。部署时还要注意模型的输出不能是硬分类,最好给出概率,后接一个滑动平均滤波,避免情绪标签频繁跳动。

6.2 多模态融合的尝试与收益

DEAP包含了眼电、肌电、皮电、呼吸等多种外周信号,多模态融合是刷性能的常见思路。我试过简单的特征拼接融合:把EEG的352维特征和后8通道的时域特征(均值、方差、峰值)拼起来,输入SVM。在valence二分类上准确率比仅用EEG高出约1.5个百分点,在arousal上提升更明显,约2到3个百分点。这说明外周信号对唤醒度的编码确实更直接,比如皮电和心率本身就受自主神经控制。

但多模态融合也带来工程复杂度:不同信号采样率不同,特征时间尺度不同,后期如果做在线系统,还要处理传感器延迟。所以我的建议是:如果目标是发论文,可以加多模态;如果目标是落地到可穿戴设备,优先把单体模态做扎实,再考虑融合。另外,多模态融合时特征之间可能存在互补,也可能存在冗余,我建议用互信息或者LASSO做一个特征筛选,而不是盲目拼接。

如果你真的要复用DEAP的多模态部分,要注意后8个通道的具体顺序。我踩过的坑是:第33通道是EOG,第34通道是EMG,第35通道是GSR,第36通道是呼吸,第37通道是脉搏,第38通道是体温,后面还有两个可能是其他信号,不同资料会有差异。一个很笨但有效的办法是画出每个通道的信号波形,和人体的生理特征对照,基本能认出来。这个步骤虽然费时间,但能避免你用错信号。

6.3 模型轻量化与部署心得

训练好的SVM模型只有几百KB,部署非常容易。全连接网络模型经过剪枝和量化后也可以压到1MB以下。我用ONNX把PyTorch模型导出,在树莓派4上推理一帧特征平均耗时不到5ms,这个量级对于实时情绪识别完全够用。关键点是在导出前要把预处理里的滤波器和特征提取同步导出,因为实际部署时,前端信号处理往往比分类模型更容易出问题。如果能用C++重写滤波器,配合TFLite或ONNX Runtime,整个端到端延迟可以控制在100ms内。

模型轻量化方面,有一个小技巧是只保留特征重要性top50特征,重新训练一个线性SVM。这样一来,不仅模型体积更小,推理时也只需要计算50维特征,省掉了大量PSD计算。我用这个方法把单次推理时间从15ms降到了2ms,准确率只下降了不到1个百分点。如果你的设备算力非常有限,这个压缩路径值得一试。

部署时的坑主要在环境依赖和内存泄漏。树莓派上如果跑Python,最好用虚拟环境并且提前安装好scipy和numpy的ARM版本,否则编译会很痛苦。如果做长期运行,要注意在循环里释放特征矩阵,避免内存膨胀。我遇到过跑了一晚上之后内存占用从200MB涨到2GB的情况,后来发现是特征提取函数里保留了历史结果,加了一个del()gc.collect()就解决了。

最后说一点个人经验,在部署这类模型时,模型的“黑盒”程度要和你对应用场景的责任挂钩。如果是辅助心理放松的小工具,偏差一点无所谓;但如果你要做医疗或健康相关的判断,记得一定把输出去重化,并且加入用户校准流程。情绪本身是个高度主观且个体差异巨大的概念,别指望一个在DEAP上训练的模型能直接对谁都准。更好的做法是让用户先做几轮简单诱导,采集用户自己的基线数据来做自适应校准,这样模型在个体上的表现会稳定很多。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询