TUH EEG-Corpus

TUH EEG Corpus — 全球最大开放临床脑电图数据集 AI-Ready Wikipedia | 千方病案医数集

来源 Temple University Neural Engineering Data Consortium (NEDC) 发布时间: 2026-08-10最后更新: 2026-08-10 阅读 1

信息速览

数据集名称TUH EEG-Corpus
数据类型约 500GB(全库),2.6 万份 EEG 记录,免费注册获取,支持商业用途
规模1.5 万名患者
接入方式Temple University Neural Engineering Data Consortium (NEDC)
AI 就绪度

INFOBOX

数据集名称 TUH EEG Corpus
英文全称 Temple University Hospital EEG Corpus
别名 / 简称 TUEG、TUH-EEG、NEDC EEG Corpus
疾病分类 8A00–8A0Z 癫痫与发作性疾病 / 8B00 神经系统症状与体征
SNOMED CT 85828005 癫痫 / 246505001 脑电图异常 / 128281000 非癫痫发作事件
数据模态 时序(临床头皮脑电图 EEG 信号 + 文本临床报告)
AI 任务类型 时序分类、事件检测、异常检测、多标签分类、域适应、基础模型预训练
样本总数 26,846 份 EEG 记录(TUEG 主库)/ 7,377 个 EDF 文件(TUSZ 子库)
数据大小 ~500 GB(TUEG 全库)/ ~81 GB(TUSZ 子库)
数据格式 EDF(欧洲数据格式,.edf)/ TXT(临床报告)/ CSV(标注,.csv + .csv_bi)
许可证 NEDC 开放数据许可(免费,注册后可下载,支持研究与商业用途)
访问级别 注册后开放(填写申请表 + 邮件发送签名副本 + rsync 下载,24-48 小时审批)
DUO 标签 GRU, NRES
语言 英文(临床报告文本)
首发日期 2016-05-13(Frontiers in Neuroscience)
最后更新 2024-05-20(资源整合页面更新)/ TUSZ v2.0.6
发布机构 Temple University Neural Engineering Data Consortium (NEDC)
官方主页 https://isip.piconepress.com/projects/tuh_eeg/
下载地址 https://isip.piconepress.com/projects/nedc/html/tuh_eeg/index.shtml
DOI 10.3389/fnins.2016.00196(TUEG)/ 10.3389/fninf.2018.00083(TUSZ)
引用次数 800+(Google Scholar,截至 2026-08,TUEG 原始论文)/ 350+(TUSZ 论文)
AI 就绪度评分 ⭐⭐⭐⭐(4/5)— 7 大子语料库覆盖全面、TUSZ 内置官方 Train/Dev/Eval 患者级划分、配套 NEDC 软件工具链;扣分项:异构采样率与通道数需标准化、标注由本科生完成(虽经验证但非执业神经科医生)、单中心来源
页面状态 published

§0 E-E-A-T 信任声明与免责声明

医学审核者:[千方病案医学编辑部]交叉审核:§2 医学背景(ICD-11 映射、癫痫临床任务定义、EEG 金标准描述)、§7 偏倚分析。

数据工程审核者:[千方病案医学编辑部交叉审核] 医疗 AI 数据工程师,审核范围:§4 DAIMS 数据字典、§5 数据划分策略、§6 预处理 Pipeline 和坑点。

审核日期:2026-08-04

医疗免责声明:本页面提供的医学信息仅供研究和教育目的,不构成医疗建议、诊断或治疗方案。数据集的医学描述基于公开发表的文献,未经逐一临床验证。任何基于该数据集训练的 AI 模型在应用于临床决策前,必须经过独立的临床验证和监管审批。

技术免责声明:本页面的代码示例、预处理建议和基准性能数据基于公开资料整理,不保证在特定环境下的准确性和适用性。使用者应自行验证代码安全性和数据预处理流程的正确性。千方病案医数集不对因使用本页面信息而导致的任何直接或间接损失承担责任。

数据使用合规:使用本页面描述的数据集前,请务必阅读并遵守数据集原始许可协议。TUH EEG Corpus 要求填写注册申请表并邮件发送签名副本。DUO 标签仅供参考,具体使用限制以数据集官方协议为准。

§1 数据集概览(Overview)

§1.0 📌 30 秒速览

TUH EEG Corpus 是 Temple 大学神经工程数据联盟(NEDC)自 2012 年起持续构建的全球最大开放临床脑电图数据集,包含 26,846 份来自 15,001 名患者的临床 EEG 记录,覆盖 2002-2017 年的采集数据,总体项目已扩展至超过 60,000 份 EEG。

它的独特价值在于构建了一个7 大子语料库生态系统——从主库(TUEG)到癫痫发作检测(TUSZ)、异常检测(TUAB)、伪影标注(TUAR)、癫痫分类(TUEP)、事件分类(TUEV)和脑电减慢(TUSL)——形成覆盖 EEG AI 研究全链条的标准化资源。其中 TUSZ 子库提供 675 名患者、1,476 小时数据、4,029 个手工标注的癫痫发作事件和官方 Train/Dev/Eval 患者级划分,是癫痫自动检测领域事实上的标准基准。数据免费开放,支持研究与商业用途,无需 IRB 或 DUA 协议。

你可以用它来:训练一个癫痫自动发作检测模型、研究如何在极端类别不平衡(癫痫段仅占 ~5%)条件下训练鲁棒分类器、或者在大规模无标注 EEG 上预训练一个 EEG 基础模型。

§1.1 摘要

TUH EEG Corpus 由 Temple 大学电气与计算机工程系教授 Iyad Obeid 和 Joseph Picone 于 2016 年正式发表(Frontiers in Neuroscience),是 NEDC 的旗舰数据产品。数据源自 Temple University Hospital 的存档临床 EEG 记录,从原始 CD-ROM 中恢复,将专有 Nicolet NicVue 格式转换为开放 EDF 标准,并按 HIPAA 隐私规则进行了严格脱敏处理(移除 18 类标识符)。每条 EEG 记录配有神经科医生撰写的文本临床报告(经 OCR 从扫描件提取)。

语料库采用层级化 Unix 文件树结构组织,按患者→会话→信号文件排列。主要技术规格包括:10-20 国际电极系统、最少 17 个 EEG 通道、采样率最低 250 Hz(多数为 256 Hz,部分 250/400/512/1000 Hz)。7 大子语料库各有独立的版本号和标注体系,其中 TUSZ 的 13 种癫痫发作类型标签(FNSZ/GNSZ/SPSZ/CPSZ/ABSZ/TNSZ/TCSZ/MYSZ 等)和官方患者级 Train/Dev/Eval 划分(63%/25%/12%)使其成为深度学习癫痫检测研究的首选基准。

§1.2 战略价值分析

技术创新维度:TUH EEG Corpus 是首个以"临床级"数据为核心的开放 EEG 资源。与此前广泛使用的 CHB-MIT(仅 23 名受试者)或 Bonn 数据集(仅 500 段 23.6s 记录)不同,TUH 从真实临床环境中采集,保留了电极位置变异、设备噪声、临床环境干扰等真实变异性。这种"临床级"数据哲学直接推动了 EEG 深度学习从实验室级演示向临床级部署的范式转变。NEDC 还开发了配套的标注工具(EAS)、实时检测系统(ERDR 基于 ResNet-18)和标准化评分包(EVAL),形成了完整的研究基础设施。

生态推动维度:TUH 的 7 大子语料库设计使其不仅是一个数据集,而是一个研究生态系统。TUSZ 支撑了癫痫发作检测,TUAB 支撑了异常筛查,TUAR 支撑了伪影去除,TUEV 支撑了六类事件分类,TUSL 则揭示了自动检测系统的主要错误模式(脑电减慢是误报主因)。2025 年 Large EEG-U-Transformer 在国际癫痫检测挑战赛中夺冠、EEG-JEPA 等基础模型将 TUEG 作为预训练数据,标志着 TUH 已成为 EEG AI 研究的"ImageNet 时刻"催化剂。NEDC 的开放许可政策——无需 IRB 或 DUA、支持商业用途——在 EEG 数据领域极为罕见,极大降低了研究者和创业者的准入门槛。

§1.3 与同类数据集对比

数据集 样本量 模态 标注方式 核心差异化
TUH EEG Corpus 26,846 份记录 / 7,377 EDF(TUSZ) 头皮 EEG 手工标注(学生团队 + 神经科医生验证)+ 临床报告 7 大子语料库生态 + 商业可用 + 官方患者级划分
CHB-MIT Scalp EEG 23 名患者 / 986 小时 头皮 EEG 手工标注 儿童长程监测,仅 198 次发作
Bonn EEG Dataset 500 段 23.6s 记录 头皮 + 侵入式 EEG 预定义类别 极小规模,仅用于二分类/三分类
Siena Scalp EEG 14 名患者 / 87 小时 头皮 EEG 手工标注 2025 挑战赛使用,规模小但质量高
Sleep-EDF 197 名受试者 多导睡眠图 睡眠专家分期 专注睡眠分期,非癫痫
TUH EEG Corpus (TUEG 全库) 26,846 份 / 15,001 患者 头皮 EEG + 报告 部分手工标注 全球最大开放 EEG 语料库,持续更新

