SEED-V数据集下载 时频联合编码和空间、时间并行注意力学习脑电表示

SEED-V数据集下载:https://gitee.com/CodeStoreHub/cbra-mod-seedv

算法源码下载:https://gitee.com/CodeStoreHub/cbra-mod-seedv

通过时频联合编码和空间、时间并行注意力学习脑电表示,加载预训练权重,在原始 EEG 上完成五类情绪识别。本文覆盖模型原理、数据处理、环境安装、训练流程及本次五种子实验的完整结果。

全参数微调FP321 秒 EEG 片段GPU0 顺序训练

62EEG 输入通道

200 Hz模型输入采样率

117,744处理后的样本总数

5 类情绪识别任务

01

算法原理

保留通道与时间结构,融合波形和频谱信息。

CBraMod 是一个 EEG 表示学习模型。首先在大量无标签脑电上通过掩码重建学习基础表示,再用有标签数据微调分类模型。核心由时频 patch 编码、非对称条件位置编码(ACPE)和 Criss-Cross Transformer组成。

输入 EEGB, C, N, 200

时频编码200 维 / patch

ACPE通道 × 时间邻域

Transformer12 层 / 双分支

情绪分类5 类 logits

1.1 以 1 秒为单位分块

设 EEG 有 C 个通道,每个通道分成 N 个不重叠时间片段。输入形状为 [B, C, N, 200],每个 patch 是一个通道的 1 秒波形。通道和时间片段组成二维网格,为不同方向的依赖建模提供明确结构。

EEG 分块与建模策略。 同一时间沿通道方向形成空间条带,同一通道沿时间方向形成时间条带。

1.2 时域与频域联合编码

时域分支:学习波形变化

三层卷积配合 GroupNorm 和 GELU。沿采样点方向进行卷积,提取一个 patch 内部的局部变化,输出 200 维表示。

实现采用 Conv2d 的 (1, k) 核;这一步不跨不同 EEG 通道卷积。

频域分支:学习频谱结构

对 200 点波形进行实数 FFT,取 101 维幅值谱,经线性投影和 Dropout 得到 200 维表示,与时域表示相加。

计算:abs(rfft(x, norm='forward'))。输入是幅值谱,并非预先提取的 DE 特征。

E = Etime + Efrequency ; E ∈ ℝB×C×N×200

1.3 ACPE:从当前输入生成位置编码

ACPE 将特征调整为 [B, 200, C, N],使用深度可分组二维卷积生成位置编码,再加回原特征。卷积核 (19, 7)、padding (9, 3)、groups 200,在通道方向取较长邻域,在时间方向取较短邻域。

条件位置编码随输入特征生成,能够适应不同通道数和时间片段数。其通道轴对应输入的排列顺序;没有直接引入电极在头皮上的二维几何坐标。

Epositioned = E + DWConv19×7(E)

1.4 空间与时间注意力并行计算

Criss-Cross Transformer。 空间分支关注同一时间的不同通道,时间分支关注同一通道的不同时间片段,拼接输出后进入残差和前馈网络。

  • **空间注意力:**固定时间片段,在各通道间计算注意力,学习不同脑电通道之间的依赖。
  • **时间注意力:**固定通道,在各时间片段间计算注意力,学习该通道的时间变化。
  • **分支融合:**200 维特征分为两个 100 维分支,每个分支有 4 个注意力头;两路输出拼接回 200 维。
  • **块内更新:**采用 pre-norm、残差连接和前馈网络,堆叠 12 层,使不同方向的信息通过特征更新融合。

| 模型配置 | 实际值 |
| 隐藏维度 / 前馈中间维度 | 200 / 800 |
| Transformer 层数 | 12 |
| 空间 / 时间注意力头 | 4 / 4,每头 25 维 |
| ACPE 卷积核 / padding | (19, 7) / (9, 3) |
| SEED-V 分类头 | 12400 → 800 → 200 → 5;隐藏层使用 ELU 和 Dropout |

完整模型参数数 14,965,805;backbone 4,883,800,分类头 10,082,005

1.5 掩码重建预训练与分类微调

掩码表示学习流程。 先学习恢复缺失脑电片段的能力,再将表示用于监督分类。

