首页/新闻资讯/正文详情

SEED EEG情绪识别源码实战:DE特征+SVM与原始EEG+CNN双路线

发布时间:2026/9/26 16:41:51 来源:云帆数科 栏目:资讯中心
SEED EEG情绪识别源码实战:DE特征+SVM与原始EEG+CNN双路线
简介这份源码资源面向计算机、人工智能及相关专业的学生与开发者聚焦在SEED脑电数据集上完成情绪识别任务可满足毕业设计、期末大作业与课程设计等场景需求。项目经过本地编译验证可运行评审得分达到98分难度适中内容经助教老师审定适合作为入门脑电信号处理与深度学习的实践参考。资源包共17个文件包含4个Python脚本、7个XML配置、2个TXT记录、1个DOCX文档及README说明等涵盖数据读取、SVM与CNN两条实验路线及结果记录压缩包约10.65MB目录结构清晰便于按模块查阅。目前已有317人学习关注。读者可从中获得完整的情绪识别实现流程包括DE特征提取与SVM分类、原始EEG的CNN建模、训练日志与结果对比文档以及项目配置与依赖说明便于快速复现实验并在此基础上做二次开发或论文撰写。1. 从一份 98 分的 SEED 情绪识别源码说起它到底能跑出什么如果你正在做 EEG 情绪识别方向的毕业设计或课程设计大概率绕不开 SEED 数据集。这份源码包就是围绕 SEED 做的一套完整实验流程一条线走传统机器学习de_LDS_SVM.py一条线走深度学习raw_eeg_CNN.py外加utils工具模块和results结果记录。它不是那种只丢一个模型文件让你自己猜输入输出的空壳而是把数据读取、特征提取、训练、评估、结果落盘都串起来了。我拿到手第一件事是看目录结构code放脚本results放 CNN 和 SVM 的结果记录log放 TensorBoard 事件文件根目录有README.md和readme.txt。这种布局说明作者是按“能复现”的思路整理的不是随手打包。适合谁适合已经了解 EEG 基本概念、需要一份能跑通 baseline 的从业者也适合赶毕设进度、想先有个能出结果的项目再往上改的同学。难度适中但前提是你得把 SEED 数据本身准备好。2. SEED 数据集与情绪识别任务先把输入输出对齐2.1 SEED 的标签体系和被试划分SEED 数据集的核心是 15 名被试观看中文电影片段时的 62 通道 EEG 信号采样率 200Hz。每个被试有 3 个 session每个 session 包含 15 个 trial对应三类情绪消极negative、中性neutral、积极positive。标签文件通常是每个 trial 一个.mat里面存着labels字段。这里有个容易翻车的地方SEED 的标签不是按时间点连续标注的而是按 trial 给一个整体标签。也就是说一个 trial 内所有时间点共享同一个情绪标签。很多新手拿到数据后想按秒切分再打标签结果发现标签对不上就是因为没理解这个粒度。常见做法是每个 trial 取中间稳定段比如去掉前 10 秒和后 10 秒剩下的时间点全部归为该 trial 的标签。这份源码里的utils模块大概率就是干这个的——读取.mat、对齐标签、做归一化。你拿到数据后先确认三件事被试数量、session 数量、每个 trial 的采样点数。这三个数对不上后面全白搭。2.2 两条技术路线的选型理由源码给了两条线不是让你二选一而是让你对比。de_LDS_SVM.py走的是传统路线DE微分熵特征 LDS线性动态系统平滑 SVM 分类。DE 特征在 EEG 情绪识别里是经典选择因为它对低频段delta、theta、alpha、beta、gamma的能量变化敏感而情绪相关的脑电变化主要集中在这几个频段。LDS 的作用是平滑时间序列减少 trial 内的波动。SVM 在小样本上表现稳定适合 SEED 这种每类样本量不大的场景。raw_eeg_CNN.py走的是端到端路线原始 EEG 信号直接喂给 CNN让网络自己学特征。这条路的好处是不依赖手工特征坏处是需要更多数据和调参。SEED 的样本量对深度学习来说偏小所以 CNN 的结构不会太深大概率是几层卷积加池化再接全连接。两条线的结果都放在results里你可以直接对比。如果 SVM 跑出来比 CNN 高别惊讶这在 SEED 上很正常。2.3 环境依赖与数据放置在跑代码之前先把环境搭好。这份源码是 Python 项目依赖不会太偏。我一般会先建一个干净的虚拟环境避免和系统里的包打架。# 创建虚拟环境 python -m venv seed_env source seed_env/bin/activate # Windows 用 seed_env\Scripts\activate # 安装核心依赖 pip install numpy scipy scikit-learn tensorflow torch matplotlib逻辑说明numpy和scipy用来读.mat文件和做信号处理scikit-learn提供 SVM 和评估指标tensorflow或torch看raw_eeg_CNN.py里 import 的是哪个。先装这两个跑的时候缺什么再补。参数说明虚拟环境名字随意但建议带seed前缀方便以后区分。Python 版本建议 3.8 到 3.10太新的版本某些科学计算库可能还没适配。数据放置SEED 数据需要你自己下载源码包里不含原始数据。下载后按README.md里的路径说明放好通常是data/SEED/下面按被试分文件夹。如果README.md写得不清楚就看utils里读文件的路径拼接逻辑反推数据该放哪。提示先跑utils里的数据加载函数确认能读到至少一个被试的数据再往下走。这一步能省掉后面 80% 的报错排查时间。3. 传统路线实操DE 特征提取与 SVM 分类3.1 DE 特征的计算与频段划分DE 特征的计算不复杂但频段划分和窗口长度有讲究。常见做法是分五个频段delta1-4Hz、theta4-8Hz、alpha8-14Hz、beta14-31Hz、gamma31-51Hz。每个频段算一个 DE 值62 个通道就是 62×5310 维特征。import numpy as np from scipy.signal import welch def compute_de_features(eeg_data, fs200, bandsNone): eeg_data: shape (n_channels, n_times) 返回: shape (n_channels, n_bands) if bands is None: bands [(1, 4), (4, 8), (8, 14), (14, 31), (31, 51)] n_channels eeg_data.shape[0] de_features np.zeros((n_channels, len(bands))) for i, (low, high) in enumerate(bands): # 对每个通道做功率谱估计 freqs, psd welch(eeg_data, fsfs, npersegfs*2) # 取频段内的平均功率 idx np.logical_and(freqs low, freqs high) de_features[:, i] np.log(np.mean(psd[:, idx], axis1) 1e-8) return de_features逻辑说明用 Welch 法估计功率谱密度取频段内平均功率再取对数。取对数是因为 DE 的定义本身就和功率的对数相关加1e-8是防止 log(0)。参数说明fs要和数据实际采样率一致SEED 是 200Hz。nperseg设为fs*2表示每 2 秒一个窗口这个可以调窗口太短谱估计不稳太长时间分辨率不够。bands的划分不是固定的你可以根据文献调整但五个频段是主流。3.2 LDS 平滑与 SVM 训练LDS 平滑这一步在源码里叫de_LDS本质是对 DE 特征序列做线性动态系统建模输出平滑后的特征。如果你不想深究 LDS 的数学可以把它理解为一个高级滑动平均目的是让特征在时间上更连续。from sklearn.svm import SVC from sklearn.model_selection import cross_val_score from sklearn.preprocessing import StandardScaler # 假设 X 是 (n_samples, n_features)y 是标签 scaler StandardScaler() X_scaled scaler.fit_transform(X) # SVM 用 RBF 核C 和 gamma 需要调 svm SVC(kernelrbf, C1.0, gammascale) scores cross_val_score(svm, X_scaled, y, cv5, scoringaccuracy) print(f交叉验证准确率: {scores.mean():.4f} ± {scores.std():.4f})逻辑说明先标准化因为 SVM 对特征尺度敏感。然后用 5 折交叉验证评估不要只看训练集准确率。参数说明C控制惩罚力度越大越容易过拟合gamma控制 RBF 核的影响范围scale是自适应值。如果准确率不理想优先调这两个。SEED 上 SVM 的 baseline 大概在 80% 到 90% 之间低于 80% 说明特征或标签有问题。注意交叉验证的划分方式要和你的实验目标一致。如果是跨被试实验不能用随机划分得按被试分。源码里如果用的是随机划分你改成按被试划分后准确率会掉这是正常的。3.3 结果记录与复现对照results里的SVM 结果记录.txt是作者跑出来的结果。你跑完后对照一下如果差距在 5 个百分点以内说明流程没问题。差距太大就按这个顺序排查数据读取是否正确、标签是否对齐、特征维度是否一致、标准化是否做了。4. 深度学习路线实操原始 EEG 喂给 CNN4.1 输入张量的形状与归一化raw_eeg_CNN.py的输入是原始 EEG 信号不是手工特征。SEED 一个 trial 大概是 62 通道 × 几千个时间点。CNN 的输入形状通常是(n_channels, n_times, 1)或者(n_times, n_channels, 1)取决于你用的是 Conv1D 还是 Conv2D。import numpy as np def prepare_cnn_input(eeg_trial, n_channels62, n_times2000): eeg_trial: shape (n_channels, n_times) 返回: shape (n_channels, n_times, 1) # 按通道做 z-score 归一化 mean eeg_trial.mean(axis1, keepdimsTrue) std eeg_trial.std(axis1, keepdimsTrue) 1e-8 normalized (eeg_trial - mean) / std # 截断或填充到固定长度 if normalized.shape[1] n_times: normalized normalized[:, :n_times] elif normalized.shape[1] n_times: pad_width n_times - normalized.shape[1] normalized np.pad(normalized, ((0, 0), (0, pad_width)), modeconstant) return normalized[..., np.newaxis]逻辑说明按通道归一化是因为不同通道的幅值差异大不归一化会让网络偏向大幅值通道。截断或填充是为了固定输入长度CNN 的全连接层需要固定维度。参数说明n_times根据你的 trial 长度定SEED 一个 trial 大概 2000 到 4000 个点。归一化用 z-score 是常见做法也可以用 min-max但 z-score 对异常值更稳。4.2 CNN 结构搭建与训练配置CNN 结构不会太复杂常见的是两到三层卷积每层后面接池化和 Dropout最后全连接分类。import tensorflow as tf from tensorflow.keras import layers, models def build_cnn(input_shape, n_classes3): model models.Sequential([ layers.Conv2D(32, (1, 5), activationrelu, input_shapeinput_shape), layers.MaxPooling2D((1, 2)), layers.Dropout(0.3), layers.Conv2D(64, (1, 5), activationrelu), layers.MaxPooling2D((1, 2)), layers.Dropout(0.3), layers.Flatten(), layers.Dense(128, activationrelu), layers.Dropout(0.5), layers.Dense(n_classes, activationsoftmax) ]) model.compile(optimizeradam, losscategorical_crossentropy, metrics[accuracy]) return model逻辑说明卷积核用(1, 5)是因为在通道维度上不做卷积只在时间维度上滑。这样每个通道独立提取时间特征符合 EEG 的空间分布特性。参数说明Dropout比例 0.3 到 0.5 是常规范围数据量小就调大。adam学习率默认 0.001如果 loss 震荡就降到 0.0005。n_classes3对应 SEED 的三类情绪。4.3 TensorBoard 日志与结果对照log目录里的events.out.tfevents文件是 TensorBoard 日志。跑完训练后可以用tensorboard --logdir log查看 loss 和 accuracy 曲线。如果曲线震荡厉害说明 batch size 太小或学习率太高。results里的CNN 结果记录.docx是作者的结果。对照时注意看作者用的是哪个被试、哪个 session不同划分方式结果差异很大。提示CNN 在 SEED 上不一定比 SVM 高如果低几个点不用慌先确认训练轮数和早停策略是否合理。5. 避坑与排查这份源码最容易翻车的五个地方5.1 数据路径不对导致读取为空现象跑de_LDS_SVM.py时报FileNotFoundError或者读到的数组 shape 是(0,)。原因SEED 数据需要单独下载源码包里只有代码。README.md里的路径是作者本机的相对路径和你放数据的位置不一致。解决打开utils里读文件的函数看它拼接路径的逻辑把你的数据放到对应位置。或者直接改路径变量指向你实际存放数据的目录。改完后先打印一个被试的数据 shape确认非空再往下跑。5.2 标签对齐错误导致准确率异常现象SVM 准确率只有 30% 多接近随机猜测。原因标签和特征没对齐。常见情况是特征按 trial 提取了但标签文件读进来顺序乱了或者 trial 编号和标签编号差了一位。解决在utils里找到标签读取的部分打印前几个 trial 的标签和特征对应的 trial 编号人工核对。SEED 的标签文件命名通常和 trial 编号对应如果用了sorted()排序注意字符串排序和数字排序的差异。5.3 频段参数不一致导致特征维度对不上现象SVM 训练时报ValueError: X and y have inconsistent numbers of samples或者特征维度和你预期的不一样。原因DE 特征提取时的频段划分和源码里后续处理用的频段不一致。比如你改了bands但没改下游的维度假设。解决把频段划分定义成一个全局变量所有地方引用同一个。改完后打印特征矩阵的 shape确认是(n_samples, 62*5)还是别的。5.4 CNN 输入形状不匹配现象raw_eeg_CNN.py报ValueError: Input 0 of layer conv2d is incompatible with the layer。原因input_shape和你实际喂进去的数据 shape 不一致。常见的是通道数和时间点数搞反了。解决在model.fit之前打印X_train.shape和build_cnn里的input_shape对比。如果用的是 Conv2D输入应该是(n_channels, n_times, 1)不是(n_times, n_channels, 1)。5.5 随机种子未固定导致结果不可复现现象每次跑出来的准确率都不一样差距还挺大。原因NumPy、TensorFlow 的随机种子没固定数据划分和权重初始化每次都在变。解决在脚本开头加上种子设置。import numpy as np import tensorflow as tf import random seed 42 np.random.seed(seed) tf.random.set_seed(seed) random.seed(seed)逻辑说明固定种子后数据划分和初始化可复现。但注意如果你用了 GPU某些操作的随机性无法完全消除结果可能有微小波动。参数说明seed选什么都行关键是整个实验统一用同一个。6. 进阶技巧把这份源码改成你自己的实验平台跑通只是第一步真正有价值的是把它改成能支撑你论文实验的平台。我一般会做三件事。第一把数据加载和特征提取抽成独立模块用配置文件控制参数。比如建一个config.yaml里面写频段划分、窗口长度、被试列表、交叉验证方式。这样你换数据集或者换被试子集时不用改代码只改配置。import yaml with open(config.yaml, r) as f: config yaml.safe_load(f) bands config[de][bands] fs config[data][fs] subjects config[data][subjects]逻辑说明配置和代码分离实验可追溯。参数说明bands写成列表的列表subjects写成被试编号列表。第二把 SVM 和 CNN 的评估统一成同一套指标。不要一个看准确率一个看 F1统一用准确率和混淆矩阵。混淆矩阵能告诉你哪类情绪容易混SEED 上常见的是中性容易被分到积极或消极。第三加一个简单的超参搜索。SVM 的C和gamma用网格搜索CNN 的学习率和 Dropout 比例用随机搜索。不用上贝叶斯优化网格搜索在小样本上够用了。from sklearn.model_selection import GridSearchCV param_grid { C: [0.1, 1, 10], gamma: [scale, 0.01, 0.001] } grid GridSearchCV(SVC(kernelrbf), param_grid, cv5, scoringaccuracy) grid.fit(X_scaled, y) print(f最优参数: {grid.best_params_}) print(f最优准确率: {grid.best_score_:.4f})逻辑说明网格搜索遍历参数组合交叉验证选最优。参数说明cv5是折数数据量小可以降到 3。从那以后我每次拿到一份新源码都强制先跑通一个最小闭环——一个被试、一个 session、一条路线——再往上加东西。这份 SEED 情绪识别源码的最小闭环就是utils读数据加de_LDS_SVM.py跑一个被试。闭环通了后面改 CNN、加被试、调参都是在这个基础上长出来的。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