§1.4 版本演进时间轴

时间 事件
2012 NEDC 成立,开始 TUH EEG 数据采集与脱敏工作
2016-05 TUEG 原始论文发表(Obeid & Picone, Front. Neurosci.),v0.6.0 含 16,986 会话/10,874 受试者
2016-11 TUSZ v1.0.0 beta 发布,首批癫痫发作标注数据上线
2018-11 TUSZ 论文发表(Shah et al., Front. Neuroinform.),含 504+ 小时数据、36 小时发作事件
2020 TUEG v2.0.0 发布,扩展至 26,846 份记录/15,001 患者
2023-01 TUSZ v2.0.2 发布,移除 2 条重复会话,修正 1 条标注
2023-05 NEDC 发布基于 ResNet-18 的实时癫痫检测系统(ERDR v1.0.1)
2023-10 TUSZ v2.0.3 发布,修正 35 个文件的标注错误
2024-05 NEDC 资源整合为统一入口页面
2024-10 TUSZ v2.0.6 发布(当前最新版)
2025-04 Large EEG-U-Transformer 基于 TUSZ 获 2025 国际癫痫检测挑战赛冠军
2026 SzCORE 基准平台上线,提供 TUSZ 标准化评测协议

§1.5 典型 AI 应用场景

  1. 癫痫自动发作检测:在连续 EEG 记录中实时检测癫痫发作事件的起止时间,支持 ICU/EMU 长程监测场景(核心任务,TUSZ 子库)
  2. 癫痫发作类型分类:区分 13 种癫痫发作类型(FNSZ/GNSZ/CPSZ/TCSZ 等),支持精细化临床诊断
  3. 异常 EEG 筛查:自动判别 EEG 是否异常,辅助临床优先级排序和批量筛查(TUAB 子库)
  4. EEG 伪影去除:识别并标注 5 类伪影(眼动/咀嚼/颤抖/电极弹跳/肌电),支持信号质量提升(TUAR 子库)
  5. EEG 基础模型预训练:在大规模无标注 TUEG 主库上预训练 EEG 基础模型(如 EEG-JEPA),迁移至下游任务

§2 医学背景(Medical Context)

§2.1 ICD-11 编码

数据集标签 ICD-11 中文名
癫痫发作 8A00–8A0Z 癫痫与发作性疾病
局灶性发作 8A00.0 局灶性癫痫发作
全身性发作 8A01 全身性癫痫
强直-阵挛发作 8A01.0 强直-阵挛发作
失神发作 8A01.1 失神癫痫
EEG 异常 8B00.0 神经系统异常发现 — EEG 异常
脑电减慢 8B20 弥漫性脑功能障碍

§2.1b SNOMED CT 映射

数据集标签 ICD-11 SNOMED CT SNOMED CT 术语
Seizure 8A00 85828005 Epileptic seizure (finding)
Focal Non-Specific Seizure 8A00.0 315343005 Focal seizure (finding)
Generalized Non-Specific Seizure 8A01 281670001 Generalized seizure (finding)
Tonic-Clonic Seizure 8A01.0 281670001 Generalized tonic-clonic seizure (finding)
Absence Seizure 8A01.1 6102002 Absence seizure (finding)
Complex Partial Seizure 8A00.0 230431005 Complex partial seizure (finding)
Abnormal EEG 8B00.0 246505001 Electroencephalogram abnormal (finding)

§2.2 疾病简介

癫痫是全球最常见的严重神经系统疾病之一,影响超过 7,000 万人。其特征是大脑神经元异常放电导致的反复癫痫发作,临床表现从短暂的意识丧失到全身强直-阵挛抽搐不等。脑电图(EEG)是癫痫诊断的金标准工具,通过头皮电极记录大脑电活动,可捕捉发作间期癫痫样放电(IED)和发作期癫痫模式。然而,EEG 的视觉判读需要经过多年培训的神经科医生,且长程监测(如 72 小时连续 EEG)产生大量数据,人工审阅耗时巨大。自动癫痫检测 AI 系统可显著提高临床效率,但需要大规模标注数据训练——这正是 TUH EEG Corpus 解决的核心瓶颈。

§2.3 临床任务定义

任务类型 临床场景 对应子库
发作检测(Screening) ICU/EMU 长程 EEG 监测中实时报警癫痫发作 TUSZ
发作分类(Diagnosis) 区分发作类型以指导抗癫痫药物选择 TUSZ
异常筛查(Screening) 批量判别 EEG 是否异常,优先级排序 TUAB
伪影识别(Quality Control) 标注伪影以支持信号清洗和自动审阅辅助 TUAR
事件分类(Diagnosis) 六类 EEG 事件分类(棘慢波/GPED/PLED/眼动/伪影/背景) TUEV
癫痫判别(Diagnosis) 区分癫痫患者与非癫痫患者 TUEP
减慢检测(Diagnosis) 识别脑电减慢事件,减少自动检测误报 TUSL

§2.4 患者人群特征

维度 特征
数据来源 Temple University Hospital(美国宾夕法尼亚州费城),单一三级学术医疗中心
采集时间 2002-2017(TUEG v2.0.2),持续采集中(~3,000 会话/年)
年龄分布 <1 岁 → 90+ 岁,平均 51.6 岁(标准差 55.9)
性别比例 51% 女性 / 49% 男
患者总数 15,001 名唯一患者(TUEG v2.0.2)/ 675 名(TUSZ v2.0.6)
就医类型 混合:门诊 Routine EEG(~30 分钟)/ 住院 LTM(长程监测)/ ICU / EMU(癫痫监测单元)
设备 主要为 Natus Medical Incorporated 设备,原始 NicVue 专用格式

§2.5 临床意义

癫痫的诊断和治疗监测高度依赖 EEG,但全球神经科医生严重不足,尤其在基层和偏远地区。自动癫痫检测 AI 可实现 24/7 不间断监测、降低漏诊率、缩短报告周转时间。TUH EEG Corpus 的临床级数据保留了真实临床环境中的变异性和噪声——电极位置偏差、设备差异、患者运动伪影——使在此数据上训练的模型更可能泛化到真实临床部署场景,而非仅在受控实验环境中有效。

§2.6 金标准

数据划分 标注方式 标注者 金标准性质
TUEG 主库 临床报告 + 无发作标注 神经科医生(报告) 参考标准(报告文本)
TUSZ Train 手工逐通道标注(onset/offset/type/channel) NEDC 本科生团队(神经科医生培训 + 验证) 专家标注金标准
TUSZ Dev 同上 同上 专家标注金标准
TUSZ Eval 同上 同上 专家标注金标准
TUAB 正常/异常二分类(基于报告自动生成 + 人工审核) 医学生审核 参考标准
TUAR 5 类伪影逐段标注 NEDC 团队 专家标注
TUEV 6 类事件标注 NEDC 团队 专家标注

标注验证:NEDC 本科生团队经神经科医生培训后进行发作标注,标注质量通过与专家神经科医生的交叉验证确认。Shah et al. (2018) 报告标注者间一致性达到可接受水平。但需注意,标注者非执业神经科医生,罕见发作类型的标注质量可能略低。

§3 数据集规格(Specifications)

§3.0 版本抉择矩阵

你的需求 推荐版本 大小 理由
癫痫发作检测 / 复现 SOTA TUSZ v2.0.6 ~81 GB 含官方 Train/Dev/Eval 患者级划分 + 4,029 个发作事件标注 + 13 种发作类型
异常 EEG 二分类 TUAB v3.0.1 ~15 GB 2,993 份记录,正常/异常平衡(50.8%/49.2%),含 Train/Eval 划分
EEG 基础模型预训练 TUEG v2.0.2 ~500 GB 26,846 份记录的大规模无标注数据,最大化预训练数据量
伪影去除 / 信号质量 TUAR v3.0.1 ~5 GB 5 类伪影逐段标注,可训练伪影分类器
事件分类(六类) TUEV v2.0.1 ~8 GB 棘慢波/GPED/PLED/眼动/伪影/背景六类标注
快速入门 / 资源有限 TUSZ v2.0.6 Eval 子集 ~20 GB 仅下载 eval/ 目录,足够跑通基线 Pipeline

§3.1 模态详细说明

TUH EEG Corpus 的核心数据模态为临床头皮脑电图(Scalp EEG)——通过放置在头皮表面的电极记录大脑皮层神经元的同步电活动。所有记录采用 10-20 国际电极系统标准放置电极,包含至少 17 个 EEG 通道(通常为 19 个 EEG + 2 个辅助通道如心率和光刺激标记)。常见的 22 通道双极导联组合包括:FP1-F7、F7-T3、T3-T5、T5-O1、FP2-F8、F8-T4、T4-T6、T6-O2、A1-T3、T3-C3、C3-CZ、CZ-C4、C4-T4、T4-A2、FP1-F3、F3-C3、C3-P3、P3-O1、FP2-F4、F4-C4、C4-P4、P4-O2。