基础预训练使用 TUEG 脑电,输入为 [B, 19, 30, 200],即 19 个通道、30 秒信号。随机遮蔽约 50% 的 patch,以重建头恢复被遮蔽波形,仅对被遮蔽部分计算均方误差(MSE)。

本次实验加载已有预训练权重,将重建头替换为分类头,并微调整个模型。训练使用带标签平滑的交叉熵,输出为五个情绪类别的 logits。

本次 SEED-V 输入的时间轴只有一个 patch。

实际输入为 [B, 62, 1, 200],经过 backbone 后展平为 [B, 12400]。时间注意力序列长度为 1,不在不同训练样本之间建模;单个 1 秒波形内部的时间变化由时域编码器提取。

02

SEED-V 数据集

以视频诱发情绪,使用原始脑电完成五分类。

SEED-V 包含 16 名被试,每人参加 3 个会话,每个会话观看 15 个视频片段,对应五类情绪。原始 EEG 使用 Neuroscan 设备记录,本项目处理 48 个 CNT 文件,保留 62 个脑电通道。原始采样率为 1000 Hz,模型输入统一为 200 Hz。

0 厌恶 · Disgust1 恐惧 · Fear2 悲伤 · Sadness3 中性 · Neutral4开心 · Happiness

数据文件命名为 被试编号_会话编号_日期.cnt,例如 1_1_20180804.cnt。会话编号由刺激材料分组决定,不应直接当成按日期排列的时间序号。原始数据中的视频起止时间与情绪顺序用于切片和赋标签。

2.1 本次使用的数据形式

本次输入:原始 EEG

CNT → 去除辅助通道 → 重采样与滤波 → 按视频试次截取 → 不重叠的 1 秒片段 → LMDB。

其他数据形式

数据包还包含提取的 DE 特征和眼动相关数据。本次训练直接读取 EEG 波形,没有使用 DE 特征或眼动融合。

2.2 按试次划分训练、验证与测试

每个会话按视频试次固定划分,先划分完整试次,再生成 1 秒样本。每个种子将全部被试与会话的数据汇总,训练一个分类模型。

训练试次 1--5 · 34,432 样本

验证试次 6--10 · 42,960 样本

测试试次 11--15 · 40,352 样本

| 划分 | 厌恶 | 恐惧 | 悲伤 | 中性 | 开心 | 合计 |
| 训练 | 5,824 | 5,600 | 11,440 | 7,488 | 4,080 | 34,432 |
| 验证 | 7,440 | 10,896 | 9,792 | 5,936 | 8,896 | 42,960 |
| 测试 | 6,544 | 7,584 | 9,440 | 10,256 | 6,528 | 40,352 |

总计 19,808 24,080 30,672 23,680 19,504 117,744
[完整数据的类别分布]

结果适用于当前试次划分。

训练、验证、测试包含相同被试。这里的成绩不能解释为跨被试 LOSO 或跨会话泛化结果。各类样本数不同,因此评估同时报告平衡准确率、Kappa 和加权 F1。

03

环境安装

新机器使用独立环境;已有服务器可复用实际训练解释器。

| 组件 | 本次实际版本 / 配置 |
| Python / PyTorch | 3.9.25 / 2.5.1 |
| CUDA runtime / GPU | 11.8 / NVIDIA RTX 3090,24 GB,仅 GPU0 |
| NumPy / SciPy | 1.26.4 / 1.13.1 |
| MNE / LMDB | 1.8.0 / 3.0.0 |
| scikit-learn / einops | 1.5.2 / 0.8.2 |

matplotlib / tqdm 3.9.4 / 4.70.1

命令均在项目根目录执行。新机器需已有 Conda、Git、curl 和可用的 NVIDIA 驱动。原始 CNT 约 37.67 GiB,最终 LMDB 约 11.24 GiB;首次处理还有一份同等大小的中间分片,建议预留至少 65 GiB 空间。

01创建独立 Python 环境

BASH · 新机器环境复制

复制代码
conda create -n cbramod-seedv python=3.9.25 pip -y
conda activate cbramod-seedv

python -m pip install torch==2.5.1 \
  --index-url https://download.pytorch.org/whl/cu118

python -m pip install -r requirements.txt
python -m pip check