支持Function Call的本地ollama模型对比评测:开发代理agent的配置与验证
支持Function Call的本地ollama模型对比评测:开发代理agent的配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:41:35

自建CRM系统实战:从Docker部署到团队落地全流程复盘
自建CRM系统实战:从Docker部署到团队落地全流程复盘

客户信息分散在微信聊天、邮件、Excel表格和个人便签里,需要回看半年前的沟通记录时,得来回切换四五个窗口,最后仍然拼不出完整过程——这是我决定认真部署一套CRM系统的直接导火索。DeskcommCRM 是我近期从选型、部署到逐步推广给团队使用的… · 2026/9/26 16:41:35

AI导航与语义SLAM技术进展:TaoToken统一Key接入ROS2 Nav2的配置与验证
AI导航与语义SLAM技术进展:TaoToken统一Key接入ROS2 Nav2的配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:41:35

Dism++深度清理Win10/Win11系统空间实战指南
Dism++深度清理Win10/Win11系统空间实战指南

1. 这不是“一键清理”广告,而是我用 Dism 救活三台濒临报废 Win10/Win11 电脑的真实记录Dism 不是杀毒软件,不是垃圾清理器,更不是那种点一下就弹出“您的C盘已释放87GB空间”的营销工具。它本质上是一个Windows 系统映像(WIM/ES… · 2026/9/26 17:45:12

OpenClaw 抓取任意网站不被屏蔽:零机器人检测配置实战
OpenClaw 抓取任意网站不被屏蔽:零机器人检测配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 17:45:06

CNN-GRU时序预测实战:从LSTM翻车到多变量预测的Python代码骨架
CNN-GRU时序预测实战:从LSTM翻车到多变量预测的Python代码骨架

简介:本资源面向从事时间序列预测的机器学习学习者与工程人员,提供一套基于Python与TensorFlow实现的CNN-GRU混合深度学习算法,将卷积神经网络提取局部特征的能力与门控循环单元建模时序依赖的优势结合,可用于风电功率、电力负荷等… · 2026/9/26 17:44:47

Atlas 300V部署YOLO实战:从环境搭建到性能优化
Atlas 300V部署YOLO实战:从环境搭建到性能优化

如果你是因为“atlas部署yolo”这个关键词点进来的,那么恭喜,你和我半年前一样,站在了一条完全陌生的起跑线上。Atlas 300V 24G,这块顶着神话巨人名字的板卡,既不是常见的游戏显卡,也不是那种上万的NVIDIA训… · 2026/9/26 17:44:41

Wan 3.0实战:30秒商品视频参考输入的分工指南
Wan 3.0实战:30秒商品视频参考输入的分工指南

把一件商品拍成30秒的动态视频,放在半年前还得靠实景棚拍、模特走位、灯光调度,现在用Wan 3.0这类视频生成模型,只要把参考图、参考视频、参考音频喂进去,就能直接“算”出一条能用的片子。但问题也在这儿——参考给了好几样&… · 2026/9/26 17:44:41

轨道交通GNSS平面控制网:从布网、基线解算到坐标转换避坑指南
轨道交通GNSS平面控制网:从布网、基线解算到坐标转换避坑指南

简介:这是一份关于轨道交通工程GNSS平面控制网布设与数据处理的专业学术文献,面向测绘工程、轨道交通建设及相关专业的测量技术人员和研究人员。资源以论文形式呈现,结合实际工程案例,系统讨论了城市轨道交通GNSS平面控制网的布设… · 2026/9/26 17:44:35

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码