除 EEG 信号外,每条记录配有神经科医生撰写的文本临床报告(.txt),包含患者病史、用药信息、EEG 发现和临床印象。报告从医院电子病历系统的扫描件中通过 OCR 提取,经人工校对和 PHI 清洗。

§3.2 样本总数(按子库拆分)

子语料库 简称 版本 EDF 文件数 患者/受试者 总时长 标注事件数
TUH EEG Corpus TUEG v2.0.2 69,582 15,001 ~16,000+ 小时
TUH EEG Seizure Corpus TUSZ v2.0.6 7,377 675 1,476 小时 4,029 发作
TUH Abnormal EEG Corpus TUAB v3.0.1 2,993 2,329 2,993 标签
TUH EEG Artifact Corpus TUAR v3.0.1 5 类伪影
TUH EEG Epilepsy Corpus TUEP v3.1.0 200 (100+100) 发作 + 疾病/药物元数据
TUH EEG Events Corpus TUEV v2.0.1 6 类事件
TUH EEG Slowing Corpus TUSL v2.0.1 减慢事件

§3.3 数据格式详情

文件类型 格式 内容 说明
.edf EDF (European Data Format) EEG 信号数据 国际标准生物信号格式,含头信息(患者 ID/性别/年龄/采集日期/通道标签/采样率/物理参数)
.txt 纯文本 临床报告 神经科医生撰写的脱敏报告,含病史/用药/EEG 发现/临床印象
.csv CSV 多类标注 发作事件的时间标注(onset/duration/label/channel),13 种发作类型
.csv_bi CSV 二分类标注 发作/非发作二分类标签,简化版标注

§3.4 存储大小

版本 压缩后 解压后 说明
TUEG v2.0.2 (全库) ~500 GB 26,846 份记录 + 报告
TUSZ v2.0.6 ~81 GB 7,377 个 EDF + 标注文件
TUAB v3.0.1 ~15 GB 2,993 份记录

§3.5 标注方式

TUSZ 的标注流程采用三级数据筛选 + 人工标注策略:

  1. 数据筛选(Triage):从 TUEG 主库中筛选高发作概率会话,使用三种独立方法:

    • NLP 关键词搜索 EEG 报告(NegEx + 朴素贝叶斯 + SVM,基于 tf-idf 特征)
    • Persyst 商用癫痫检测软件自动检测
    • NEDC 深度学习癫痫检测系统自动检测
    • 三种方法一致的数据优先级最高
  2. 人工标注:NEDC 本科生团队使用开源标注工具(EAS)对筛选后的数据进行逐通道标注,记录每个发作事件的起始时间、终止时间、发作类型和涉及通道

  3. 质量验证:部分标注与专家神经科医生的判读进行交叉比对,确认标注者间一致性

  4. 双格式输出:同时提供多类标注(.csv,13 种发作类型)和二分类标注(.csv_bi,发作/非发作),以及事件级(per-channel)和术语级(per-session,最早起始→最晚终止)两种视图

§3.6 标注者资质

标注者 人数 资质 培训 一致性验证
NEDC 本科生团队 数十人(逐年轮换) Temple 大学本科生,经神经科医生培训 神经科医生指导下的系统培训 部分标注与专家神经科医生交叉比对
神经科医生顾问 2+ Dr. Mercedes Jacobson (TUH) / Dr. Steven Tobochnik (Columbia) 执业神经科医生 提供标注标准培训和金标准验证
医学生(TUAB) 一组 Temple 大学医学院学生 标注与报告信息一致性 97-100%

§3.7 采集时间范围

2002 年至 2017 年(TUEG v2.0.2 发布范围)。数据持续采集中,整体项目已超过 60,000 份 EEG。年均采集约 1,000-2,500 会话(2000-2002 年和 2005 年因电子病历档案不完整而较少)。

§3.8 地域覆盖

单一机构:Temple University Hospital(美国宾夕法尼亚州费城)。作为三级学术医疗中心,患者群体以费城及周边地区为主,涵盖多种神经科疾病。单中心来源是已知泛化性限制(见 §7.3)。

§3.9 设备规格

项目 规格
EEG 设备 主要为 Natus Medical Incorporated(Nicolet NicVue 系统)
原始格式 Nicolet NicVue 专用格式(从 CD-ROM 恢复)
转换格式 EDF (European Data Format) 国际标准
电极系统 10-20 国际电极系统
通道数 最少 17 个 EEG 通道(通常 19 EEG + 2 辅助)
采样率 最低 250 Hz;多数 256 Hz;部分 250/400/512/1000 Hz
导联配置 多种:TCP (Temporal Central Parasagittal)、AR (Average Reference) 等

§3.10 深度溯源链

Temple University Hospital 临床 EEG 采集 (2002-2017)
    ↓ CD-ROM 存档
NEDC 数据恢复 (非联网工作站,TUH 神经科)
    ↓ Nicolet NicVue → EDF 格式转换
HIPAA 脱敏 (18 类标识符移除 + 自动/人工校对)
    ↓ 患者编号随机化 (映射密钥离线保存)
临床报告配对 (EMR 扫描件 → 图像增强 → OCR → PHI 清洗)
    ↓ TUEG v2.0.2 主库发布
TUSZ 三级筛选 (NLP 关键词 + Persyst 商用检测 + NEDC DL 检测)
    ↓ 高发作概率会话
NEDC 本科生团队手工标注 (EAS 工具,逐通道 onset/offset/type)
    ↓ 神经科医生交叉验证
TUSZ v2.0.6 发布 (Train/Dev/Eval 患者级划分)

§4 数据结构详解(Data Schema)

§4.0 目录结构预览

tuh_eeg/                              # TUH EEG Corpus 根目录
├── tuh_eeg/                          # TUEG 主库
│   └── v2.0.2/
│       └── edf/
│           ├── 000/                  # 第 0 组(约 100 名患者)
│           │   └── 00000000/         # 患者 ID
│           │       └── s001_2006_01_23/  # 会话 ID(序号_日期)
│           │           └── 01_tcp_ar/    # 导联配置(01_tcp_ar = TCP + AR)
│           │               ├── 00000000_s001_t000.edf  # EEG 信号文件
│           │               └── 00000000_s001_t000.txt  # 临床报告
│           ├── 001/                  # 第 1 组
│           └── ...
│
├── tuh_eeg_seizure/                  # TUSZ 子库
│   └── v2.0.6/
│       └── edf/
│           ├── train/                # 训练集 (63%, 3,277,229s)
│           │   └── 00010125/
│           │       └── s003_2013_02_05/
│           │           └── 01_tcp_ar/
│           │               ├── 00010125_s003_t000.edf
│           │               └── 00010125_s003_t000.csv     # 多类标注
│           ├── dev/                  # 开发集 (25%, 467,795s)
│           └── eval/                 # 评估集 (12%, 1,567,972s)
│
├── tuh_eeg_abnormal/                 # TUAB 子库
│   └── v3.0.1/
│       ├── abnormal/                 # 异常 EEG
│       └── normal/                   # 正常 EEG
│
├── tuh_eeg_artifact/                 # TUAR 子库
│   └── v3.0.1/
│
├── tuh_eeg_epilepsy/                 # TUEP 子库
│   └── v3.1.0/
│
├── tuh_eeg_events/                   # TUEV 子库
│   └── v2.0.1/
│
└── tuh_eeg_slowing/                  # TUSL 子库
    └── v2.0.1/

§4.1 DAIMS 标准化字段描述表(TUSZ 标注文件)

字段名 数据类型 说明 示例值 AI 用途 观测误差 信息性缺失编码 取值范围
onset Float 发作起始时间(秒,相对于 EDF 文件起点) 152.3 事件检测标签起点 ±1s(标注者间变异) ≥0
duration Float 发作持续时长(秒) 45.7 事件检测标签长度 ±2s >0
label String 发作类型标签(13 种) FNSZ 多类分类标签 FNSZ/GNSZ/SPSZ/CPSZ/ABSZ/TNSZ/TCSZ/MYSZ/CNSZ/ATSZ/NESZ/SEIZ/INTR
channel String 发作涉及的通道标签 FP1-F7 空间定位 10-20 系统导联名
confidence String 标注置信度 质量过滤

§4.2 TUSZ 13 种癫痫发作类型标签分布

标签 全称 描述 事件数 占比
FNSZ Focal Non-Specific Seizure 局灶性非特异性发作(起源于一侧半球) 992 ~24.6%
GNSZ Generalized Non-Specific Seizure 全身性非特异性发作(双侧网络) 415 ~10.3%
SPSZ Simple Partial Seizure 单纯部分性发作(意识保留) 44 ~1.1%
CPSZ Complex Partial Seizure 复杂部分性发作(意识受损) 342 ~8.5%
ABSZ Absence Seizure 失神发作(短暂意识丧失) 99 ~2.5%
TNSZ Tonic Seizure 强直发作(肢体僵硬) 67 ~1.7%
TCSZ Tonic-Clonic Seizure 强直-阵挛发作(大发作) 50 ~1.2%
MYSZ Myoclonic Seizure 肌阵挛发作 <1%
CNSZ Clonic Seizure 阵挛发作 <1%
ATSZ Atonic Seizure 失张力发作 <1%
NESZ Non-Epileptic Seizure 非癫痫性发作事件 <1%
SEIZ Seizure (generic) 通用发作标签
INTR Interictal 发作间期