先安装 CUDA 11.8 版本的 PyTorch,再安装其他依赖。该流程不编译自定义 CUDA 扩展。安装方法匹配公开包版本;原环境使用的 Conda 构建与新 pip wheel 不保证二进制完全相同。

02验证仅 GPU0 可见

BASH + PYTHON · CUDA 检查复制

复制代码
CUDA_DEVICE_ORDER=PCI_BUS_ID CUDA_VISIBLE_DEVICES=0 python - <<'PY_GPU'
import torch
assert torch.cuda.is_available(), "CUDA 不可用"
assert torch.cuda.device_count() == 1, "仅允许一个可见 GPU"
print("PyTorch:", torch.__version__)
print("CUDA runtime:", torch.version.cuda)
print("GPU:", torch.cuda.get_device_name(0))
print("计算检查:", torch.ones(4, device="cuda:0").sum().item())
PY_GPU

本机已有 .venv/bin/python 是实际训练解释器,继承原有环境中的 PyTorch。继续使用本机代码时,可以将指南中的 python 换为 .venv/bin/python;新机器按上述步骤安装独立环境。

03准备固定版本实现与预训练权重

当前项目已经包含源码和权重。只在对应目录或文件缺失时执行以下命令:

BASH · 固定版本实现复制

复制代码
mkdir -p upstream
git clone https://github.com/wjq-learning/CBraMod.git upstream/CBraMod
git -C upstream/CBraMod checkout b9e961003214326972c567eff390e75b0287e32a

BASH · 预训练权重复制

复制代码
mkdir -p artifacts/pretrained
curl -fL --retry 3 \
  https://huggingface.co/weighting666/CBraMod/resolve/main/pretrained_weights.pth \
  -o artifacts/pretrained/pretrained_weights.pth

sha256sum artifacts/pretrained/pretrained_weights.pth

本次预训练权重的 SHA-256:0792cb808c14e6b7a2bb2ce1dff379bc47bc54c49a779825bdfeb33bf8157178。

04

数据预处理

固定通道、采样率、时间戳和存储精度,获得一致的模型输入。

  1. 读取完整 CNT,删除 M1/M2/VEO/HEO,保留原排列顺序的 62 个 EEG 通道。
  2. 先重采样到 200 Hz,再进行 0.3--75 Hz FIR 带通。
  3. 读取微伏值,根据视频起止时间截取试次,并沿用固定标签顺序。
  4. 切成不重叠的 1 秒样本,每个样本形状为 (62, 1, 200)。
  5. 保存 float64 数组至 LMDB;训练读取时执行微伏值 /100,再转为 float32。

流程没有额外的重参考、notch、z-score 或数据增强。对 7_1_20180411.cnt 的异常样本数字段,仅在内存中按已核验布局恢复 3,527,400 个 int32 样本;原始文件不改写,其余 47 个文件使用原读取器。

4.1 在新机器生成完整 LMDB

将 48 个 CNT 放入 data/SEED-V/EEG_raw/。下面的命令用于首次处理;输出目录和分片目录需为空。四个 CPU worker 处理连续排序的文件子集,最终按原顺序合并。

BASH · CPU 预处理复制

复制代码
export OMP_NUM_THREADS=2
export OPENBLAS_NUM_THREADS=2
export MKL_NUM_THREADS=2

python -u scripts/preprocess_cbramod_parallel.py \
  --raw-dir data/SEED-V/EEG_raw \
  --shards data/SEED-V/CBraMod/.shards \
  --output data/SEED-V/CBraMod/processed_parallel \
  --artifacts results/cbramod/preprocessing_parallel \
  --workers 4

本机已有完整数据,可跳过预处理。

直接使用 data/SEED-V/CBraMod/processed_parallel。若重做数据,请为 output、shards 和 artifacts 指定新目录;内存不足可以将 workers 改为 1,仍保留同样的 CNT 兼容读取流程。

4.2 完成后的数据检查

本次对 117,744 个样本验证了形状、float64 类型、有限值、类别计数及分片合并后的保存字节,差异数为 0。完整划分为 34,432 / 42,960 / 40,352。训练只读取合并后的 LMDB;已清理的中间分片不影响训练,但不能再用于单独合并。

05

训练指南

固定五个种子、完整训练 50 轮,按验证 Kappa 选择权重。

5.1 启动一次新的五种子实验