注意:FNSZ 和 GNSZ 合计占发作事件的 ~35%,是最常见的两种类型。罕见类型(ATSZ、MYSZ、CNSZ)事件数极少(<70),训练时需特殊处理。SPSZ 和 MYSZ 仅出现在 Train 集中,Dev/Eval 集中无此两类。

§4.3 TUSZ Train/Dev/Eval 划分统计

划分 会话比例 总时长 发作段占比 含发作文件比例 患者重叠
Train 63% 3,277,229s (~910h) 5.34% 18.7%
Dev 25% 467,795s (~130h) 5.09% 17.7%
Eval 12% 1,567,972s (~436h) 5.82% 22.1%

关键设计:三个划分之间严格患者级不重叠——同一患者的所有数据只出现在一个划分中。这是防止数据泄漏的标准做法。然而,各划分间的发作类型分布不完全一致(如 MYSZ/SPSZ 仅在 Train 中),这是已知的数据分布偏差。

§4.4 数据层级关系

患者 (Patient) — 唯一 ID,可能多次就诊
  └── 会话 (Session) — 一次 EEG 记录会话,可能含多个 EDF 文件
       └── EDF 文件 — 一段连续 EEG 信号(长程监测可能拆分多文件)
            └── 通道 (Channel) — 单个导联信号(如 FP1-F7)
                 └── 时间点 (Sample) — 单个采样点

§4.5 缺失值情况

缺失类型 描述 影响 处理建议
变长 EDF 文件 长程监测拆分为多个 EDF 文件 时间不连续 使用 Natus 文件命名规则(t000, t001…)按顺序拼接
异构采样率 不同会话采样率不同(250-1000 Hz) 批处理困难 统一重采样至目标频率(如 200 Hz)
异构通道数 不同会话通道数不同(≥17) 批处理 padding 选择公共通道子集或 padding 至最大通道数
部分会话无标注 TUSZ 仅标注含发作的会话 非发作段无逐事件标签 使用 .csv_bi 二分类标签或 term-based 标注

§5 数据划分与使用建议(Splits & Usage)

§5.1 官方划分策略

TUSZ 提供官方 Train/Dev/Eval 三分划分,按患者级分离

划分 用途 患者数 会话数 EDF 文件数
Train 模型训练 ~437 (36% 癫痫患者) ~1,036 ~4,651
Dev 超参调优 ~180 (84% 癫痫患者) ~410 ~1,304
Eval 最终评估 ~158 (79% 癫痫患者) ~199 ~1,422

§5.2 使用建议

  1. 严格遵循官方划分:不要将 Train 和 Eval 混合后重新划分(这是文献中最常见的错误,见 §6.5 坑点 1)
  2. Dev 用于超参选择:在 Dev 集上选择阈值和后处理参数,然后冻结策略,仅在 Eval 上评估一次
  3. 连续 EEG 评估:在连续 EEG 上评估而非仅发作段评估,以获得真实临床场景的性能估计
  4. 双指标报告:同时报告窗口级(window-level)和事件级(event-level)指标

§5.3 评估指标推荐

指标类型 指标 说明
窗口级 AUROC 受试者工作特征曲线下面积
窗口级 Balanced Accuracy 平衡准确率
窗口级 F1 Score 发作类的 F1
事件级 Event Sensitivity 事件级敏感度(至少 1 个窗口检测到发作)
事件级 False Alarms per Hour 每小时误报次数
事件级 Time-based PPV 时间维度的阳性预测值
事件级 Event F1 事件级 F1 分数

§6 AI 就绪指南(AI-Ready Guide)

§6.1 快速上手

# ========================================
# TUH EEG Corpus (TUSZ) 快速上手 — PyTorch + MNE-Python
# 环境要求: torch>=2.0, mne>=1.5, pandas, numpy, scipy
#
# ⚠️ 目录结构预期:
#   请将下载的 TUSZ 数据放在 ./tusz/ 目录,确保以下结构:
#   ./tusz/
#   ├── edf/
#   │   ├── train/
#   │   │   └── 00010125/s003_2013_02_05/01_tcp_ar/
│   │   │       ├── *.edf     # EEG 信号文件
│   │   │       └── *.csv     # 多类标注
│   │   ├── dev/
│   │   └── eval/
#
#   数据下载方式:rsync(需先注册)
#   rsync -auxvL progress nedc-tuh-eeg@www.isip.piconepress.com:data/tuh_eeg/tuh_eeg_seizure/v2.0.6/ ./tusz/
# ========================================

import mne
import numpy as np
import pandas as pd
from pathlib import Path
from glob import glob

# - 1. 加载单个 EDF 文件 -
edf_path = "./tusz/edf/train/00010125/s003_2013_02_05/01_tcp_ar/00010125_s003_t000.edf"
raw = mne.io.read_raw_edf(edf_path, preload=True, verbose=False)

print(f"采样率: {raw.info[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''sfreq'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']} Hz")
print(f"通道数: {len(raw.ch_names)}")
print(f"通道名: {raw.ch_names}")
print(f"时长: {raw.n_times / raw.info[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''sfreq'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']:.1f} 秒")

# - 2. 加载对应的标注文件 -
csv_path = edf_path.replace(''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.edf'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.csv'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''')
annotationevent-blocked= pd.read_csv(csv_path)
print(f"\n标注文件列名: {list(annotations.columns)}")
print(f"发作事件数: {len(annotations)}")
if len(annotations) > 0:
    print(annotations[[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''label'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''onset'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''duration'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']].head())

# - 3. 提取固定长度窗口 -
def extract_windows(raw, window_sec=12, stride_sec=6, target_sfreq=200):
    """从 Raw 对象提取固定长度窗口"""
    # 重采样到目标频率
    raw_resampled = raw.copy().resample(target_sfreq)
    sfreq = raw_resampled.info[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''sfreq'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']
    
    window_samples = int(window_sec * sfreq)
    stride_samples = int(stride_sec * sfreq)
    n_samples = raw_resampled.n_times
    
    windows = []
    for start in range(0, n_samples - window_samples + 1, stride_samples):
        segment = raw_resampled[:, start:start + window_samples][0]
        windows.append(segment)
    
    return np.stack(windows)  # (n_windows, n_channels, window_samples)

windows = extract_windows(raw, window_sec=12, stride_sec=6)
print(f"\n窗口形状: {windows.shape}")

§6.2 数据获取方式

方式 链接/命令 大小 说明
rsync(推荐) rsync -auxvL nedc-tuh-eeg@www.isip.piconepress.com:data/tuh_eeg/tuh_eeg_seizure/v2.0.6/ ./tusz/ ~81 GB 需先注册获取 SSH 密钥/密码
硬盘邮寄 向 NEDC 发送 8TB USB 硬盘 全库 适合获取全量 TUEG 数据
浏览器下载 https://isip.piconepress.com/projects/nedc/html/tuh_eeg/index.shtml 按需 可选择性下载子集

注册流程

  1. 下载申请表 PDF:https://isip.piconepress.com/projects/nedc/forms/tuh_eeg.pdf
  2. 填写表格(需准确填写地址信息)
  3. 邮件发送签名副本至 help@nedcdata.org,标题含 “Download The TUH EEG Corpus”
  4. 24-48 小时内收到 rsync 用户名和密码
  5. 使用 rsync 下载(支持断点续传)

§6.3 预处理 Pipeline

# ========================================
# TUSZ 预处理 Pipeline — 标准化处理流程
# ========================================

import mne
import numpy as np
from scipy.signal import butter, filtfilt

def preprocess_tusz(edf_path, target_sfreq=200, n_channels=22):
    """
    TUSZ EDF 文件标准化预处理
    1. 加载 EDF
    2. 通道标准化(选择公共 22 通道 + padding)
    3. 重采样至目标频率
    4. 带通滤波 (0.5 - 120 Hz)
    5. 陷波滤波 (50/60 Hz)
    """
    # 加载
    raw = mne.io.read_raw_edf(edf_path, preload=True, verbose=False)
    sfreq = raw.info[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''sfreq'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']
    
    # 通道标准化:选择标准 22 通道双极导联
    standard_channels = [
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP1-F7'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F7-T3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T3-T5'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T5-O1'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP2-F8'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F8-T4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T4-T6'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T6-O2'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''A1-T3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T3-C3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C3-CZ'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''CZ-C4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C4-T4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T4-A2'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP1-F3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F3-C3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C3-P3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''P3-O1'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP2-F4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F4-C4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C4-P4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''P4-O2''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ]
    
    # 选择可用通道(处理异构通道数)
    available = set(raw.ch_names)
    selected = [ch for ch in standard_channels if ch in available]
    raw.pick_channels(selected)
    
    # 如果通道不足,padding
    if len(raw.ch_names) < n_channels:
        n_pad = n_channels - len(raw.ch_names)
        pad_data = np.zeros((n_pad, raw.n_times))
        pad_info = mne.create_info(
            [f''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''PAD_{i}'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' for i in range(n_pad)], sfreq, ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''eeg''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        )
        pad_raw = mne.io.RawArray(pad_data, pad_info, verbose=False)
        raw = mne.concatenate_raws([raw, pad_raw])
    
    # 重采样
    if sfreq != target_sfreq:
        raw.resample(target_sfreq)
    
    # 带通滤波 (0.5 - 120 Hz)
    raw.filter(l_freq=0.5, h_freq=120.0, method=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''fir'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', verbose=False)
    
    # 陷波滤波 (60 Hz, 美国电力线频率)
    raw.notch_filter(freqs=60.0, method=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''fir'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', verbose=False)
    
    # 逐通道 z-score 标准化
    data = raw.get_data()
    mean = data.mean(axis=1, keepdims=True)
    std = data.std(axis=1, keepdims=True)
    data = (data - mean) / (std + 1e-8)
    
    return data  # (n_channels, n_samples)


def create_labels(edf_path, csv_path, window_sec=12, stride_sec=6, 
                  target_sfreq=200):
    """
    为每个窗口生成二分类标签
    标签规则:窗口内包含 ≥1 秒发作活动 → 标记为 ictal
    """
    raw = mne.io.read_raw_edf(edf_path, preload=False, verbose=False)
    durationevent-blocked= raw.n_times / raw.info[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''sfreq'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']
    
    window_samples = int(window_sec * target_sfreq)
    stride_samples = int(stride_sec * target_sfreq)
    n_windows = int((duration_s * target_sfreq - window_samples) / stride_samples) + 1
    
    labels = np.zeros(n_windows, dtype=np.int32)
    
    if csv_path and Path(csv_path).exists():
        ann = pd.read_csv(csv_path)
        for _, row in ann.iterrows():
            onevent-blocked= row[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''onset'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']
            dur = row[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''duration'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']
            
            for i in range(n_windows):
                window_start = i * stride_sec
                window_end = window_start + window_sec
                seizure_start = onset
                seizure_end = onset + dur
                
                overlap = min(window_end, seizure_end) - max(window_start, seizure_start)
                if overlap >= 1.0:  # 至少 1 秒重叠
                    labels[i] = 1
    
    return labels

§6.4 框架加载(PyTorch / TensorFlow)

<details>
<summary>🔧 PyTorch Dataset(点击展开)</summary>

import torch
from torch.utils.data import Dataset, DataLoader
from pathlib import Path
from glob import glob

class TUSZDataset(Dataset):
    """TUSZ PyTorch Dataset"""
    
    STANDARD_CHANNELS = [
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP1-F7'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F7-T3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T3-T5'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T5-O1'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP2-F8'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F8-T4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T4-T6'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T6-O2'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''A1-T3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T3-C3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C3-CZ'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''CZ-C4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C4-T4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''T4-A2'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP1-F3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F3-C3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C3-P3'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''P3-O1'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''FP2-F4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F4-C4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''C4-P4'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''P4-O2''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ]
    
    def __init__(self, root_dir, split=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''train'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', window_sec=12, 
                 stride_sec=6, target_sfreq=200, n_channels=22):
        self.root = Path(root_dir) / ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''edf'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' / split
        self.window_sec = window_sec
        self.stride_sec = stride_sec
        self.target_sfreq = target_sfreq
        self.n_channels = n_channels
        
        # 扫描所有 EDF 文件
        self.edf_files = sorted(glob(str(self.root / ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''**'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' / ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''*.edf''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''), recursive=True))
        
        # 预计算每个文件的窗口数
        self.file_windows = []
        for edf_path in self.edf_files:
            raw = mne.io.read_raw_edf(edf_path, preload=False, verbose=False)
            duration = raw.n_times / raw.info[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''sfreq'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''']
            n_windows = max(1, int((duration - window_sec) / stride_sec) + 1)
            self.file_windows.append(n_windows)
        
        self.cumulative = np.cumsum(self.file_windows)
    
    def __len__(self):
        return int(self.cumulative[-1]) if len(self.cumulative) > 0 else 0
    
    def __getitem__(self, idx):
        # 定位文件和窗口
        file_idx = np.searchsorted(self.cumulative, idx)
        if file_idx > 0:
            window_idx = idx - self.cumulative[file_idx - 1]
        else:
            window_idx = idx
        
        edf_path = self.edf_files[file_idx]
        csv_path = edf_path.replace(''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.edf'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.csv'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''')
        
        # 预处理
        data = preprocess_tusz(edf_path, self.target_sfreq, self.n_channels)
        labels = create_labels(edf_path, csv_path, self.window_sec, 
                               self.stride_sec, self.target_sfreq)
        
        # 提取窗口
        sfreq = self.target_sfreq
        start = int(window_idx * self.stride_sec * sfreq)
        end = int(start + self.window_sec * sfreq)
        
        if end > data.shape[1]:
            # 末尾 padding
            pad = np.zeros((self.n_channels, end - data.shape[1]))
            window = np.concatenate([data[:, start:], pad], axis=1)
        else:
            window = data[:, start:end]
        
        label = labels[window_idx] if window_idx < len(labels) else 0
        
        return torch.FloatTensor(window), torch.LongTensor([label]).squeeze()

# 使用示例
train_ds = TUSZDataset(''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''./tusz'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', split=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''train'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''')
train_loader = DataLoader(train_ds, batch_size=32, shuffle=True, num_workers=4)

for batch_x, batch_y in train_loader:
    print(f"Batch shape: {batch_x.shape}")  # (32, 22, 2400) for 12s @ 200Hz
    print(f"Labels: {batch_y.shape}")        # (32,)
    break

</details>

<details>
<summary>🔧 TensorFlow DataLoader(点击展开)</summary>

import tensorflow as tf

def create_tf_dataset(root_dir, split=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''train'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', window_sec=12, 
                      stride_sec=6, target_sfreq=200, batch_size=32):
    """TensorFlow Dataset for TUSZ"""
    
    def generator():
        edf_files = sorted(glob(
            str(Path(root_dir) / ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''edf'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' / split / ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''**'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' / ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''*.edf''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''), 
            recursive=True
        ))
        for edf_path in edf_files:
            csv_path = edf_path.replace(''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.edf'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.csv'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''')
            data = preprocess_tusz(edf_path, target_sfreq)
            labels = create_labels(edf_path, csv_path, window_sec, 
                                   stride_sec, target_sfreq)
            
            window_samples = int(window_sec * target_sfreq)
            stride_samples = int(stride_sec * target_sfreq)
            
            for i in range(0, data.shape[1] - window_samples + 1, stride_samples):
                window = data[:, i:i + window_samples].T  # (samples, channels)
                label = labels[i // stride_samples] if i // stride_samples < len(labels) else 0
                yield window.astype(np.float32), np.int32(label)
    
    output_signature = (
        tf.TensorSpec(shape=(int(window_sec * target_sfreq), 22), dtype=tf.float32),
        tf.TensorSpec(shape=(), dtype=tf.int32)
    )
    
    ds = tf.data.Dataset.from_generator(generator, output_signature=output_signature)
    ds = ds.shuffle(1000).batch(batch_size).prefetch(tf.data.AUTOTUNE)
    
    return ds

train_ds = create_tf_dataset(''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''./tusz'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', split=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''train'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''', batch_size=32)

</details>

§6.5 常见坑点

⚠️ 坑点 1:非标准划分导致数据泄漏(分类:数据泄漏)

问题:文献中最常见的错误是将官方 Train 和 Eval 合并后重新 k-fold 交叉验证,导致同一患者的数据同时出现在训练和验证集中。Zabihi et al. (2026, Nature Sci. Reports) 指出"many studies use non-canonical splits, mix patients across partitions, or evaluate on seizure-only segments"。

症状:报告的性能远高于使用官方 Eval 划分的结果(如 95%+ vs 83%),模型在真实临床场景中表现骤降。

解决

  1. 严格使用官方 Train/Dev/Eval 划分:Train 用于训练,Dev 用于超参选择,Eval 仅用于最终一次性评估
  2. 患者级分离验证:确认 Train/Dev/Eval 之间无患者重叠(官方划分已保证)
  3. 在连续 EEG 上评估:不要仅在发作段评估,需包含非发作背景段
  4. 参考 SzCORE 基准:使用 SzCORE 平台 (epilepsybenchmarks.com) 的标准化评测协议

参考:Zabihi et al. (2026), Nature Scientific Reports. DOI: 10.1038/s41598-026-41358-w

⚠️ 坑点 2:异构采样率与通道数(分类:预处理陷阱)

问题:TUSZ 的采样率从 250 Hz 到 1000 Hz 不等,通道数从 17 到 22+ 变化。直接 batch 加载会导致维度不匹配错误。

症状ValueError: expected sequence of length X at dim Y 或模型输入维度不一致。

解决

  1. 统一重采样:将所有信号重采样至固定频率(推荐 200 Hz,平衡信息保留与计算效率)
  2. 通道标准化:选择标准 22 通道子集,缺失通道用零填充
  3. 逐文件预处理:在 Dataset __getitem__ 中实时预处理,而非预加载全部数据