使用新的结果目录 results/cbramod_new,保留已经完成的 results/cbramod。以下命令逐个运行种子 3407--3411:

BASH · GPU0 / 五种子 / 顺序执行复制

复制代码
export CUDA_DEVICE_ORDER=PCI_BUS_ID
export CUDA_VISIBLE_DEVICES=0

python -u scripts/run_cbramod_seedv.py \
  --data-dir data/SEED-V/CBraMod/processed_parallel \
  --checkpoint artifacts/pretrained/pretrained_weights.pth \
  --results results/cbramod_new \
  --seeds 3407 3408 3409 3410 3411 \
  --jobs 1 --epochs 50 --batch-size 64 \
  --lr 1e-4 --weight-decay 0.05 \
  --optimizer AdamW --clip-value 1.0 \
  --dropout 0.1 --label-smoothing 0.1

训练入口自身强制仅 GPU0 可见,子进程使用逻辑 cuda:0 并核对可见设备数。--jobs 1 表示五个独立训练进程顺序执行;每个种子都有独立随机状态、验证结果和权重。

请显式传入完整数据目录。

使用 --data-dir data/SEED-V/CBraMod/processed_parallel。脚本旧默认目录为 processed,而本次完整数据保存在 processed_parallel。

5.2 训练参数

| 参数 | 实际配置 |
| 训练轮数 / batch | 50 / 64 |
| 优化器 | AdamW;betas=(0.9, 0.999),eps=1e-8 |
| Backbone 初始学习率 | 1e-4 |
| 分类头初始学习率 | 5e-4;由 0.001 × sqrt(batch / 256) 生成 |
| Weight decay / dropout | 0.05 / 0.1 |
| Label smoothing / 梯度 norm 上限 | 0.1 / 1.0 |
| 学习率调度 | CosineAnnealingLR,逐 batch 更新;eta_min=1e-6 |
| 更新范围 / 精度 | Backbone 与分类头全部微调 / FP32 |

选模与测试 50 次验证;验证 Kappa 最高的权重;最终测试一次

验证 Kappa 相同则保留最早的 epoch;选中的 Kappa 必须高于实现的初始值 0。训练结束后恢复选中模型,测试集不参与模型选择。--lr 控制 backbone 学习率,分类头使用 multi_lr 规则。

5.3 汇总与指标校验

五个种子完成后,训练入口自动生成 JSON 和 CSV 汇总。需要再次汇总新实验时,执行:

BASH · 结果汇总及校验复制

复制代码
python scripts/summarize_cbramod.py --results results/cbramod_new
python scripts/audit_cbramod_results.py --results results/cbramod_new

校验工具从整数混淆矩阵独立复算三项指标,核对验证选模、最终测试、权重和日志哈希、均值及标准差。当前校验面向五种子、每种子 50 次验证的标准协议;不要使用 python -O,它会禁用断言检查。

5.4 复核本机已完成的结果

BASH · CPU 校验,不重新训练复制

复制代码
.venv/bin/python scripts/audit_cbramod_results.py \
  --results results/cbramod

.venv/bin/python results/cbramod/analysis/plot_results.py \
  --validate-only

关于重复运行、恢复和数据保护

06

本次实验结果

汇总全部五次独立运行,报告均值与样本标准差。

平衡准确率 · Balanced Accuracy40.00%样本标准差 ± 0.94 个百分点

Cohen's Kappa0.2548样本标准差 ± 0.0136

加权 F1 · Weighted F140.65%样本标准差 ± 1.32 个百分点

6.1 五个种子的最终测试成绩

| 种子 | 选中 epoch | 平衡准确率(%) | Kappa | 加权 F1(%) |
| 3407 | 29 | 40.97564 | 0.26874278 | 41.88868 |
| 3408 | 22 | 40.15886 | 0.25883325 | 41.07484 |
| 3409 | 29 | 40.67357 | 0.26328254 | 41.49188 |
| 3410 | 18 | 39.61104 | 0.24929597 | 40.23669 |
| 3411 | 10 | 38.60043 | 0.23402655 | 38.54670 |

均值 ± 样本标准差 --- 40.00391 ± 0.94086 0.25483622 ± 0.01364227 40.64776 ± 1.32460
[验证选模后的测试结果]