# 重采样到 200 Hz
raw.resample(200)
# 通道 padding
if len(raw.ch_names) < 22:
    pad_data = np.zeros((22 - len(raw.ch_names), raw.n_times))
    # ... concatenate

⚠️ 坑点 3:极端类别不平衡(发作段仅占 ~5%)(分类:评估误用)

问题:TUSZ 中癫痫发作段仅占总数据的 ~5%,直接训练会导致模型倾向于全部预测为"非发作",准确率虚高但检测率为零。

症状:模型准确率 95%+ 但 Sensitivity 接近 0%;AUROC 看似合理但事件级 F1 极低。

解决

  1. 损失函数:使用 Focal Loss 或加权交叉熵(正类权重 ~19:1)
  2. 过采样/欠采样:对发作窗口过采样,或对非发作窗口欠采样
  3. 评估指标:报告 Balanced Accuracy、AUROC、事件级 Sensitivity 和 FP/hour,不要仅看 Accuracy
  4. 阈值调优:在 Dev 集上优化阈值(而非使用默认 0.5),在敏感性和误报率之间权衡

参考:Zabihi et al. (2026) 将阈值选择建模为"警报预算决策问题",在特异性 ≥0.93 且 FP ≤0.69/h 约束下最大化事件敏感度。

⚠️ 坑点 4:发作类型分布不一致(分类:偏倚陷阱)

问题:Train 集含 13 种发作类型,但 Dev/Eval 集缺少 MYSZ 和 SPSZ。在 Dev/Eval 上无法评估模型对这两类的检测能力。

症状:多类分类模型在 Dev/Eval 上对 MYSZ/SPSZ 的 F1 为 0 或 NaN。

解决

  1. 二分类优先:对于发作检测任务,优先使用二分类(发作 vs 非发作),避免多类分布不一致问题
  2. 合并罕见类:将 <70 个事件的类型(ATSZ/MYSZ/CNSZ/SPSZ)合并为"罕见发作"类
  3. 报告已知限制:明确说明 Dev/Eval 缺少哪些类型,不做该类型的性能声明

⚠️ 坑点 5:EDF 文件拆分与时间不连续(分类:工程陷阱)

问题:长程监测会话被 Natus 系统拆分为多个 EDF 文件(t000, t001…),文件间可能存在时间间隔(Natus 技术员手动移除了无信息段)。直接拼接会引入虚假的时间连续性。

症状:拼接后的信号在文件边界出现突变伪影;标注时间戳与信号不对应。

解决

  1. 逐文件处理:以 EDF 文件为单位处理和标注,不跨文件拼接
  2. 标注时间对齐:标注文件中的 onset 是相对于单个 EDF 文件的,不是会话级别的
  3. 文件命名规则:t000, t001 通常按时间顺序排列,但由技术员决定具体顺序

⚠️ 坑点 6:标注者非执业神经科医生(分类:标签理解)

问题:TUSZ 的发作标注由 NEDC 本科生团队完成(虽经神经科医生培训和验证),而非执业神经科医生。罕见发作类型的标注质量可能低于常见类型。

症状:模型学到的"发作模式"在专家审核时部分被判定为误标。

解决

  1. 关注常见类型:优先评估 FNSZ 和 GNSZ(占 35%+,标注质量最有保障)
  2. 标签平滑:使用 Label Smoothing (ε=0.1) 缓解标注噪声
  3. 交叉验证:对关键结果进行人工抽样审核
  4. 使用 .csv_bi:二分类标注比多类标注更鲁棒,标注分歧更小

§6.6 数据增强策略

方法 安全性 说明
时间窗口滑动 ✅ 推荐 改变窗口起点,增加样本量
通道 Dropout ✅ 推荐 随机置零部分通道,增强通道缺失鲁棒性
时间偏移 ✅ 推荐 整段信号循环移位,保持频域特征
幅度缩放 ✅ 推荐 乘以随机因子 (0.8-1.2),模拟电极阻抗变化
高斯噪声 注入 ✅ 推荐 添加低水平白噪声 (SNR > 30dB)
频率掩码 ✅ 推荐 随机遮蔽某个频带,增强频域鲁棒性
时间拉伸 ✅ 谨慎 使用 STFT 域插值,避免失真
MixUp ✅ 推荐 两个窗口线性混合,标签同步混合
患者级 MixUp ❌ 危险 跨患者混合可能产生不真实的 EEG 模式
反转信号 ❌ 危险 EEG 有方向性,反转会破坏生理意义

§6.7 模型推荐配置

模型 参数量 输入 预期性能 说明
Large EEG-U-Transformer ~10M 原始 EEG (all channels) 1st place 2025 挑战赛 U 形 seq-to-seq,无需预训练
SeizFormer ~5M STFT 频谱图 (12s) F1 54.65 (subject-avg) CNN + Transformer,12s 窗口
ResBiLSTM ~2M 原始 EEG (1D) Acc 95.03% (10-fold CV) ResNet1D + BiLSTM
CatBoost Ensemble 专家特征 (60s) AUROC 0.92, FP 0.68/h 可解释,严格遵循官方划分
ResNet-18 (NEDC) ~11M STFT 频谱图 官方基线 NEDC 配套系统,含实时解码器

§6.8 硬件配置建议

配置 GPU 磁盘 训练时间 说明
最低 RTX 3090 (24GB) 200 GB SSD ~12h (ResNet) 单 GPU 训练基线模型
推荐 A100 (40GB) 500 GB SSD ~4h (ResNet) / ~8h (Transformer) 支持 batch_size=64
高性能 2× A100 (80GB) 1TB NVMe ~2h (Transformer) 多 GPU 并行 + 大 batch
存储 100 GB (TUSZ Eval) / 81 GB (TUSZ 全量) 原始 EDF 文件

§6.9 评估指标代码

# ========================================
# TUSZ 评估指标 — 窗口级 + 事件级
# ========================================

import numpy as np
from sklearn.metrics import roc_auc_score, balanced_accuracy_score, f1_score

def evaluate_window_level(y_true, y_pred, y_prob, threshold=0.5):
    """窗口级评估"""
    y_pred_binary = (y_prob >= threshold).astype(int)
    
    metrics = {
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''AUROC'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': roc_auc_score(y_true, y_prob) if len(np.unique(y_true)) > 1 else 0.0,
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Balanced_Acc'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': balanced_accuracy_score(y_true, y_pred_binary),
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''F1'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': f1_score(y_true, y_pred_binary, zero_division=0),
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Sensitivity'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': recall_score(y_true, y_pred_binary, zero_division=0),
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Specificity'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': recall_score(1 - y_true, 1 - y_pred_binary, zero_division=0),
    }
    return metrics


def evaluate_event_level(y_true_windows, y_pred_windows, 
                          window_sec=12, stride_sec=6,
                          overlap_threshold=0.5):
    """
    事件级评估
    一个真实发作事件被"检测到"的条件:
    在发作时间段内,至少有 overlap_threshold 比例的窗口被正确预测为发作
    """
    # 识别真实事件段(连续的 ictal 窗口)
    true_events = []
    in_event = False
    event_start = 0
    
    for i, label in enumerate(y_true_windows):
        if label == 1 and not in_event:
            event_start = i
            in_event = True
        elif label == 0 and in_event:
            true_events.append((event_start, i - 1))
            in_event = False
    if in_event:
        true_events.append((event_start, len(y_true_windows) - 1))
    
    # 识别预测事件段
    pred_events = []
    in_event = False
    event_start = 0
    
    for i, label in enumerate(y_pred_windows):
        if label == 1 and not in_event:
            event_start = i
            in_event = True
        elif label == 0 and in_event:
            pred_events.append((event_start, i - 1))
            in_event = False
    if in_event:
        pred_events.append((event_start, len(y_pred_windows) - 1))
    
    # 事件级匹配
    n_true = len(true_events)
    n_detected = 0
    n_false_alarms = 0
    
    for t_start, t_end in true_events:
        t_duration = t_end - t_start + 1
        detected_windows = sum(
            1 for i in range(t_start, t_end + 1) 
            if y_pred_windows[i] == 1
        )
        if detected_windows / t_duration >= overlap_threshold:
            n_detected += 1
    
    # 误报事件
    matched_pred = set()
    for p_start, p_end in pred_events:
        matched = False
        for t_start, t_end in true_events:
            if p_start <= t_end and p_start >= t_start:
                matched = True
                break
        if not matched:
            n_false_alarms += 1
    
    event_sensitivity = n_detected / n_true if n_true > 0 else 0.0
    total_hours = len(y_true_windows) * stride_sec / 3600
    fp_per_hour = n_false_alarms / total_hours if total_hours > 0 else 0.0
    
    event_f1 = 2 * event_sensitivity * (1 - fp_per_hour / (fp_per_hour + 1)) / \
               (event_sensitivity + (1 - fp_per_hour / (fp_per_hour + 1)) + 1e-8)
    
    return {
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Event_Sensitivity'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': event_sensitivity,
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''False_Alarms_per_Hour'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': fp_per_hour,
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Event_F1'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': event_f1,
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''n_true_events'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': n_true,
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''n_detected'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': n_detected,
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''n_false_alarms'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''': n_false_alarms,
    }

§6.10 MLOps 笔记

  • 版本管理:TUSZ 版本更新频繁(v1.5.2 → v2.0.0 → v2.0.1 → v2.0.2 → v2.0.3 → v2.0.6),不同版本的标注文件有修正。论文复现时需明确标注使用的版本号。

  • 数据完整性:rsync 下载支持 checksum 选项验证文件完整性,推荐下载后运行校验。

  • 实时部署:NEDC 提供基于 ResNet-18 的实时检测系统(ERDR),可作为部署参考。

  • 评测标准化:SzCORE 平台 (epilepsybenchmarks.com) 提供标准化的 TUSZ 评测协议和排行榜,推荐作为性能对标。

§7 质量评估与局限性(Quality & Limitations)

§7.1 已知偏倚

偏倚类型 描述 严重程度 缓解措施
单中心偏倚 所有数据来自 Temple University Hospital(费城),地理和人口多样性有限 外部验证(见 §7.8),使用 CHB-MIT、Siena 等数据集验证
选择偏倚 TUSZ 通过 NLP + 商用检测 + DL 三级筛选从 TUEG 中选择,可能偏向"明显"发作 人工标注验证,报告筛选流程透明
发作类型不平衡 FNSZ/GNSZ 占 35%+,罕见类型(ATSZ/MYSZ)<70 事件 合并罕见类,使用 Focal Loss,报告按类型性能
标注者偏倚 本科生标注(非执业神经科医生),罕见类型质量可能较低 优先使用二分类标签,标签平滑
设备偏倚 主要为 Natus 设备,不同设备信号特征可能不同 外部验证使用不同设备采集的数据
时间漂移 数据跨 2002-2017 年,EEG 设备和临床协议可能变化 报告数据采集年份分布

§7.2 标注质量评估

标注类型 标注方式 一致性 局限性
TUSZ 发作标注 NEDC 本科生逐通道标注 与神经科医生交叉验证,一致性可接受 非执业医生标注;罕见类型质量不确定
TUAB 正常/异常 自动从报告生成 + 医学生审核 医学生 vs 报告一致性 97-100% 自动生成可能遗漏信号层面的细微异常
TUAR 伪影标注 NEDC 团队标注 伪影边界判断存在主观性
TUEV 事件标注 NEDC 团队标注 六类事件定义可能与其他标准不同

§7.3 泛化性讨论

场景 失效风险 证据
迁移到不同医院 EEG 中-高 单中心数据,设备/协议/人群差异
迁移到不同设备 主要为 Natus 设备,其他品牌可能不同
儿科 EEG TUEG 以成人为主,儿科数据有限
ICU 连续监测 TUSZ 含 ICU 数据但比例较低
实时部署 延迟和计算资源限制可能影响性能

§7.4 伦理考量

  1. HIPAA 脱敏:所有数据按 HIPAA Safe Harbor 移除 18 类标识符,患者姓名和出生日期已删除,病历号随机化(映射密钥离线保存)
  2. IRB 审批:所有工作经 Temple University IRB 批准,遵循赫尔辛基宣言
  3. 知情同意:数据来自存档临床记录(回顾性研究),经 IRB 豁免知情同意
  4. 商业使用:NEDC 明确声明数据可用于研究和商业化,这在医疗数据领域极为罕见
  5. 数据安全:原始文件处理在非联网计算机上进行,位于 TUH 神经科物理安全区域

§7.5 公平性评估

TUH EEG Corpus 未正式发布种族/族裔数据。作为费城三级学术医疗中心,患者群体以当地人口结构为主。已知的人口统计信息仅包括年龄(<1 → 90+ 岁,平均 51.6)和性别(51% 女性)。性别分布相对均衡,但年龄分布偏向中老年。儿科和老年患者的代表性需在下游应用中特别关注。

§7.6 数据漂移提示

数据采集跨度 2002-2017 年。期间 EEG 设备技术(采样率、通道数、滤波器)和临床协议(记录时长、导联配置、监测指征)可能发生变化。2002 年的记录可能使用较旧设备(低采样率、少通道),而 2017 年的记录更接近现代标准。训练模型时建议关注数据采集年份分布,必要时按年份分层分析性能。

§7.7 DAIMS 24 项数据就绪度评估表

# 检查项 状态 说明
1 数据集基本信息文档化 Obeid & Picone (2016) + Shah et al. (2018) 详细描述
2 数据采集协议文档化 临床 EEG 采集标准,10-20 系统,设备型号明确
3 标注协议文档化 标注指南文档 (2026),电极配置文档 (2020)
4 标注者资质文档化 本科生团队 + 神经科医生培训与验证
5 数据划分策略文档化 TUSZ 官方 Train/Dev/Eval 患者级划分
6 标签分布统计 13 种发作类型分布已统计
7 缺失值机制文档化 ⚠️ 异构采样率/通道数已知,但正式文档不完整
8 已知偏倚文档化 单中心、选择偏倚、类型不平衡已识别
9 伦理审批文档化 Temple IRB 批准,HIPAA 脱敏
10 许可证明确 NEDC 开放许可,支持研究+商业
11 DOI 持久标识符 10.3389/fnins.2016.00196 (TUEG) / 10.3389/fninf.2018.00083 (TUSZ)
12 数据格式标准化 EDF 国际标准格式
13 元数据完整性 EDF 头信息含患者 ID/性别/年龄/日期/通道/采样率
14 预处理脚本公开 NEDC 提供 PYPR (EDF 解析)、EVAL (评分) 等工具
15 评估协议标准化 SzCORE 基准平台 + 官方划分 + Zabihi et al. (2026) 透明协议
16 外部验证记录 ⚠️ 多篇论文使用 CHB-MIT/Siena 验证,但无系统化矩阵
17 版本管理 清晰的版本历史 (v1.0.0 → v2.0.6),变更日志详细
18 数据大小合理 1,476 小时 (TUSZ) 为公开 EEG 发作检测最大规模
19 多中心验证 单中心数据,无多中心验证
20 种族/人口多样性 未发布种族数据,单一地理来源
21 标注者间一致性量化 ⚠️ 定性报告"可接受",未给出定量 kappa 值
22 ICD/SNOMED 编码映射 未提供标准疾病编码映射
23 数据增强指南 无官方数据增强指南
24 基础模型评测支持 BenchECG/SzCORE 提供标准化基础模型评测平台

DAIMS 评分:16/24

评分解读良好 — 接近优秀,需少量补充工作。

对你意味着什么:TUH EEG Corpus 的规范性总体优秀,是 EEG AI 领域最成熟的公开数据集。主要扣分项集中在:单中心来源限制泛化性、标注者间一致性未量化、无标准疾病编码映射。建议在训练前执行以下操作:(1) 严格使用官方 Train/Dev/Eval 划分,不要混合重新划分;(2) 统一重采样至 200 Hz 并标准化通道数;(3) 优先使用二分类标签(.csv_bi)以减少多类分布不一致的影响;(4) 在 CHB-MIT 或 Siena 数据集上进行外部验证。

§7.8 外部验证矩阵

外部数据集/场景 来源机构 样本量 评估任务 性能指标 相对内部测试集变化 关键发现
CHB-MIT Scalp EEG Children’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’'s Hospital Boston 23 名患者 / 198 次发作 发作检测 AUROC 0.85-0.95 (不同模型) -5%~-10% 儿科数据泛化性下降,发作模式不同
Siena Scalp EEG University of Siena 14 名患者 / 87 小时 发作检测 Event F1 3.71% (SeizFormer) 2025 挑战赛使用,TUSZ 训练模型可直接迁移
MIT-BIH EEG MIT 不同设备/协议,需域适应
TUAB (跨子库) Temple University 2,993 份记录 异常检测 AUROC 0.78-0.92 TUEG 预训练 → TUAB 微调,跨任务迁移验证

约束:本矩阵仅记录有同行评审论文或公开挑战赛支撑的外部评估结果。

§8 基准性能与生态(Benchmarks & Ecosystem)

§8.1 排行榜

注意:以下排行榜中不同论文使用的 TUSZ 版本、评估协议(窗口级 vs 事件级)、划分策略(官方划分 vs 自定义 CV)不完全一致。绝对数值不可直接比较。请仔细阅读"评估协议"列。

TUSZ 癫痫发作检测(二分类,严格遵循官方 Train/Dev/Eval 划分)
排名 模型 性能指标 年份 评估协议 关键技术 完整引用 代码
1 Large EEG-U-Transformer 1st place (2025 Challenge) 2025 事件级, 连续 EEG U 形 seq-to-seq, 无需预训练 Wu et al., 2025, arXiv:2504.00336 GitHub
2 CatBoost Ensemble AUROC 0.92, BalAcc 0.83, Event Sens 0.75, FP 0.68/h 2026 严格官方划分, 60s 窗口 专家特征 + 梯度提升 + 时间上下文 Zabihi et al., 2026, Nature Sci. Reports. DOI: 10.1038/s41598-026-41358-w GitHub
3 SeizFormer Subject-avg F1 54.65, Event Sens 77.49% 2025 12s 窗口, STFT CNN + Transformer Dani et al., 2025, University of Tübingen
4 TSD Transformer AUROC 92.1% 2023 12s 窗口, STFT Transformer + 双极导联 TSD paper, 2023, bioRxiv
TUSZ 癫痫发作检测(自定义划分 / k-fold 交叉验证)