标准差采用 ddof=1,描述五次运行之间的波动;它不是置信区间。全部五次均纳入均值,没有用最优单次成绩代替整体结果。

6.2 指标如何解释

| 指标 | 含义 | 日志字段 |
| 平衡准确率 | 五类 recall 的算术平均,各类贡献相同,适合类别数量不均衡的情况。 | acc |
| Cohen's Kappa | 根据真实和预测类别分布校正偶然一致性的指标,0 对应其机会一致水平。 | kappa |

加权 F1 各类 F1 按真实类别样本数加权,综合反映 precision 与 recall。 f1

6.3 完整训练与验证曲线

每个种子都训练满 50 轮。 所选 epoch 为 29、22、29、18、10;标记由验证 Kappa 决定,测试成绩不参与选模。训练 loss 来自日志,保留五位小数。

6.4 平均测试混淆行为

行是真实类别,列是预测类别。 先按每个模型的真实类别数量逐行归一化,再对五个模型等权平均。它描述五次模型的平均表现,不是额外集成模型的预测结果。

从类别平均 recall 看,恐惧类别约为 22.87% ,悲伤类别约为 53.01%,说明不同情绪类别的识别难度存在明显差异。评估时应同时查看总体指标和类别混淆行为。

结果的适用范围

这些数值对应当前固定试次划分、公开预训练权重、软件版本和训练参数。它们不代表跨被试成绩,也不能直接替代其他数据划分或训练配置的测量。

07

代码与结果文件

训练入口、数据路径、结果记录及必要的实现适配。

| 位置 | 用途 |
| scripts/preprocess_cbramod_parallel.py | 推荐的 CNT 预处理入口,支持 CPU 分片和兼容读取。 |
| scripts/run_cbramod_seedv.py | 固定配置,生成外部适配,顺序执行训练,最后汇总。 |
| scripts/train_cbramod_seed.py | 调用训练器和评估器,记录完整精度的指标与混淆矩阵。 |
| scripts/summarize_cbramod.py | 汇总五次成绩、均值、样本及总体标准差。 |
| scripts/audit_cbramod_results.py | 独立复算指标,校验选模和产物哈希。 |
| data/SEED-V/EEG_raw | 48 个原始 CNT。 |
| data/SEED-V/CBraMod/processed_parallel | 本次实际使用的完整 LMDB。 |
| results/cbramod/summary.json results/cbramod/summary.csv | 五种子结果与汇总统计,JSON 保留完整精度。 |
| results/cbramod/seed_3407 ... seed_3411 | 每次运行的权重、训练日志、评估记录和 run.json。 |

artifacts/environment 实际软件版本和环境记录。

保留数值行为的外部适配

  • 删除 forward 中多余的展平,让分类头的 Rearrange 接收到四维特征;分类器结构和参数不变。
  • 三个数据视图共享同一个只读 LMDB 环境,避免同进程重复打开问题。
  • CPU 分片、每试次事务与原字节合并改善数据处理效率。
  • 对一个异常 CNT 头部采用限定的内存读取修正。
  • 记录评估器返回的完整精度结果,避免仅从五位小数日志汇总指标。

CBraMod · SEED-V 脑电情绪识别中文离线指南 · 文档整理 2026-10-13

相关推荐
LONGZHIQIN2 小时前
Python学习笔记
笔记·python·学习
czt_java2 小时前
网络基础入门:IPv4、IPv6、私网公网、MAC、以太网帧与 DNS 学习笔记
网络·学习·macos
我命由我123453 小时前
LRU 缓存淘汰策略
数据结构·redis·学习·mysql·算法·缓存·学习方法
一木 之林3 小时前
微信小程序开发全攻略·文章版|01 入门与环境搭建
人工智能·学习·计算机视觉·微信小程序·notepad++
Xudde.3 小时前
Quaoar 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全
遇印记3 小时前
网络安全,数据链路层,物理层
运维·服务器·网络·windows·学习
cc5725026533 小时前
2027校招:大数据管理与应用转财务数字化,会计业务、SQL与BI学习路线
数据库·sql·学习
Swilderrr4 小时前
论文精读 | Fast Approximate Similarity Join in Vector Databases(SimJoin)
笔记·学习
外收内放4 小时前
数据分析(DataFrame与series)
python·学习·数据分析