⚠️ 以下结果使用非官方划分,性能可能被高估,仅供架构对比参考。

排名 模型 性能指标 年份 评估协议 关键技术 完整引用 代码
1 ResBiLSTM Acc 95.03%, F1 95.03% 2024 10-fold CV (7 类) ResNet1D + BiLSTM Zhao et al., 2024, Front. Comp. Neurosci. DOI: 10.3389/fncom.2024.1415967
2 SeizureNet F1 0.909 (96Hz) 2019 5-fold CV (发作类型) DenseNet 密集特征学习 SeizureNet, 2019, arXiv:1903.03232
3 Domain Adaptation TSS SOTA (MICCAI 2024) 2024 TUSZ v1.5.2 注意力 CNN + 域适应 Fan et al., 2024, MICCAI. DOI: 10.1007/978-3-031-72086-4_2 GitHub
TUAB 异常 EEG 检测
排名 模型 性能指标 年份 关键技术 完整引用
1 xresnet1d101 AUROC 0.827 2021 1D ResNet Strodthoff & Strodthoff, 2021
2 ConvNet (TUABEXB) AUROC 0.78-0.82 2023 自动标注扩展训练集 Kiessner et al., 2023, Computers in Biology and Medicine

§8.2 SOTA 总结与选型建议

你的目标 推荐模型 理由
复现最新 SOTA / 挑战赛 Large EEG-U-Transformer 2025 挑战赛冠军,无需预训练即可超越基础模型
可解释性 / 临床部署 CatBoost Ensemble 专家特征 + 梯度提升,透明可解释,严格遵循官方划分
快速基线 / 资源有限 ResNet-18 (NEDC) NEDC 官方配套系统,含实时解码器
多类发作类型分类 SeizureNet 专为发作类型分类设计,F1 0.909
跨患者泛化 Domain Adaptation TSS 注意力 + 域适应,MICCAI 2024

§8.3 评估协议

推荐标准协议(基于 Zabihi et al., 2026 + SzCORE):

  1. 数据划分:严格使用 TUSZ 官方 Train/Dev/Eval,患者级不重叠
  2. 预处理:60s 窗口,15s 步长,连续 EEG 评估
  3. Dev 集决策:在 Dev 集上联合优化阈值和后处理(约束:Specificity ≥ 0.93, FP ≤ 0.69/h)
  4. Eval 集评估:冻结 Dev 集策略,仅在 Eval 集上评估一次
  5. 报告指标:窗口级 AUROC + Balanced Accuracy + F1;事件级 Sensitivity + FP/hour + PPV
  6. 基线对标:与 CatBoost Ensemble (AUROC 0.92) 对标

§8.4 相关数据集

数据集 类型 规模 关系
CHB-MIT Scalp EEG 儿科 EEG 发作检测 23 患者 / 986h 互补验证集,儿科场景
Siena Scalp EEG 成人 EEG 发作检测 14 患者 / 87h 2025 挑战赛使用,外部验证
Bonn EEG Dataset 小规模 EEG 分类 500 段 23.6s 早期基准,规模过小
Sleep-EDF 多导睡眠图 197 受试者 不同任务(睡眠分期)
TUH EEG Corpus (TUEG) 大规模无标注 EEG 26,846 记录 TUSZ 的母库,预训练数据源

§8.5 关键论文

  1. Obeid, I. & Picone, J. (2016). “The Temple University Hospital EEG Data Corpus.” Frontiers in Neuroscience, 10:196. DOI: 10.3389/fnins.2016.00196 — 奠基论文,描述 TUEG 主库的采集、脱敏和组织结构
  2. Shah, V. et al. (2018). “The Temple University Hospital Seizure Detection Corpus.” Frontiers in Neuroinformatics, 12:83. DOI: 10.3389/fninf.2018.00083 — TUSZ 核心论文,描述发作标注流程和语料库统计
  3. Wu, K. et al. (2025). “Large EEG-U-Transformer for Time-Step Level Detection Without Pre-Training.” arXiv:2504.00336 — 2025 挑战赛冠军,U 形 Transformer 无需预训练超越基础模型
  4. Zabihi, M. et al. (2026). “A transparent AI assurance and benchmarking framework for EEG seizure detection on TUSZ.” Nature Scientific Reports. DOI: 10.1038/s41598-026-41358-w — 透明基准框架,严格遵循官方划分的可复现基线
  5. Kiessner, A.-K. et al. (2023). “Reaching the ceiling? Empirical scaling behaviour for deep EEG pathology classification.” Computers in Biology and Medicine. — TUAB 扩展研究,自动标注 + 扩展训练集

§8.6 社区活跃度

维度 数值 截至日期
NEDC 注册用户 1,300+(2018 年数据,预计已大幅增长) 2018
TUEG 原始论文引用 800+ 2026-08
TUSZ 论文引用 350+ 2026-08
SzCORE 基准平台算法数 持续增长 2026-08
2025 癫痫检测挑战赛参赛队伍 多支国际团队 2025

§8.7 生态快照

资源 类型 链接 Star/Fork(截至 2026-08) 为什么值得关注
NEDC EVAL 评分工具 官方 官方标准化 EEG 评分包(Python),实现多种标准评估指标
NEDC ERDR 实时检测系统 官方 基于 ResNet-18 的实时癫痫检测系统,含训练和解码器
SeizureTransformer 模型代码 GitHub 活跃 2025 挑战赛冠军模型,支持时间步级和窗口级检测
EEG_DOMAIN 域适应代码 GitHub MICCAI 2024 域适应方法,解决跨患者泛化问题
SzCORE 基准平台 epilepsybenchmarks.com 标准化癫痫检测评测协议和排行榜
Braindecode 工具库 GitHub 800+/200+ EEG 深度学习工具库,原生支持 TUH 数据加载
MNE-Python 信号处理库 GitHub 2,800+/1,000+ EEG 信号处理标准库,EDF 读取 + 滤波 + 可视化

§9 相关资源与引用(Resources & Citation)

§9.1 引用格式

TUEG 主库

@article{obeid2016temple,
  title={The Temple University Hospital EEG Data Corpus},
  author={Obeid, Iyad and Picone, Joseph},
  journal={Frontiers in Neuroscience},
  volume={10},
  pages={196},
  year={2016},
  doi={10.3389/fnins.2016.00196}
}

TUSZ 子库

@article{shah2018temple,
  title={The Temple University Hospital Seizure Detection Corpus},
  author={Shah, Vinit and von Weltin, Emily and Lopez, Silvia and McHugh, Jesse and Veloso, Lohith and Golmohammadi, Mehdi and Obeid, Iyad and Picone, Joseph},
  journal={Frontiers in Neuroinformatics},
  volume={12},
  pages={83},
  year={2018},
  doi={10.3389/fninf.2018.00083}
}

§9.2 官方资源

资源 链接
NEDC 主页 https://isip.piconepress.com/projects/nedc/
TUH EEG 下载页 https://isip.piconepress.com/projects/nedc/html/tuh_eeg/index.shtml
申请表 PDF https://isip.piconepress.com/projects/nedc/forms/tuh_eeg.pdf
NEDC 关于我们 https://isip.piconepress.com/projects/nedc/html/about_us.shtml

§9.3 资助来源

  • NIH NHGRI: U01 HG008468

  • NSF: IIP-1622765

  • DARPA

  • University City Science Center

  • Temple University College of Engineering

  • IBM(联合赞助癫痫检测挑战赛)

§10 AI 使用声明卡

字段 内容
AI 模型 Claude 3.5 Sonnet (2025) — 文献研究与条目写作
AI 参与范围 文献检索、技术规格整理、代码示例生成、DAIMS 评估
输入文档 Obeid & Picone (2016) Front. Neurosci.; Shah et al. (2018) Front. Neuroinform.; Zabihi et al. (2026) Nature Sci. Reports; Wu et al. (2025) arXiv:2504.00336; NEDC 官方网站; SzCORE 基准平台; 多篇 TUSZ 基准论文
AI 生成章节 §1-§9 全章节(基于公开文献整理)、§6 代码示例(基于 MNE-Python + PyTorch 标准实践)
最后人工审核 2026-08-04
内容模块 审核者 审核方式 审核状态
§2 医学背景 千方病案医学编辑部 交叉审核 ✅ 已通过
§6 代码示例 千方病案医学编辑部 逻辑审查 ✅ 已通过
§3 数据规格 千方病案医学编辑部 与官方文档交叉比对 ✅ 已验证
§7 DAIMS 评估 千方病案医学编辑部 逐项核查 ✅ 已验证
§8 排行榜 千方病案医学编辑部 论文交叉验证 ✅ 已验证

页面状态:published(全部内容已完成审核并发布)

返回 AI Ready 数据集