信息速览

PPG-DaLiA — 日常活动可穿戴 PPG 心率估计数据集 AI-Ready Wikipedia
INFOBOX
| 数据集名称 | PPG-DaLiA |
| 英文全称 | PPG Dataset for Motion Compensation and Heart Rate Estimation in Daily Life Activities |
| 别名/简称 | PPG-DaLiA、PPG_DaLiA、PPG Dalia |
| 疾病分类 | 无疾病标签——健康人群生理监测(非临床诊断数据集;相关生理量纲见 ICD-11 心血管功能检查用途,非编码疾病) |
| SNOMED CT | 非疾病编码数据集;涉及概念:251292004 Photoplethysmography / 102475003 Measurement of heart rate / 431314004 Heart rate(详见 §2.1b) |
| 数据模态 | 多通道时序生理信号:腕部 PPG(BVP)、ECG、三轴加速度、呼吸、皮肤电导(EDA)、体温 |
| AI 任务类型 | PPG 心率估计(回归)、运动伪差抑制、PPG+ACC 多模态融合、人体活动识别(分类)、HRV 恢复 |
| 样本总数 | 15 名受试者 / 约 36-37 小时 / 64,697 个 8 秒窗 / UCI 标注 8,300,000 采样点 |
| 数据大小 | 2.7 GB(data.zip,内含 15 个受试者 .pkl 文件) |
| 数据格式 | Python pickle(.pkl,每受试者一文件);社区提供 pkl→MATLAB 转换脚本 |
| 许可证 | CC BY 4.0(UCI 页面声明);原始 Uni Siegen 下载页另附"科学非商业用途"说明 |
| 访问级别 | 开放下载(无需申请) |
| DUO 标签 | NRES(UCI CC BY 4.0 分发口径) |
| 语言 | 英文(元数据/readme) |
| 首发日期 | 2019-07-29(UCI 捐赠) |
| 最后更新 | 2019-07-29(UCI v1.0,单版本) |
| 发布机构 | UCI Machine Learning Repository(原采集:Robert Bosch GmbH / 德国锡根大学 Ubiquitous Computing) |
| 官方主页 | https://archive.ics.uci.edu/dataset/495/ppg+dalia |
| 下载地址 | https://archive.ics.uci.edu/dataset/495/ppg+dalia |
| DOI | 10.24432/C53890(数据集)/ 10.3390/s19143079(原始论文) |
| 引用次数 | 502(论文,Google Scholar,截至 2026-09) |
| AI 就绪度评分 | ⭐⭐⭐⭐(4/5)— 金标准与评测协议(LOSO)社区统一、原始 .pkl 结构清晰;扣分项:无官方划分文件、需自行实现预处理与降采样、格式为 Python pickle 而非临床通用格式 |
| 页面状态 | published |
§0 E-E-A-T 信任声明与免责声明
医学审核者:千方病案医学编辑部交叉审核:§2 医学背景(PPG/ECG 生理学背景、心率量纲与临床意义、非诊断定位)、§7 偏倚分析。
数据工程审核者:千方病案医学编辑部交叉审核:§4 DAIMS 数据字典(多模态同步字段字典、窗口分段与金标准生成)、§5 数据划分策略、§6 预处理 Pipeline 和坑点。
审核日期:2026-09-05
审核方式:交叉审核
利益冲突声明:千方病案医数集与 UCI、Robert Bosch、德国锡根大学、Empatica 或 BiosignalsPLUX 无任何商业利益关联。本页面不销售 PPG-DaLiA 数据集本身,仅提供 AI 就绪指南与学术信息服务。
医疗免责声明:本页面提供的医学信息仅供研究和教育目的,不构成医疗建议、诊断或治疗方案。数据集的医学描述基于公开发表的文献,未经逐一临床验证。任何基于该数据集训练的 AI 模型在应用于临床决策前,必须经过独立的临床验证和监管审批。
技术免责声明:本页面的代码示例、预处理建议和基准性能数据基于公开资料整理,不保证在特定环境下的准确性和适用性。使用者应自行验证代码安全性和数据预处理流程的正确性。千方病案医数集不对因使用本页面信息而导致的任何直接或间接损失承担责任。
数据使用合规:使用本页面描述的数据集前,请务必阅读并遵守数据集原始许可协议。PPG-DaLiA 以 CC BY 4.0 分发于 UCI,但原始采集方页面另附"科学、非商业用途"声明——两者存在口径差异,商用前务必与 UCI 页面及采集方确认最终授权。DUO 标签仅供参考,具体使用限制以数据集官方协议为准。
§1 数据集概览
§1.0 30 秒速览
这是什么? PPG-DaLiA 是一个公开的可穿戴心率估计数据集。15 名健康人手腕上戴着一只手环(Empatica E4,能发射绿光照进皮肤测脉搏,即 PPG),胸口系着一条 ECG 采集带(RespiBAN),在坐、上下楼、玩桌上足球、骑车、开车、吃午饭、走路、上班这 8 种贴近真实的日常活动中,被连续记录约 2.5 小时。ECG 是"准确答案"来源——因为它是心脏电活动,可精确算出每分钟心跳。整份数据约 36-37 小时,切成 64,697 个 8 秒小窗。
为什么重要? 智能手表测心率靠的就是手腕 PPG,可人一动、手环一晃,光信号就被"运动干扰"污染,心率和杂音混在一起,这是可穿戴心率不准的头号原因。此前公开数据既短、又只在实验室里走跑步机,练不出真实场景下的鲁棒模型。PPG-DaLiA 是第一个在"真实日常活动"里大规模记录的手腕 PPG 数据集,论文被引超 500 次,成了这个领域评测"动作下心率准不准"的事实标准。
我能用它做什么? 你可以拿它训练 AI 模型:输入 PPG 和加速度信号,让模型输出心率(回归),并用 ECG 给出的真值打分;或做活动识别。社区统一用"留一受试者"(LOSO)协议评测,保证没见过的陌生人也能测准。它能验证你的模型能不能扛住走楼梯、骑车这种强干扰动作——这比实验室小样本数据集更能说明真实可穿戴场景的泛化能力。
§1.1 摘要
PPG-DaLiA(PPG Dataset for Motion Compensation and Heart Rate Estimation in Daily Life Activities)由 Attila Reiss、Ina Indlekofer、Philip Schmidt 与 Kristof Van Laerhoven 提出,2019 年发表于 MDPI Sensors,并由作者团队同步捐赠至 UCI Machine Learning Repository(DOI 10.24432/C53890)。数据集以"贴近真实生活"为设计目标:15 名健康受试者(8 女 7 男,21-55 岁)佩戴胸部 RespiBAN Professional(ECG、呼吸、三轴加速度均 700 Hz)与非惯用手腕的 Empatica E4(PPG/BVP 64 Hz、加速度 32 Hz、EDA 与体温 4 Hz),在一套约 150 分钟、覆盖坐姿/上下楼/桌上足球/骑行/驾车/午餐/行走/办公 8 类活动及显式过渡期的协议下同步采集(论文:可用总时长约 36 小时;多篇复现论文统计为 37.5 小时录制)。心率金标准由 ECG 的三点式 R 峰自动检测加人工逐点校正后,按 8 秒窗、2 秒步长取窗口平均瞬时心率得到(范围 41-187 bpm),共 64,697 个标注窗。作者在论文中提出的 Deep PPG CNN 方案在 LOSO 协议下把 MAE 从经典方法的 11.06 bpm 降至 7.65 bpm(改善 31%),确立该数据集的评测范式。后续 TimePPG/Q-PPG/PULSE 等研究进一步将其推到约 4 bpm 量级。
§1.2 战略价值
运动伪差鲁棒性(算法鲁棒性维度):PPG-DaLiA 的核心战略价值在于它把评测从"实验室受控运动"推进到"真实活动导致的高强度、非平稳运动伪差"。走楼梯(MAE 16.98 bpm)、桌上足球(12.16 bpm)与行走(9.21 bpm)等动作下误差显著放大,而办公/坐姿等静态活动误差仅约 4-5 bpm——这种"活动难度梯度"让研究者能精确判断算法在强干扰下是否会崩溃,是检验泛化能力的稀缺试金石(来源:Deep PPG 论文 Table 11)。
评测协议统一性(可复现性维度):数据集自带的"8 秒窗 + 2 秒步长 + ECG 均值金标准 + LOSO 四折划 15 人"协议被社区几乎一致采用(TimePPG、Q-PPG、PULSE、MH Conv-LSTM 均沿用),MAE(bpm)成为事实统一指标。这使得不同论文结果可跨文比较——这在生理信号数据集中极为少见,极大降低了复现与对标成本(来源:arxiv-vanity.com/papers/2210.11415 等)。
多模态协同(数据多样性维度):同一份录制同时提供腕部(PPG+ACC+EDA+体温)与胸部(ECG+呼吸+ACC)两大设备视图,既满足"PPG+加速度做输入、ECG 做真值"的主流范式,也为呼吸率估计(胸带感应容积描记为真值)、HRV/IBI 恢复、活动识别、联邦个性化等下游任务预留了素材,一库多用(来源:Emergentmind DALIA 主题综述)。
§1.3 同类数据集横向对比表
| 数据集 | 规模 | 设备/模态 | 采样率 | 环境 | 标注/金标准 | 差异化定位 |
|---|---|---|---|---|---|---|
| PPG-DaLiA(本库) | 15 人 / 约 36-37 h / 64,697 窗 | 腕 E4(PPG+ACC+EDA+体温)+ 胸 RespiBAN(ECG+呼吸+ACC) | PPG 64 Hz / ECG 700 Hz | 8 类真实日常活动 | ECG 人工校正 R 峰→窗均值 HR | 最大、活动最全的公开腕戴 PPG 心率基准 |
| IEEE SP Cup 2015 | 12 人 / <1 h / 1,768 训练窗 | 腕部两通道 PPG + ACC | 125 Hz | 走/跑/臂部运动 | ECG 窗均值 HR | 最经典但极短、实验室受控 |
| WESAD | 15 人 / 约 12 h | 腕 E4 + 胸 RespiBAN | PPG 64 Hz / ECG 700 Hz | 基线/压力/娱乐/冥想 | 压力/情感标签 + ECG | 侧重压力与情感,动作干扰较少 |
| Wrist PPG During Exercise | 8 人(3 男 5 女) | 腕 PPG + ACC + 陀螺仪 + 参考 ECG | — | 走/跑/骑行(固定器械) | 运动下 HR | 含陀螺仪,但仅 3 类受控运动 |
| MIMIC-III 波形(参考) | 约 30,000 ICU 患者 | 床旁多导波形(含 PPG/ECG/ABP) | 125 Hz | 重症 ICU | 临床监护 | 临床量大但卧床、无运动伪差 |
§1.4 版本时间轴表
| 时间 | 事件 | 说明 |
|---|---|---|
| 2018-10 | 前作会议论文(EH 2018) | PPG-based HR estimation with Time-Frequency Spectra:A Deep Learning Approach,铺垫方法论 |
| 2019-05-23 | Sensors 论文收稿 | Deep PPG: Large-Scale Heart Rate Estimation with CNNs |
| 2019-07-10 | 论文录用 | Sensors 19(14):3079,评审通过 |
| 2019-07-12 | 论文正式发表 | DOI 10.3390/s19143079,随文公布 Uni Siegen 原始下载页(2.7 GB) |
| 2019-07-29 | UCI 捐赠 v1.0 | UCI 页面上线,DOI 10.24432/C53890,数据.zip 2.7 GB |
| 2020- | 社区生态成型 | DBDP 提供 pkl→.mat 转换、TimePPG/Q-PPG/PULSE 等基准涌现 |
§1.5 典型应用场景
- 运动伪差下的心率回归:输入 8 秒 PPG+ACC 窗,输出窗口平均心率(bpm),LOSO 评测,目标是普通智能手表在真实活动中的准确度。
- 活动识别(HAR):利用加速度+PPG 特征对 8 类活动分类(可含过渡期共 9 类),验证腕戴传感器能否仅凭运动/血流推断用户当前在做的事。
- 运动伪差抑制算法评测:将 ECG 心率真值与 PPG 频谱叠加对比,检验 SpaMa/TROIKA 类频谱去噪方法在楼梯、桌上足球等高干扰活动下的表现。
- 多模态/能量受限边缘部署研究:作为最大公开 PPG 基准,验证 TCN/CNN 量化为 int8 后能否在 STM32 级 MCU 上实时测心率(Q-PPG/TimePPG 范例)。
- 个性化与联邦学习:用某受试者前 25% 数据微调大幅降低该人误差(S5 可从约 15 bpm 降到 <5 bpm),支撑"每用户校准"的联邦/个性化范式研究。
- 跨库域泛化研究:用 PPG-DaLiA 预训练、在 WESAD/IEEE 等异域集上评估迁移与域自适应,检验"大而全"数据能否支撑"小而新"设备(Deep PPG 即四库联评)。
§1.6 何时选择本数据集(决策速览)
| 你的需求 | 是否选 PPG-DaLiA | 建议替代 |
|---|---|---|
| 真实日常活动下评测腕戴 PPG 测心率 | ✅ 首选 | — |
| 需要大量"运动伪差"以压测算法鲁棒性 | ✅ 首选(楼梯/桌上足球难例最全) | — |
| 复现 Deep PPG/TimePPG/Q-PPG 等公认基线 | ✅ 首选(同协议可比) | — |
| 想做"静态/受控运动"快速冒烟(成本低) | 可(但强干扰不足) | IEEE SP Cup 2015 |
| 想研究压力/情感(非测心率) | ❌ | WESAD |
| 想做疾病/心律失常/临床人群研究 | ❌(健康数据、无病理) | MIMIC 波形库等临床数据 |
| 需要全球/跨肤色代表性 | ❌(单点健康人群) | 需自行补充多中心数据 |
一句话:PPG-DaLiA 是"真实日常活动下腕戴 PPG 心率估计"这一任务的事实基准,凡研究目标落在该任务上,用它做基准最省心;凡超出"健康人日常活动测心率"的范围,都应在它之外另行获取数据。
§2 医学背景
§2.1 ICD-11 编码映射表
PPG-DaLiA 采集的是健康受试者的生理信号,不含疾病诊断,因此无法也无须映射疾病 ICD-11 编码。但数据集所支撑的心率估计,其临床应用场景(可穿戴慢病与心血管监测)落在 ICD-11 相关章节。下表给出"数据集所测生理量纲"到 ICD-11 临床应用目的的对齐,便于理解数据集的临床语境。
| 数据集关注量 | ICD-11 相关用途 | 临床语境 | 说明 |
|---|---|---|---|
| 心率(PPG 估计目标) | MG42 心脏节律与速率异常相关检查(量纲层,非疾病) | 可穿戴连续心率监测 | PPG-DaLiA 是验证监测算法,不含疾病病例 |
| 运动伪差抑制 | XS5C 检查性生理测量(非编码) | 保证日常活动下测量可信 | 数据用于算法开发而非诊断 |
| ECG 真值生成 | 心电图检查(方法与参考) | 提供心率金标准 | 仅在受试者侧记录 |
§2.1b SNOMED CT 映射表
| 标签/概念 | ICD-11 | SNOMED CT 码 | 术语 |
|---|---|---|---|
| 光电容积脉搏波检查 | MG42 相关检查(非编码) | 251292004 | Photoplethysmography |
| 心率测量 | 量纲 | 102475003 | Measurement of heart rate |
| 心率(生理量) | 量纲 | 431314004 | Heart rate |
| 心电图采集 | 方法参考 | 164849005 | Electrocardiogram |
| 日常活动状态监测 | 用途 | 428859008 | Activities of daily living (observable entity) |
§2.2 生理学背景与流行病学语境
光电容积脉搏波(Photoplethysmography, PPG)通过向皮肤照射绿光并测量被血红蛋白吸收后反射光强度的脉动变化,无创反映每搏血容量变化,从而可推算瞬时脉搏/心率。其优势是成本低、可嵌入腕带/手表持续佩戴;其短板是极易被运动伪差污染——肢体摆动使传感器与皮肤相对位移、环境光泄漏,产生与真实脉搏频谱重叠的噪声。ECG(心电图)通过记录心肌电活动给出精确的 R-R 间期,是心率的"金标准",但需要贴身电极,难以长期日常佩戴。因此可穿戴行业普遍采用"手腕 PPG 估心率 + 胸带 ECG 做标定/真值"的组合。
流行病学上,PPG-DaLiA 面向的是庞大的可穿戴慢病与心血管风险监测需求:房颤筛查、高血压随访、运动心率区间管理等都依赖可靠的连续心率数据。然而它本身记录的是 15 名健康员工,不包含疾病人群、心律失常发作或极端生理状态,任何临床诊断结论都不能由该数据集得出。它更接近"测量科学的试验床":验证"在日常真实活动中,腕戴光学传感器能否给出与 ECG 一致的心率读数"。
§2.2b PPG 信号物理与"估心率为什么难"
PPG 波形是动脉血容量随每次心搏搏动的透/反射光调制。健康静息时波形呈稳定的"主峰—降支—重搏波"周期,频谱中峰频即等于心率。但该信号幅度极小(相对基线仅约 1-3%),且对探头-皮肤相对运动、环境光、组织压迫极其敏感:
| 干扰源 | 机制 | 在 PPG-DaLiA 中的体现 |
|---|---|---|
| 运动伪差(MA) | 肢体摆动使探头滑动、静脉移位,产生与脉搏同量级甚至更大的频谱分量 | 行走/楼梯/桌上足球时 ECG 真值清晰而 PPG 频谱被污染 |
| 非平稳性 | 动作随活动变化,伪差频率漂移,非静止可建模 | 楼梯等活动的伪差是突发、剧烈、非周期的 |
| 基线漂移 | 组织压迫/呼吸引起低频漂移 | 需高通/带通(0.4-4 Hz)去除 |
| 肤色/血流差异 | 不同肤色的光学吸收使信噪比不同 | 记录了 Fitzpatrick SKT,用于偏倚审计 |
这正是为什么"测心率的准"不能只看静态数据:静态 PPG 信噪比极高、任何算法都好;只有在真实活动引入的强伪差下,不同算法(经典频谱 vs 深度学习)的能力差距才暴露——PPG-DaLiA 的价值正在于把这些伪差"放回真实日常场景"。
临床测量语境:本数据集虽非疾病库,其评测的却是连续可穿戴心率的"测量可靠性",这是数字健康(房颤负荷、静息心率趋势、运动区间时长)应用的前置条件——测量都不可信,下游任何医学推断都无从谈起。因此它服务于"医疗器械级算法验证"的早期阶段,而非疾病预测本身。
§2.3 临床任务定义(针对 AI 就绪)
| 任务 | 定义 | 输入 | 输出/金标准 | 评测指标 |
|---|---|---|---|---|
| 心率估计(回归) | 从腕戴 PPG(+ACC) 估计窗口平均心率 | 8 s PPG + ACC 窗 | ECG 均值瞬时 HR(bpm) | MAE (bpm)、σ、P 值相关 |
| 运动伪差抑制 | 在强运动伪差下仍准确测 HR | PPG+ACC(干扰叠加) | ECG HR | MAE 按活动分层 |
| 活动识别(分类) | 推断受试者所做活动 | ACC(+PPG) 特征 | 8 类活动标签 | 分类准确率 / F1 |
| 个性化校准 | 用个体少量数据校准全局模型 | 个体前段数据 | 该个体 HR | MAE 降低幅度 |
§2.4 患者人群表
| 维度 | 内容 |
|---|---|
| 来源 | 德国锡根 Robert Bosch / 锡根大学研究园区的健康志愿者(研究受试者) |
| 时间 | 2018-2019 年(Sensors 2019 发表时公布采集) |
| 年龄 | 21-55 岁 |
| 性别 | 8 女 7 男 |
| 种族/肤色 | 未系统披露;记录了 Fitzpatrick 皮肤类型(SKT)与体能等级(FL,1-6 量表) |
| 就医类型 | 健康人群(非患者、无临床就诊);研究经园区工人委员会与数据保护官批准 |
§2.5 临床价值
对可穿戴与数字健康,PPG-DaLiA 的价值在于量化"日常活动条件下腕戴光学测心率的误差上界",从而推动:(1) 运动伪差鲁棒算法的成熟(从 11 bpm 类经典方法到约 4 bpm 的深度模型);(2) 为房颤筛查、心率区间管理等下游提供"传感器测量可靠性"的证据基础;(3) 验证边缘 MCU 上低功耗实时测心的可行性,支撑长期可穿戴监测。需再次强调其局限:非疾病数据,任何诊断用途均超出数据集定位。
§2.6 金标准表
| 划分/标注 | 方式 | 标注者 | 性质 |
|---|---|---|---|
| 活动标签 | 采集协议预定 + 显式过渡期单独标记 | 研究者(协议驱动,非主观标注) | 客观协议标签 |
| 心率真值 | ECG R 峰自动检测(Pan-Tompkins 类)→ 人工逐窗检查校正 | 研究者人工 + 算法辅助 | 半自动金标准(人工把关) |
| 窗口定义 | 8 s 窗 / 2 s 步长滑动取均值瞬时 HR | 研究者 | 方法学约定(社区通用) |
| 设备同步 | 开始/结束各一次"双击"手势 + 人工时基校准 | 研究者 | 人工同步(存在手工误差) |
§3 数据集规格
§3.0 版本抉择矩阵
PPG-DaLiA 在 UCI 仅有一个正式版本(v1.0,2019-07-29),原始 Uni Siegen 下载页提供同一份 2.7 GB 数据。社区研究中不存在多版本选择问题,本矩阵说明"从哪个渠道取数"与"用原始 pkl 还是社区重打包"的差异。
| 你的需求 | 推荐渠道/形态 | 大小 | 理由 |
|---|---|---|---|
| 官方权威、附带稳定 DOI 引用 | UCI 官方 data.zip(.pkl) | 2.7 GB | DOI 10.24432/C53890 可稳定引用,页面维护良好 |
| 需要 MATLAB 工作流 | UCI 取 .pkl 后跑 DBDP 转换脚本 | 转后 .mat | 官方仅提供 .pkl,MATLAB 需转换脚本(非官方) |
| 复现 Deep PPG 论文特征 | Uni Siegen 原始链接(论文随附) | 2.7 GB | 与论文 Sensors 2019 同源,便于逐窗复现 |
| 轻量原型(不想整包) | 自选 2-3 个受试者 .pkl | 数百 MB | 先验证管线,再全量训练 |
§3.1 模态详情
| 模态 | 设备 | 通道 | 采样率 | 量程/精度(据论文) | 任务用途 |
|---|---|---|---|---|---|
| PPG(BVP) | Empatica E4(非惯用手腕) | 1(绿光通道公开) | 64 Hz | 4 颗 LED(2 绿 2 红)、2 光敏单元 | HR 估计主输入 |
| 三轴加速度 | E4 | x/y/z | 32 Hz | ±2 g / 8-bit | 运动伪差参考 |
| 皮肤电导 EDA | E4 | 1 | 4 Hz | 0.01-100 μS / 900 pS | 附加(压力等) |
| 体温 | E4 | 1 | 4 Hz | 精度 ±0.2 °C(36-39 °C) | 附加 |
| ECG | RespiBAN(胸) | 1(三点式,±1.5 mV / 16-bit,0.5-100 Hz) | 700 Hz | Ag/AgCl 电极 | 心率金标准 |
| 呼吸 | RespiBAN | 1(感应容积描记,±50%) | 700 Hz | 16-bit | 附加(可作呼吸率真值) |
| 三轴加速度(胸) | RespiBAN | x/y/z | 700 Hz | ±3.6 g,50 Hz 低通 | 附加 |
§3.2 按子集样本数表
| 活动标签 | 窗口数(8 s 窗) | 均值 HR (bpm) | 特征 |
|---|---|---|---|
| Transition(过渡期) | 17,495 | 94.72 | 显式标注,量最大 |
| Lunch(午餐休息) | 13,552 | 83.58 | 静态低干扰 |
| Working(办公室工作) | 8,502 | 76.40 | 静态低干扰 |
| Driving(驾车) | 6,845 | 84.70 | 坐姿、低干扰 |
| Walking(行走) | 4,697 | 99.18 | 中等干扰 |
| Sitting(坐) | 4,573 | 61.07 | 静态最低 HR |
| Stairs(上下楼) | 3,242 | 118.53 | 强干扰、最高误差 |
| Cycling(骑行) | 3,479 | 123.05 | 强干扰、最高均值 HR |
| Table soccer(桌上足球) | 2,312 | 90.40 | 强干扰、高误差 |
| 合计(含过渡期) | 64,697 | — | 8 类 + 过渡期 |
§3.3 格式表
| 文件/渠道 | 格式 | 说明 |
|---|---|---|
| UCI data.zip | application/zip | 内含每受试者一个 Python pickle(.pkl) |
| 单受试者数据 | Python pickle(dict) | 同步原始信号 + HR 标签 + 活动标签 |
| readme.pdf | 字段/协议/同步/真值生成详细说明(798.6 KB) | |
| 社区 .mat 重打包 | MATLAB .mat | 由 DBDP/ppg-beats 转换脚本生成,非官方 |
§3.4 存储大小
UCI 单 zip 下载 2.7 GB;解压后约每受试者数百 MB(合计解压体积需预留,一般建议 ≥6 GB 工作盘)。若在训练前把所有通道按社区协议重采样到 32 Hz 并切窗,会显著压缩驻留内存;建议至少 8 GB RAM 处理单受试者原始数组。
§3.5 标注方式
活动标签来自采集协议预定顺序(研究者在协议中定义活动边界,过渡期显式单独标记),属客观协议标签而非主观人工标注。心率真值为半自动:ECG R 峰用成熟检测器自动提取,随后研究者逐例人工检查与校正(去除伪峰、补漏峰),再按 8 s 窗取均值。因此"标注质量"的关键变量是人工作校正的彻底性,尤其在高运动伪差窗(如桌上足球误 R 峰)上。
§3.6 标注者资质与一致性
论文未给出独立标注者人数或一致性 Kappa 统计;真值生成由作者团队(信号处理研究者)完成,方法为"自动 R 峰检测 + 人工把关"。因原始信号与校正后 R 峰索引都在 pkl 中公开,使用者可自行复核校正质量——这是本数据集标注可信度的重要机制。
§3.7 采集周期
每受试者一次性约 150 分钟协议(连续单会话);受试者 S6 因一次硬件故障,其后数据丢失,有效数据仅约前 90 分钟(论文明确注明)。全部 15 人的采集在 2018-2019 年间完成。
§3.8 地域覆盖
单一地点:德国锡根地区研究园区及其周边(驾车活动在周边城镇与乡道进行、午餐在园区食堂、行走在工作园区内)。属单中心、单人群地理范围,不具备人口地理代表性。
§3.9 设备规格
- 腕部 Empatica E4:PPG 系统 4 LED(2 绿 2 红)+ 2 光敏单元(共 14 mm² 敏感面积),输出氧合/去氧峰差信号 64 Hz;加速度 ±2 g、8-bit、32 Hz;EDA 0.01-100 μS、900 pS、4 Hz;体温 4 Hz、±0.2 °C。戴于非惯用手腕。
- 胸部 RespiBAN Professional(BiosignalsPLUX):ECG 三点式(右侧胸大肌中央/左下肋/左胸大肌接地),±1.5 mV、16-bit、0.5-100 Hz 带通;呼吸感应容积描记 ±50%;集成三轴加速度 ±3.6 g、50 Hz 低通;全部 700 Hz。
§3.10 深度溯源链
采集与发布链路:健康志愿者招募 → 研究园区伦理/工委会与数据保护官批准 → 双设备同步佩戴并按协议完成 8 活动 → 数据本机存储后转出 → ECG R 峰自动+人工校正生成 HR → 8 s 窗重切 → 由 Bosch/锡根大学团队于 2019 年捐赠 UCI(DOI 10.24432/C53890),论文 Sensors 19(14):3079 同步发表并提供 Uni Siegen 下载。衍生生态由 DBDP、ppg-beats、TimePPG/Q-PPG 等维护转换与基准代码。
§4 数据结构
§4.0 目录树
data.zip 解压后为 15 个受试者 pickle 文件与说明文档。典型布局如下:
PPG-DaLiA/
├── data/
│ ├── S1.pkl
│ ├── S2.pkl
│ ├── S3.pkl
│ ├── ...
│ └── S15.pkl
└── readme.pdf
单个受试者 pkl 载入后为字典,其典型键结构(社区 ppg-beats/DBDP 解析所依据):
S1 = { 'signal': { 'wrist': {'BVP': float[64Hz], 'ACC': float[32Hz,3],
'EDA': float[4Hz], 'TEMP': float[4Hz]},
'chest': {'ECG': float[700Hz], 'RESP': float[700Hz],
'ACC': float[700Hz,3]} },
'activity': int[4Hz], # 活动标签序列(与活动名表对应)
'activity_types': str[list], # 活动名称表(索引→活动名)
'label': float[2Hz], # 心率真值(bpm,8s 窗步长 2s)
'subject': S1, ... } # 受试者元数据(年龄/性别/身高/体重等)
注意不同社区解析脚本对键名(如 activity_types vs activity_names、label vs HR)口径可能略有差异——导入前务必核对目标工具期望的键。
§4.1 DAIMS 字段字典
下表为按社区常用解析得到的核心字段字典(8 列)。
| 字段名 | 类型 | 说明 | 示例值 | AI 用途 | 观测误差 | 缺失编码 | 取值范围 |
|---|---|---|---|---|---|---|---|
| wrist/BVP | float[] | 绿光 PPG 原始信号(64 Hz) | 4.2e5 量级原始 ADC | HR 估计主输入 | 运动伪差/基线漂移 | 无(连续) | 相对 ADC 值 |
| wrist/ACC | float[] | 三轴加速度(32 Hz) | [-1.2, 0.8, 9.4] | 运动伪差参考 | 量化 ±0.5 LSB | 无 | ±2 g |
| wrist/EDA | float[] | 皮肤电导(4 Hz) | 3.2 μS | 附加 | 运动伪差 | 无 | 0.01-100 μS |
| wrist/TEMP | float[] | 体温(4 Hz) | 32.4 °C | 附加 | ±0.2 °C | 无 | 皮肤温度带 |
| chest/ECG | float[] | ECG 原始(700 Hz) | ±mV 量级 | 心率真值来源 | 电极/运动伪差 | 无 | ±1.5 mV |
| chest/RESP | float[] | 呼吸(700 Hz) | ±% 位移 | 呼吸率(附加) | — | 无 | ±50% |
| chest/ACC | float[] | 胸部加速度(700 Hz) | 三轴 | 附加运动 | — | 无 | ±3.6 g |
| activity | int[] | 活动标签序列(4 Hz) | 0-8 | HAR 分类 / 分层误差 | 协议客观 | 无 | 0=过渡…8 |
| activity_types | str[] | 活动名表 | Sitting 等 | 标签解码 | — | — | 8+过渡 |
| label | float[] | HR 金标准(bpm) | 78.5 | 回归目标 | 人工 R 峰校正 | 无 | 41-187 |
| subject 元数据 | mixed | 年龄/性别/身高/体重/SKT/FL | 30, f, 168, 62 | 偏倚分析 | 自报 | 无 | — |
§4.2 标签分布统计
HR 金标准(8 s 窗)分布见 §3.2 活动子集表与下述按 HR 区间的分段(来源:Deep PPG 论文 Table 2,总和恰为 64,697):
| HR 区间 (bpm) | 窗数 |
|---|---|
| 40-60 | 3,746 |
| 60-80 | 21,585 |
| 80-100 | 22,374 |
| 100-120 | 9,884 |
| 120-140 | 4,878 |
| 140-160 | 1,679 |
| 160-180 | 512 |
| 180-200 | 39 |
可见主体落在 60-120 bpm 的中低强度区间(日常活动定位),高 HR 窗稀缺。这也解释了为何以"日常活动"为目标的可穿戴测心率比"跑步/冲刺"场景更容易做到低误差——极端高强度窗在数据集中先天不足。
§4.3 关键统计
- 总窗 64,697;其中 8 类命名活动合计 47,202 窗,过渡期 17,495 窗。
- HR 范围 41-187 bpm(跨全体样本)。
- 各活动样本量与均值 HR 见 §3.2。
- 受试者 S5 平均 HR 显著高于其他受试者(个体差异异常项);S6 因缺后段低强度活动而均值偏高(见 §7 偏倚)。
§4.3b 会话级 HR 洞察(论文 Table 3 解读)
| 受试者特征 | 说明(来源:Deep PPG 论文) |
|---|---|
| 普遍 | 多数受试者会话 HR 统计彼此相近,符合"同一园区日常活动"的同质性 |
| S5 | 平均 HR 显著高于其他 14 人,属生理/体质离群者,是多篇论文跨人 MAE 的主误差源 |
| S6 | 仅前约 90 分钟有效;其有效部分以中高强度活动为主,故会话均值偏高,并非其生理异常 |
| 其余 | 各人 HR 统计基本可比,会话与受试者在单会话设计中可互换 |
这一会话级洞察直接影响两件事:(1) 做 LOSO 时不要因个别离群受试者(S5)的异常就把其剔除——那会掩盖真实跨人难度;(2) 在论文中如实报告 S6 的截断,避免读者误读其 HR 分布。
§4.4 数据层级
受试者(S1-S15)→ 单会话协议 → 逐通道时序(不同采样率:PPG 64 / ACC 32 / ECG 700 Hz)→ 8 s 窗(2 s 步长,相邻窗 60% 重叠)→ 每窗一个 HR 真值标签。层级核心是"受试者"层:所有数据以受试者为最大独立性单位,LOSO 划分即在该层进行,避免同一人窗混入训练与测试。时间重叠意味着窗级随机切分会产生严重相关性(见坑点 2)。
§4.5 缺失值处理
数据集声明 “Has Missing Values? No”。实际缺失来自整段数据丢失(受试者 S6 后半段因硬件故障缺失),而非逐点 NaN。因此在按受试者切窗、训练时,须把 S6 视为"可用时长更短"的受试者(仅约 90 分钟),不可假设每受试者窗数一致。逐点层面无 NaN 编码;皮肤/肤色等元数据按受试者自报完整提供。
信息性缺失编码表如下:
| 缺失类型 | 表现 | 是否"信息性" | 处理建议 |
|---|---|---|---|
| 逐点 NaN | 无(声明无缺失) | 否 | 无需 impute |
| S6 后 60 分钟整段 | pkl 中该段信号与标签不存在 | 是——缺失段为低强度活动,导致 S6 均值 HR 偏高 | 保留其现有 90 分钟,勿补齐;报告时注明 |
| 元数据 | 每受试者均有年龄/性别/身高/体重/SKT/FL | 否 | 完整 |
处理原则:永远不要"猜"S6 缺失段的活动或 HR;把 S6 当作一个样本量较小的受试者即可,缺失段的信息内容(低强度活动)本身就是偏倚来源,不应以插补掩盖。
§4.6 受试者元数据
每受试者 pkl 内含一份人口/体质元数据,是偏倚审计与个性化建模的依据(具体键名以 readme.pdf 为准)。
| 元数据 | 含义 | 用途 |
|---|---|---|
| subject | 受试者编号 S1-S15 | 主键、LOSO 切分 |
| age / gender | 年龄(21-55)、性别(8 女 7 男) | 人口统计/分层 |
| height / weight | 身高 (cm) / 体重 (kg) | 体质特征 |
| SKT | Fitzpatrick 皮肤类型(肤色) | 光学测量偏倚审计 |
| FL | 体能等级(1-6,每周运动频率) | 与 HR 水平相关的混杂 |
| ECGbpm / label | ECG 衍生心率标签(每 8 s 窗) | 回归目标(冗余派生) |
要点:(1) 肤色(SKT)与体能(FL)是影响 PPG 信噪比与基础心率的已知混杂,跨人建模若把 FL 当作特征可能吸收"谁的体能好"而非"动作下测心准不准";(2) 性别/年龄可用于子群分层报告,但 15 人样本不足以做稳健的分组统计,子群结论只能作方向性观察;(3) FL/SKT 均为受试者自报,存在主观误差。
§5 划分与使用建议
§5.1 官方划分
PPG-DaLiA 不提供官方训练/测试划分文件,只给出受试者 S1-S15 与时间连续的真实录制。官方评测范式在论文中定义:Leave-One-Session-Out(LOSO)/ Leave-One-Subject-Out(LOSO)——15 个受试者随机分成 4 折,3 折做训练,剩下一折内再分出一名受试者为测试、其余为验证,循环 15 次使每人都做过测试。此协议被绝大多数后续研究沿用。
§5.2 社区惯例划分
社区几乎统一采用:(1) 数据降采样至 32 Hz(PPG 从 64 Hz、ACC 已 32 Hz;部分论文把 chest ECG 也压到 32 Hz 仅作标签对齐);(2) 以原 8 s 窗为输入单元(部分重建 4×256 张量);(3) 每通道 z-score 标准化;(4) LOSO 训练,报告跨 15 人的平均 MAE ± 标准差。TimePPG/Q-PPG/PULSE/MH Conv-LSTM 均依此,使结果可比。
§5.3 划分策略建议与泄漏风险
必须按受试者切分,切勿按窗随机切——同一受试者相邻 8 s 窗(2 s 步长,60% 重叠)高度相关,若按窗随机分流会造成严重时间信息泄漏,跨人 MAE 会虚高。S6 数据仅前段有效,其窗数少、且缺失段为低强度活动,导致其均值 HR 偏高——若随机抽样会让 S6 整组 HR 分布偏移,应按完整会话整段使用。论文 Table 3 明确 S5 为平均 HR 异常高的离群受试者,跨人评测时应保留其误差的逐窗报告以便诊断。
§5.4 交叉验证建议
建议沿用 15 折 LOSO(一次留一受试者),报告 mean MAE ± std across 15 test subjects,并按活动分层(尤其 Stairs/Table soccer/Walking)汇报,以暴露模型在强干扰下的短板。对在意资源的小实验,可先用 3-4 名代表性受试者(覆盖离群 S5 与静态/动态混合)做快速冒烟测试。
§5.5 外部验证建议
跨数据集泛化验证建议使用 WESAD(同团队、同设备生态、不同活动/情绪协议)与 IEEE SP Cup 2015(同任务、125 Hz 双通道 PPG)——Deep PPG 论文即在四数据集上评估 CNN,验证"在大数据集上训练可泛化到小/异域数据集"。注意各集采样率与通道数不同,输入表示需统一。
§5.6 一份可复现的实验设置清单
为便于复现与对标文献,把常用设置固化为清单:
| 环节 | 推荐取值 | 出处/说明 |
|---|---|---|
| 输入信号 | 腕部 BVP(1ch) + 三轴 ACC(3ch),共 4 通道 | Q-PPG/TimePPG |
| 重采样 | 全部统一到 32 Hz | arxiv-vanity 2203.14907 |
| 窗 | 8 s(256 样本),步长 2 s | 论文真值窗 |
| 输入张量 | 4×256(channel × time),z-score 按通道 | PULSE 4×256 |
| 归一化 | 通道级 z-score,统计量只在训练受试者上拟合并冻结 | 坑点 2/5 |
| 划分 | 15 折 LOSO,留一受试者 | Deep PPG 协议 |
| 优化 | Adam,lr 5e-4(参考 PULSE),early-stop 150 迭代 | arXiv 2210.11415 |
| 后处理 | 输出相对近 10 次均值超 ±10% 即钳制(可选,报告时注明) | PULSE 约定 |
| 指标 | 逐受试者 MAE → mean ± std;附按活动分层 MAE | 论文 Table 10/11 |
把上表作为实验配置的"协议头"写进论文/README,读者即可一键复现并公平对标;任何偏离(如改输入通道、去掉 z-score、加后处理)都应在数值旁注明,否则会触发坑点 5 的不可比陷阱。
§6 AI 就绪指南
§6.0 云端快速启动
可在本地 Python 3.8+ 环境直接处理 .pkl(无需 GPU 即可跑通预处理与冒烟训练;完整 CNN 训练建议单卡 GPU 或免费 Colab/云实例)。依赖:numpy、scipy、scikit-learn、pytorch(§6.4)。如需将 pkl 转 .mat,可参考 DBDP 的 convert_subject_pickle_files_to_mat.py。
最小环境清单:
# requirements.txt
numpy>=1.21
scipy>=1.7
scikit-learn>=1.0
torch>=1.12 # CPU 即可先跑通冒烟,GPU 可选
在免费 Colab/云实例上:把 data.zip 传到工作目录 → unzip → 逐受试者读 .pkl → 用 §6.3 切窗。2.7 GB 解压对 8 GB 内存足够;若内存吃紧,可一次只加载 1-2 个受试者、切完即写盘成 .npz,避免全量驻留。
# 云端快速冒烟(示意)
# !wget -O data.zip "https://archive.ics.uci.edu/static/public/495/ppg+dalia.zip"
# !unzip -o data.zip
# 加载 S1 验证管线,见 §6.1 / §6.3
§6.1 快速上手
假设数据目录结构为 data/S1.pkl ... data/S15.pkl。下列代码加载一个受试者并打印键与关键形状,随后演示按 8 s 窗聚合 HR 真值、做活动标签分布。
import pickle, numpy as np
# 目录预期:PPG-DaLiA/data/S1.pkl ... S15.pkl
data_root = "PPG-DaLiA/data"
with open(f"{data_root}/S1.pkl", "rb") as f:
subj = pickle.load(f)
print("顶层键:", list(subj.keys()))
sig = subj["signal"]
print("wrist BVP 采样点数(64Hz):", len(sig["wrist"]["BVP"]))
print("chest ECG 采样点数(700Hz):", len(sig["chest"]["ECG"]))
print("activity 采样点数:", len(subj["activity"]),
"| 活动名表:", subj.get("activity_types"))
print("HR label 点数:", len(subj["label"]),
"| 首个 HR:", subj["label"][:3])
活动标签是整数索引,需用 activity_types 解码为活动名;受试者元数据也在此字典中,用于偏倚审计。
# 解码活动:把逐点 4Hz 活动索引映射到活动名
act_names = subj.get("activity_types")
print("活动名表:", act_names)
# 采样一个活动标签直方图(按 4Hz 点计数)
import numpy as np
act = np.asarray(subj["activity"])
unique, counts = np.unique(act, return_counts=True)
for code, cnt in zip(unique, counts):
name = act_names[code] if act_names and code < len(act_names) else str(code)
print(f"活动 {name}: {cnt} 点 (~{cnt/4/3600:.2f} h)")
# 受试者元数据(示意键;实际键名以 readme 为准)
meta = subj.get("subject", subj)
print("受试者元数据键:", list(meta.keys()) if isinstance(meta, dict) else meta)
提示:
activity为 4 Hz 逐点标签、label为 2 Hz HR(每窗一个),signal各通道采样率不同(64/32/700/4 Hz)。读字段时务必按采样率换算时间轴,勿直接把不同长度数组当同一时间线(见 §4.1 与坑点 4)。
§6.2 数据获取
| 项目 | 内容 |
|---|---|
| 下载地址 | https://archive.ics.uci.edu/dataset/495/ppg+dalia |
| 文件 | data.zip(2.7 GB)+ readme.pdf(798.6 KB) |
| 申请流程 | 免申请,直接下载;引用请按 §9 |
| 备用渠道 | Uni Siegen 原始页(ubi29…/data_ppgdalia.html,2.7 GB) |
# 示例:命令行下载(如环境允许)
cd /your/work && mkdir -p ppgdalia && cd ppgdalia
# wget -O data.zip "https://archive.ics.uci.edu/static/public/495/ppg+dalia.zip"
unzip -o data.zip
ls
下载与运行环境注意事项:
| 事项 | 说明 |
|---|---|
| 空间 | 需 ≥2.7 GB 下载 + ≥6 GB 解压/中间数组空间 |
| Python 版本 | .pkl 用 Python 读取即可;若为较旧序列化需 encoding 参数(见坑点 7) |
| 依赖 | numpy/scipy 预处理、pytorch 训练;转 .mat 需 DBDP 脚本 |
| 校验 | 下载后核对 zip 大小与 readme 中的 md5/说明(如有),防止传输损坏 |
| 离线/慢网 | UCI 与 Uni Siegen 均为静态托管,支持断点续传(wget -c) |
提示:UCI 页面用 ucimlrepo 包也能
fetch_ucirepo(id=495)取元数据,但原始 64/700 Hz 波形仍建议直接下载 zip 后本地切窗,ucimlrepo 主要面向汇总视图。
§6.3 预处理全流程
标准预处理:把每通道按社区协议对齐到 32 Hz → 切 8 s 窗(2 s 步长)→ 生成 PPG 与 ACC 的 4×256 输入张量(PPG 1 通道 + ACC 3 通道)→ 取对应窗 HR 真值 → 每通道 z-score。以下给出可运行的轻量实现。
import numpy as np, pickle, os
FS = 32 # 目标采样率
WIN, STEP = 8, 2 # 秒
subjects = [f"S{i}.pkl" for i in range(1, 16)]
def load_and_window(path):
with open(path, "rb") as f:
subj = pickle.load(f)
sig = subj["signal"]
ppg = np.asarray(sig["wrist"]["BVP"], dtype=np.float64)
acc = np.asarray(sig["wrist"]["ACC"], dtype=np.float64) # (N,3)
# 重采样 PPG 64->32 Hz:线性插值到统一长度
n_ppg_old = ppg.shape[0]
t_old = np.arange(n_ppg_old) / 64.0
n_new = int(np.ceil(t_old[-1] * FS))
t_new = np.arange(n_new) / FS
ppg32 = np.interp(t_new, t_old, ppg)
# 对齐 ACC:原 32 Hz,重对齐到同一时间轴
n_acc = acc.shape[0]
ta = np.arange(n_acc) / 32.0
acc32 = np.stack([np.interp(t_new, ta, acc[:, k]) for k in range(3)], axis=-1)
# 切窗:每窗 WIN 秒
step = FS * STEP; win = FS * WIN
X, y, act = [], [], []
n_win = (len(t_new) - win) // step + 1
for w in range(n_win):
a = w * step; b = a + win
if b > len(t_new):
break
seg = np.concatenate([ppg32[a:b][:, None], acc32[a:b]], axis=-1) # (win,4)
X.append(seg)
y.append(float(subj["label"][w])) # 2Hz label,索引=窗序
act.append(int(subj["activity"][int(a / (32/4))])) # activity 4Hz
return np.array(X), np.array(y), np.array(act)
X1, y1, a1 = load_and_window("PPG-DaLiA/data/S1.pkl")
print("S1 窗张量:", X1.shape, "HR:", y1[:3], "活动数:", a1[:3])
§6.4 PyTorch DataLoader
以下 Dataset 类实现受试者级加载、LOSO 的窗拼接与 DataLoader 实例化。
import torch
from torch.utils.data import Dataset, DataLoader
import numpy as np, pickle, glob
class PPGDaliaLOSO(Dataset):
"""LOSO: train/val/test 均在'受试者'层隔离。"""
def __init__(self, subject_ids, data_root, transform=None):
self.windows, self.labels, self.acts = [], [], []
for sid in subject_ids:
X, y, a = load_and_window(f"{data_root}/S{sid}.pkl")
self.windows.append(X); self.labels.append(y); self.acts.append(a)
self.X = np.concatenate(self.windows, axis=0).astype(np.float32)
self.y = np.concatenate(self.labels, axis=0).astype(np.float32)
# 通道级 z-score(在训练受试者上拟合并冻结,见坑点)
self.mean_ = self.X.mean(axis=(0, 1), keepdims=True)
self.std_ = self.X.std(axis=(0, 1), keepdims=True) + 1e-8
self.X = (self.X - self.mean_) / self.std_
def __len__(self): return len(self.X)
def __getitem__(self, i):
return torch.tensor(self.X[i].transpose(1, 0)), torch.tensor(self.y[i])
train_ids = list(range(1, 14)) # 示例:S1-S13 训练
val_ids = [14] # S14 验证
test_ids = [15] # S15 测试(LOSO 轮次)
ds = PPGDaliaLOSO(train_ids, "PPG-DaLiA/data")
loader = DataLoader(ds, batch_size=256, shuffle=True)
for xb, yb in loader:
print("batch:", xb.shape, yb.shape) # (256,4,256) / (256,)
break
§6.4b 完整 LOSO 训练与评测循环
以下给出一个可运行、受试者级隔离的 LOSO 训练与逐人 MAE 汇总,供对齐论文报告协议使用。模型为轻量 1D-CNN(示例),非 SOTA,仅示范评测脚手架。
import torch, torch.nn as nn, numpy as np, pickle, os
from torch.utils.data import DataLoader, TensorDataset
torch.manual_seed(0)
data_root = "PPG-DaLiA/data"
FS, WIN, STEP = 32, 8, 2
win, step = FS * WIN, FS * STEP
def load_sessions(sid_list):
Xa, ya, meta = [], [], []
for sid in sid_list:
with open(f"{data_root}/S{sid}.pkl", "rb") as f:
subj = pickle.load(f)
sig = subj["signal"]
ppg = np.asarray(sig["wrist"]["BVP"], np.float64)
acc = np.asarray(sig["wrist"]["ACC"], np.float64)
t = np.arange(int(np.ceil(len(ppg) / 64.0 * FS))) / FS
ppg32 = np.interp(t, np.arange(len(ppg)) / 64.0, ppg)
acc32 = np.stack([np.interp(t, np.arange(len(acc)) / 32.0, acc[:, k])
for k in range(3)], -1)
X = np.concatenate([ppg32[:, None], acc32], -1)
n_win = (len(t) - win) // step + 1
for w in range(n_win):
a, b = w * step, w * step + win
Xa.append(X[a:b]); ya.append(subj["label"][w])
Xa = np.asarray(Xa).astype(np.float32)
return torch.from_numpy(Xa.transpose(0, 2, 1)), torch.tensor(ya, dtype=torch.float32)
class Net(nn.Module):
def __init__(self):
super().__init__()
self.body = nn.Sequential(
nn.Conv1d(4, 16, 5, padding=2), nn.ReLU(), nn.MaxPool1d(2),
nn.Conv1d(16, 32, 5, padding=2), nn.ReLU(), nn.MaxPool1d(2),
nn.Flatten(), nn.Linear(32 * 64, 64), nn.ReLU(), nn.Linear(64, 1))
def forward(self, x): return self.body(x).squeeze(-1)
def loso_mae(test_sid):
tr_ids = [i for i in range(1, 16) if i != test_sid]
Xtr, ytr = load_sessions(tr_ids)
Xte, yte = load_sessions([test_sid])
# 训练期统计量冻结后应用到测试,避免泄漏(见坑点 2/5)
mean = Xtr.mean(dim=(0, 2), keepdim=True)
std = Xtr.std(dim=(0, 2), keepdim=True) + 1e-8
Xtr, Xte = (Xtr - mean) / std, (Xte - mean) / std
model = Net()
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
lossf = nn.L1Loss()
dl = DataLoader(TensorDataset(Xtr, ytr), batch_size=128, shuffle=True)
for epoch in range(8):
model.train()
for xb, yb in dl:
opt.zero_grad(); loss = lossf(model(xb), yb); loss.backward(); opt.step()
model.eval()
with torch.no_grad():
pred = model(Xte)
return float(torch.abs(pred - yte).mean().item())
scores = [loso_mae(s) for s in range(1, 16)]
print("LOSO 逐人 MAE:", [round(x, 2) for x in scores])
print(f"平均 MAE = {np.mean(scores):.2f} ± {np.std(scores):.2f} bpm")
§6.4c Deep PPG 风格频域(谱图)预处理
Deep PPG 论文把 PPG 与 ACC 转成时间-频谱图输入 CNN;许多后续研究则回归 4×256 时域张量。两种表示都可复现。以下给出频域表示的一个可运行配方(0.4-4 Hz 心跳频带,32 Hz 信号)。
import numpy as np
def tf_spectrogram(channel, fs=32, win_s=8, fmin=0.4, fmax=4.0):
"""返回给定通道的时频谱图(对数幅度)。channel: 1D 时域。"""
n = int(fs * win_s)
freqs = np.fft.rfftfreq(n, 1.0 / fs)
mask = (freqs >= fmin) & (freqs <= fmax)
frames = []
for start in range(0, len(channel) - n + 1, n):
seg = channel[start:start + n]
spec = np.abs(np.fft.rfft(seg * np.hanning(n))) ** 2
frames.append(spec[mask])
return np.array(frames) # (n_windows, n_freq_bins)
# 说明:Deep PPG 使用滑动 8s 窗 + FFT;心跳频带通常截取 0.4-4 Hz 对应 24-240 bpm
# 使用时把 PPG 与 3 轴 ACC 各生成一张谱图,按时间轴对齐作为多通道 CNN 输入。
频域 vs 时域取舍:时域 4×256 实现简单、内存友好、多数现代基线采用;频域对强周期伪差更敏感、接近原始 Deep PPG 设定但需更多 FFT 调参。新项目建议先走时域复现 4×256,需要追平 Deep PPG 原实验再切频域。
§6.4d 活动识别 DataLoader(多类标签)
若做 8+1 类活动识别,需要把每窗的主导活动与窗关联(窗口跨活动边界时取众数)。
def window_dominant_activity(sid, data_root="PPG-DaLiA/data", fs_a=4):
"""返回每 8s 窗的主导活动标签(activity 序列为 4 Hz)。"""
with open(f"{data_root}/S{sid}.pkl", "rb") as f:
subj = pickle.load(f)
act = np.asarray(subj["activity"]) # 4 Hz
win, step = 8 * fs_a, 2 * fs_a
n = (len(act) - win) // step + 1
dom = []
for w in range(n):
a, b = w * step, w * step + win
vals, cnt = np.unique(act[a:b], return_counts=True)
dom.append(int(vals[int(np.argmax(cnt))]))
return np.array(dom)
# 用法:对训练受试者取窗特征与主导活动做多分类;评测按 LOSO 留一受试者
提示:活动标签以 4 Hz 逐点记录,非逐窗;做 HAR 时先经"窗口主导"聚合,避免把边界窗的混合活动当作单一标签造成标签噪声。
§6.5 坑点 8 个
⚠️ 坑点 1:只公开单通道绿光 PPG——别把论文的多通道当既有(分类:数据理解/标签理解)
问题:E4 硬件本身有 2 绿 2 红 4 颗 LED 的多通道 PPG,但公开版 PPG-DaLiA 每个受试者只放出单通道(绿光)BVP。许多新手照 Q-PPG/TimePPG 的文字想读"两通道"或"红光",却发现根本取不到对应数据。
症状:KeyError、通道数不对(以为 4×256 却拿到 1+3 通道),输入形状与复现论文不一致。
解决:
- 简单方法:接受"1 通道 PPG + 3 通道 ACC = 4 通道输入(4×256)“,这正是 Q-PPG/TimePPG 采用的形式(来源:arxiv-vanity 2203.14907 明确"仅绿光通道公开”)。
- 进阶方法:如需更多波长信息做光谱分离,可改用含多通道腕 PPG 的其他集(如 SPC 2015 的 2 通道);不要在本数据集硬拼不存在的通道。
参考:https://arxiv-vanity.com/papers/2203.14907(“only the former (green) is available in the public version”)
⚠️ 坑点 2:LOSO 按受试者切——按窗随机切=时间泄漏,跨人误差虚低(分类:评估误用)
问题:8 s 窗步长 2 s,相邻窗重叠 6 s,同一受试者窗间强相关。若为"提样本量"而把全部 64,697 窗随机分 train/test,同一人心跳信息同时出现在两侧,测试 MAE 会被系统性低估,无法代表真实新用户。
症状:随机切得到的 MAE 远低于 LOSO 报告值(对比文献 ~4-7 bpm 会显得异常低),但换数据集即失效。
解决:
- 简单方法:永远在受试者 S1-S15 层做 15 折 LOSO,每轮留一受试者做测试(来源:Deep PPG 论文协议)。
- 进阶方法:报告时附逐受试者 MAE 与 std,暴露离群者(如 S5)对均值的影响,别只报一个均值。
参考:https://ubi29.informatik.uni-siegen.de/usi/pdf/ubi_sensors2019.pdf(§2.2 评测协议)
⚠️ 坑点 3:ECG 含运动伪差——金标准不是纯自动、别迷信绝对真值(分类:数据理解)
问题:论文坦承 R 峰检测后仍需人工逐例校正(去除伪峰、补漏峰),桌上足球等强干扰会让 ECG 误检 R 峰(论文 Fig.3 例 S1)。这些校正后的 R 峰索引才构成 HR 真值。
症状:若用 pkl 中公开的 ECG 重新自动做 R 峰检测,得到的 HR 与官方 label 出现偏差,且误差集中在高运动窗;用错误真值训练会使模型在楼梯/桌上足球误判。
解决:
- 简单方法:直接信任官方
label(已人工校正),勿重新检测。- 进阶方法:复核高运动窗 label 与 ECG 峰索引的一致性,必要时剔除非静止时段的低质量窗;研究 IBI/HRV 时用官方校正峰索引而非重检。
参考:https://tomesphere.com/paper/PMC6679242(R-peak correction & Fig.3)
⚠️ 坑点 4:S6 数据只有前约 90 分钟——别按"每人一样长"假设批处理(分类:工程陷阱)
问题:一次硬件故障使 S6 后半(约最后 1 小时,多为低强度活动)数据丢失,全库仅此受试者有效时长约 90 分钟而非 150 分钟。批量切窗/拼接时若假设每受试者窗数相同,会因越界而出错或静默错位。
症状:循环到 S6 时索引越界、窗口数不一致导致对齐错误、S6 相关 HR 分布偏高(缺低强度段)。
解决:
- 简单方法:逐受试者按实际信号长度动态切窗(见 §6.3
for w in range(n_win)),不写死每人数。- 进阶方法:LOSO 训练注意 S6 贡献样本少,报告时单独看 S6 误差并注明其时长差异;如需均衡可对该受试者做时间窗过采样。
参考:https://www.mdpi.com/1424-8220/19/14/3079(“data of one subject valid for first 90 min”,且指出 S6 缺失的是低强度活动)
⚠️ 坑点 5:跨论文基准不可直接比——输入、采样率、z-score 后处理各不相同(分类:评估误用)
问题:Deep PPG 用 64 Hz 谱图输入 MAE 7.65;Q-PPG 报 4.36;PULSE 报 4.44/后处理 4.03——这些并非同一输入,难以直接断言孰优。差异来源:是否降采样 32 Hz、输入是否 4×256 张量、通道 z-score 归一化、以及是否含"输出钳制/滑窗后处理"。
症状:把两篇论文的单一 MAE 数字相减当作性能差,结论被输入表示差异污染。
解决:
- 简单方法:比较时只认"同一输入协议(32 Hz 4×256 + z-score)下的 LOSO MAE",并区分"裸输出 vs 后处理"。
- 进阶方法:自建统一评测脚本,用同一切窗/归一化/后处理复跑各方法,再横向对比(TimePPG 的做法即如此)。
参考:https://arxiv-vanity.com/papers/2210.11415(输入 4×256、z-score、post-processing 定义)
⚠️ 坑点 6:个体差异极大——S5 是离群者,均值 MAE 会被拖高(分类:偏倚陷阱/标签理解)
问题:论文指出 S5 平均 HR 显著高于全体,属生理/体质离群者。深度模型普遍在其上误差高(部分方法 S5 单人多达 ~15 bpm),拉高全库平均 MAE;微调后 S5 可降至 <5 bpm(Robust…2021)。不看逐人分布会高估"平均性能即代表所有人"。
症状:均值 MAE 尚可但 S5 等离群人误差数倍于他人;换受试者子集重跑,排名剧变。
解决:
- 简单方法:报告逐受试者 MAE 表 + 标准差,别只给均值。
- 进阶方法:做个性化/联邦实验时,用受试者前 25% 数据微调以捕获个体光/肤色与体质差异(TimePPG 把 S5 误差从 ~15 降到 <5 bpm);对"冷启动跨人"任务如实说明离群个体是主要误差来源。
参考:https://www.mdpi.com/1424-8220/19/14/3079 + https://lacuna.tiptreesystems.com/paper/robust-and-energy-efficient-ppg-based-heart-rate-monitoring/
⚠️ 坑点 7:.pkl 是 Python2/3 兼容坑——读取必须用 rb 且注意 encoding(分类:工程陷阱)
问题:官方数据是 pickle 序列化(每受试者一 .pkl),非临床通用格式。直接
open(..., 'r')或跨 Python 版本打开会报TypeError: a bytes-like object is required或UnpicklingError;且 pickle 不可信时可能执行任意代码。
症状:复现他人脚本时pickle.load报 bytes/str 类型错或 invalid load key。
解决:
- 简单方法:一律
open(path, 'rb')打开;若遇旧版序列化加encoding='bytes'。- 进阶方法:只对可信来源 pickle;跨语言(MATLAB)用 DBDP 的 pkl→.mat 转换脚本或转成 numpy/npz/CSV 再分发,避免长期依赖 pickle 的 Python 版本耦合。
参考:https://ppg-beats.readthedocs.io/en/stable/datasets/ppg_dalia(pkl→mat 转换流程)
⚠️ 坑点 8:license 表述冲突——UCI 标 CC BY 4.0、原页限"非商业"(分类:数据使用合规)
问题:UCI 数据页声明 CC BY 4.0(允许商业用途、须署名),但 Uni Siegen 原始下载页同时写明"may use for scientific, non-commercial purposes"。两条口径并存,商用/重分发前若不作确认有合规风险。
症状:按 CC BY 4.0 放手商用后,被采集方原始非商业声明质疑;或相反误以为完全禁商用而错过合理授权。
解决:
- 简单方法:以你实际下载的分发渠道为准——UCI 下载则按 UCI 页 CC BY 4.0 及署名要求执行,同时留意采集方页面的非商业措辞。
- 进阶方法:商用/训练商用模型前,书面联系采集方(Bosch/锡根大学作者)确认最终授权范围;学术用途则双向均合规,仅需正确引用(论文+数据集 DOI)。
参考:https://archive.ics.uci.edu/dataset/495/ppg+dalia(CC BY 4.0) vs https://ubi29.informatik.uni-siegen.de/usi/data_ppgdalia.html(non-commercial disclaimer)
§6.6 数据增强
安全 ✅:训练期对 8 s 窗做小幅通道级时间抖动/加性高斯噪声、按受试者切开的窗内短时平移、频谱掩膜(模拟局部伪差),均可提升鲁棒性而不引入跨人泄漏;用合成 PPG 数据扩充(Improved PPG-based HR 方向)也已被证实有效(来源:Semantic Scholar 相关论文)。
危险 ❌:跨受试者拼接窗做"数据混合"做增强——会把一个人的运动伪差模式带进另一人,破坏 LOSO 的受试者独立性,使跨人评测失真;在增强后再做随机 train/test 切分同样触发坑点 2 的时间泄漏。任何增强都必须在受试者层已划分完成后、仅作用于训练受试者的窗。
安全增强示例(仅作用于训练受试者、在划分之后):
def safe_augment(X): # X: (batch, 4, 256) 训练受试者张量
import numpy as np
out = X.copy().astype(np.float32)
# 1) 幅度缩放:模拟佩戴松紧/皮肤差异(不动时间结构)
scale = 1.0 + np.random.uniform(-0.15, 0.15, size=(X.shape[0], 4, 1))
out *= scale
# 2) 通道级加性高斯噪声:模拟传感器电噪声
noise = np.random.normal(0, 0.01, size=out.shape).astype(np.float32)
out += noise
# 3) 频谱掩膜(模拟局部伪差掩盖一段频带)——提示,具体实现按你的频域管线
return out
增强的边界:任何增强都不应"跨受试者搬运信号片段",也不应在增强后与测试受试者数据混洗;否则 LOSO 的"没见过的陌生人"测试语义被破坏。
§6.7 模型推荐表
| 模型/家族 | 输入 | 参数量 | MAE (bpm) | 定位 |
|---|---|---|---|---|
| SpaMaPlus(经典频谱) | PPG+ACC 频谱 | 轻 | 11.06 | 传统基线(论文) |
| Deep PPG CNN ensemble | 谱图 | 8.5M×7 | 7.65 | 原始深度基线 |
| TimePPG-Big(TCN) | 4×256 | 232k | 4.88 | 高精度可部署 |
| TimePPG-Small(TCN) | 4×256 | 5.09k | 5.63 | 超轻量 |
| Q-PPG(TCN+量化) | 4×256 | — | 4.36(后处理) | MCU 端 int8 |
| PULSE(注意力) | 4×256 | — | 4.44 / 后处理 4.03 | 注意力融合 |
| MH Conv-LSTM | 时域 | ~680k | 6.28 | Conv-LSTM |
选型建议速记:起步基线用 SpaMaPlus(纯信号处理、可解释、不用训练)验证数据与真值;要快速出 CNN 结果用单模型(非 ensemble)的 4×256 时域 CNN;追 SOTA 用 TimePPG-Big/PULSE 类(注意是否为后处理口径);要 MCU 落地用 TimePPG-Small/Q-PPG 的 int8 版。任何模型都要配 §6.4b 的 LOSO 评测脚手架,否则数字无从与文献对齐。
§6.8 硬件需求表
| 阶段 | CPU 内存 | GPU 建议 | 耗时量级(参考) |
|---|---|---|---|
| 预处理/切窗 | 8-16 GB | 不需要 | 分钟级 |
| 浅层 CNN 冒烟 | 8-16 GB | 1× 轻量 GPU/Colab | 约 1 小时 |
| Deep PPG 大 CNN(8.5M×7 ensemble) | 16+ GB | 1× 高端 GPU | 论文训练 15,000 迭代(小时-天级) |
| TCN/NAS 全探索(Q-PPG/TimePPG) | 16+ GB | 1-4× GPU | 天级(NAS 迭代多) |
§6.9 评估指标代码
import numpy as np
def mae_bpm(y_true, y_pred):
return float(np.mean(np.abs(np.asarray(y_true) - np.asarray(y_pred))))
def pearson(y_true, y_pred):
yt, yp = np.asarray(y_true), np.asarray(y_pred)
return float(np.corrcoef(yt, yp)[0, 1])
# 用法:LOSO 每轮对留出受试者算 MAE,最后平均 15 个 MAE 与 std
scores = [] # 每轮一个受试者 MAE
for s_true, s_pred in loso_folds_predictions: # 示意
scores.append(mae_bpm(s_true, s_pred))
print("LOSO MAE =", round(np.mean(scores), 2), "±", round(np.std(scores), 2))
指标解读:MAE (bpm) 是主流主指标,通常附 Pearson 相关与按活动分层误差。临床参考量级——静息静态活动约 4-5 bpm 已接近可部署;楼梯/桌上足球等强干扰活动在 10-17 bpm,若应用容忍度不允许该误差,应明确标注"仅适用低-中强度日常场景"。逐受试者 std 高(S5 拉大)说明模型对个体敏感,需看箱线而非仅看均值。
§6.10 MLOps 笔记
- 版本与溯源:受试者级元数据(年龄/性别/SKT/FL)可用于偏倚审计;训练前把受试者划分与归一化统计量(mean/std)冻结并随模型保存,推理端复用同一统计量。
- 数据漂移监测:真值 HR 仅来自 ECG,部署侧拿不到;可监控输入窗的频谱能量与 ACC 幅度分布,异常高运动段单独降级/标记(ActPPG 的 movement-detector 思路)。
- 个性化热启动:为每个新用户保留"冷启动全局模型 + 前段 25% 数据微调"两态,便于迭代收集用户数据后切换(TimePPG fine-tune 验证有效)。
- pickle 安全:入库前统一转成 npz/parquet 等自描述格式并校验哈希,避免长期依赖 pickle 与 Python 版本耦合。
- 逐窗缓存:全库切窗 + 归一化后可把 (X, y, activity, subject) 存为内存映射数组(.npy/.npz),LOSO 每折只需按 subject 索引子集,避免重复读 .pkl,训练提速明显。
- 可复现三件套:固定随机种子 + 冻结划分(subject 名单)+ 记录归一化统计量,缺一不可;尤其注意 DataLoader shuffle 的随机种子要与 LOSO 轮次解耦。
- 指标口径版本化:把"裸输出 MAE"“后处理 MAE”"按活动分层 MAE"作为三个独立版本记录,避免后续对比时口径混用。
- 异常受试者看板:为每个测试受试者生成 MAE+误差直方图,S5/S6 的异常能立刻在 CI/实验看板上暴露,而不是被均值掩盖。
§7 质量评估与局限性
§7.1 已知偏倚表
| 偏倚类型 | 描述 | 严重程度 | 缓解 |
|---|---|---|---|
| 样本量偏倚 | 仅 15 名健康受试者,LOSO 高方差、受离群者支配 | 高 | 报告逐人 MAE;跨数据集验证(WESAD/IEEE) |
| 人群/人口学偏倚 | 德国研究园区员工为主,肤色/体能多样性窄 | 高 | 承认不可外推到患者/全球人群;按 SKT 分层审计 |
| 活动偏倚 | 无跑步等高强度全身运动;以中低强度日常为主 | 中 | 明确"日常活动"定位,勿当作极限运动数据 |
| 生理离群者 | S5 均值 HR 显著偏高;S6 缺后半数据致均值偏移 | 中 | LOSO 逐个分析,勿给极端个体打标签剔除 |
| 真值误差 | 人工 R 峰校正存在主观性,高运动窗仍可能残留误差 | 中 | 复核校正峰;只用高信噪比窗做严格评测 |
| 设备/单点采集 | 单一 E4/RespiBAN 品牌与固定戴位 | 中 | 跨设备时重新标定 |
§7.2 标注质量
活动标签为协议客观、无主观模糊;HR 真值为半自动(自动 R 峰 + 人工校正),论文提供了校正必要性证据(S1 桌上足球误 R 峰例)。受试者元数据(身高/体重/肤/体能)完整。未公开标注者间一致性统计,使用者应把 HR 真值视为"经人工把关的高质量参考",而非零误差的绝对标准。
使用前建议做一次轻量质量抽检(可部分自动化):
| 抽检项 | 方法 | 判定 |
|---|---|---|
| R 峰合理性 | 对每个 8 s 窗,用官方 label 反推窗内心搏数 ≈ HR×8/60 | 异常窗(偏离 >20%)需人工看 ECG |
| 相邻窗平滑性 | HR 真值逐窗应平滑(相邻 2 s 步长变化通常 <10 bpm) | 突跳窗可疑 |
| 活动边界一致性 | activity 切换点附近 ACC 幅度应变化 | 不一致提示同步误差 |
| 离群窗复核 | S5 高 HR 段、Stairs/Table soccer 的高 MAE 窗逐一核 R 峰 | 确认是否为伪差真例 |
若你的研究对 HRV/IBI 敏感,务必使用官方校正过的 R 峰索引而非重新检测,并在论文注明"真值依赖人工校正、含主观成分",把结论限定在合理误差范围内。
§7.3 泛化性表
| 场景 | 失效风险 | 证据 |
|---|---|---|
| 同人群新受试者(LOSO) | 中——离群者(S5)误差大 | 各论文 LOSO MAE 跨人 std 大 |
| 高强度运动(跑步/冲刺) | 高——数据未含,伪差更强 | 协议无跑步 |
| 非研究园区人群/肤色 | 高——训练分布单一 | 人口偏倚 |
| 患者/心律失常 | 高——健康数据、无病理 | 非临床定位 |
| 同任务跨数据集(WESAD/IEEE) | 中——可用但需重采样 | Deep PPG 四库评测 |
§7.4 伦理
研究经园区工人委员会与数据安全官批准;受试者健康志愿者、无临床影像/姓名公开、以 S1-S15 编号脱敏。数据集不含患者,因而无 HIPAA 类临床脱敏需求,但使用者仍应尊重原始非商业/署名声明并正确引用。
§7.5 公平性
人群代表性差(健康、德国、园区员工、肤色记录但范围窄)是最大公平性短板:据此训练的模型对深肤色、老年、患病人群的 PPG 心率误差可能更高。论文/社区已有肤色敏感性讨论(如 ppg-beats 肤色子集工具),但 PPG-DaLiA 本身无法支撑此类公平性结论,跨人群结论需在更具多样性数据上验证。
§7.6 数据漂移
数据采集于 2018-2019,单批静态。传感器(E4/RespiBAN)随时间漂移与商业固件变化会使训练-部署之间存在域差;可穿戴光学技术在变(新 LED/波长),本数据作为"绿光单通道"代表可能逐渐跟不上多波长新硬件。建议在真实部署设备上持续采集影子数据校准。
§7.7 DAIMS 24 项表
| # | 检查项 | 状态 | 说明 |
|---|---|---|---|
| 1 | 宽格式 | ✅ | 每受试者 pkl 为结构化 dict,便于对齐 |
| 2 | 唯一标识 | ✅ | 受试者 S1-S15 唯一;每窗由"受试者+时间"唯一定位 |
| 3 | 特殊字符 | ⚠️ | 活动名表与键为英文,无特殊字符问题;但跨工具键名口径不一 |
| 4 | 重复行 | ✅ | 无逐窗重复记录(时间为连续序列) |
| 5 | 缺失编码 | ⚠️ | 无 NaN;但 S6 整段缺失无显式缺失标记 |
| 6 | 标签标识 | ✅ | 活动标签有 activity_types 解码表;HR 为连续标签 |
| 7 | 罕见类分组 | ✅ | HR 高区间(160-200)与强干扰活动窗稀疏,评测按活动分层 |
| 8 | 偏倚评估 | ✅ | 论文显式讨论 S5 离群、S6 截断、肤色/体能元数据 |
| 9 | 数据字典 | ✅ | readme.pdf + 论文含字段/量程/采样率 |
| 10 | 信息性缺失解释 | ✅ | 论文解释 S6 缺失为硬件故障 |
| 11 | 设备记录 | ✅ | 详细记录 E4/RespiBAN 量程、滤波、位数 |
| 12 | 共线性 | ⚠️ | 相邻 8 s 窗重叠 6 s,强共线,需按受试者切 |
| 13 | 编码映射 | ✅ | 活动标签↔名称映射提供 |
| 14 | 时间戳处理 | ✅ | 同步协议(双击手势)说明漂移校正 |
| 15 | 划分建议 | ⚠️ | 无官方划分文件,仅论文定义 LOSO 范式 |
| 16 | 泄漏讨论 | ✅ | 受试者级切分共识;本文坑点 2 说明 |
| 17 | 标签分布 | ✅ | 论文 Table 2/3/11 给 HR 与活动分布 |
| 18 | 测量偏倚 | ✅ | 运动伪差、ECG 伪峰人工校正均披露 |
| 19 | 外部验证建议 | ✅ | 作者用 WESAD/IEEE 交叉评估 |
| 20 | 版本记录 | ✅ | 单版本 UCI v1.0,DOI 稳定 |
| 21 | 预处理脚本 | ❌ | 官方无预处理脚本;仅社区(DBDP/ppg-beats)提供 |
| 22 | 合规要求 | ⚠️ | license 双口径(CC BY 4.0 vs 非商业声明)需确认 |
| 23 | 多模态对齐 | ✅ | 腕/胸同步信号齐全并给出同步方法 |
| 24 | 去标识化 | ✅ | 健康志愿者以 S1-S15 编号脱敏 |
DAIMS 评分:17.5 / 24
评分解读:良好偏可复现——作为研究驱动的健康受试者数据集,其在唯一标识、标签解码、偏倚披露、设备记录、多模态对齐、去标识化上做得扎实,评测协议(LOSO)社区高度统一,这是它成为该领域事实基准的根本。扣分集中于"AI 工程化配套"而非数据质量本身:官方无预处理/划分脚本(需社区自造)、格式为 Python pickle(非临床通用)、单版本无官方后处理、license 双口径、相邻窗强重叠需使用者自行规避时间泄漏——这些都是把"研究数据"变成"即插即用训练集"时要补的功课。
对你意味着什么:PPG-DaLiA 是"数据干净、评测统一、但工程配套要自己补"的代表。上手第一件事不是写模型,而是:先用受试者级 LOSO 建好切窗/归一化/后处理的统一评测脚本(否则论文 MAE 无法复现、跨文比较失真),再处理 S6 的截断与 S5 的离群(逐人报告),并自建 pkl→numpy/parquet 的稳健加载层。多数扣分项——预处理脚本、划分文件、格式转换——是作者留给社区的作业,恰好是你在自己 pipeline 里要投资的部分;而数据自身的唯一标识、标签解码与偏倚披露已经足够好,无需二次清洗。
§7.8 外部验证矩阵
| 外部数据集/场景 | 来源机构 | 评估任务 | 性能指标 | 相对内部变化 | 关键发现 |
|---|---|---|---|---|---|
| WESAD | DFKI/锡根大学 | HR 估计(CNN) | MAE 7.47 bpm | 与内部 7.65 相当 | 同一 Deep PPG 模型跨同生态数据集稳定(来源:Deep PPG 论文) |
| IEEE SP Cup 2015 | IEEE CinC | HR 估计(CNN) | 更优 MAE | 数据集更小/受控 | 大库训练可迁移到小受控集 |
| 本库 S5 个性化 | 社区(TimePPG) | 微调后 HR | ~15→<5 bpm | 个体差异主导 | 冷启动跨人难,微调有效 |
§8 基准性能与生态
§8.1 排行榜
以下为 LOSO、8 s 窗、ECG 金标准下报告的代表性 MAE。数值不可直接比较的原因:不同论文的输入表示(谱图 vs 4×256 时域张量)、是否 z-score、是否含"滑窗输出钳制"后处理均不同;同模型含/不含后处理结果亦不同。横向比较请回归统一协议复测。
| 排名(按裸/声明) | 模型 | 性能 MAE | 年份 | 关键技术 | 完整引用 | 代码 |
|---|---|---|---|---|---|---|
| 1 | PULSE(后处理) | 4.03 bpm | 2022 | 多头交叉注意力 PPG+ACC 融合 | Kumar A. et al., 2022, arXiv 2210.11415 | 论文附 |
| 1b | Q-PPG(后处理) | 4.36 bpm | 2022 | TCN+NAS+量化 | Burrello A. et al., IEEE TETC 2022 | 作者 |
| 2 | PULSE | 4.44 bpm | 2022 | 同上(裸输出) | 同上 | 论文附 |
| 3 | TimePPG-Big | 4.88 bpm | 2021 | NAS 设计 TCN(~232k) | Risso M. et al., ISQED 2021 | 作者 |
| 4 | TimePPG-Small | 5.63 bpm | 2021 | 轻量 TCN(5k) | 同上 | 作者 |
| 5 | MH Conv-LSTM | 6.28 bpm | 2021 | Conv-LSTM 多头 | Jaskó 等, Sensors 21(15):5212 | 论文 |
| 6 | Deep PPG CNN ensemble | 7.65 bpm | 2019 | 谱图 CNN+7 次 ensemble | Reiss A. et al., Sensors 19(14):3079 | Uni Siegen |
| 7 | SpaMaPlus(经典) | 11.06 bpm | 2019 | 频谱峰追踪 | Reiss A. et al., 同上 | — |
§8.1b 按活动的误差画像(Deep PPG 论文 Table 11)
同一模型在不同活动上的 MAE 差异巨大,这比总 MAE 更能揭示难点分布。下表给出 Deep PPG 的 CNN ensemble 与经典 SpaMaPlus 在各活动上的 MAE(bpm,LOSO)。
| 活动 | CNN ensemble MAE | SpaMaPlus MAE | 画像 |
|---|---|---|---|
| Working(办公) | 3.84 | 4.91 | 最易——低干扰 |
| Sitting(坐) | 4.93 | 4.27 | 静态低干扰 |
| Driving(驾车) | 4.96 | 6.24 | 坐姿低干扰 |
| Lunch(午餐) | 5.22 | 7.33 | 静态为主 |
| Transition(过渡期) | 8.77 | 14.34 | 中度、含走动 |
| Walking(行走) | 9.21 | 18.16 | 节奏性伪差 |
| Table soccer(桌上足球) | 12.16 | 21.48 | 突发强干扰 |
| Stairs(上下楼) | 16.98 | 25.42 | 最难——剧烈非平稳伪差 |
关键读数:静态活动(办公/坐/驾)模型几乎已达约 4-5 bpm 的可部署水平;误差全部集中在高动态活动(楼梯、桌上足球、行走),且深度模型相比经典方法在高干扰活动的降幅最大(楼梯从 25.42 降到 16.98、桌上足球 21.48 降到 12.16)。因此判断一个 PPG 测心算法的鲁棒性,必须看其在"楼梯/桌上足球"这类强干扰活动的误差,而不只看总体均值。
§8.2 SOTA 总结与选型建议
当前该基准的最优结果集中在"受试者级隔离 + 深度时序/注意力模型 + 后处理输出钳制",已从原始 7.65 推进到约 4 bpm。选型:要精度→PULSE/TimePPG-Big 类注意力/TCN;要边缘部署→TimePPG-Small/Q-PPG 的 int8 量化模型(可在 STM32 MCU 实时);要做方法学对比→务必复跑同一输入协议(32 Hz 4×256 + z-score),再谈孰优。
从 §8.1b 可见,剩余误差集中于强干扰活动的"非平稳运动伪差"与个体差异(S5 等离群者)。因此 SOTA 的进一步提升主要不是来自把静态活动误差压到更低(已接近饱和),而是:(1) 对高动态活动做运动感知的伪差建模(TimePPG/ActPPG 的 movement-detector 思路);(2) 通过个性化/联邦微调捕获个体差异(S5 可由约 15 降到 <5 bpm)。规划研究时,把主战场放在"楼梯+桌上足球"与"离群个体",而非追逐 0.1 bpm 的静态增益。
§8.3 评测协议
官方范式:LOSO(15 折,留一受试者);输入 8 s 窗(2 s 步长);指标 MAE (bpm) + 逐受试者 std;常附 Pearson 相关与按活动分层误差。后处理约定:预测值相对最近 10 次均值超过 ±10% 即钳制(PULSE 用)。报告应注明"裸输出 vs 后处理"。
复测要点:(1) 训练/验证/测试严格受试者隔离;(2) 归一化统计量只从训练受试者估计;(3) 完整报告 15 个测试受试者的逐人 MAE(可画箱线暴露离群者);(4) 附一张按活动分层的误差表(§8.1b 格式)。满足这四点,你的结果才与文献"协议可比"。
§8.4 相关数据集表
| 数据集 | 任务 | 与 PPG-DaLiA 关系 | 主要差异 |
|---|---|---|---|
| WESAD | 压力检测 | 同团队/设备 | 12 小时、情绪协议、动作少 |
| IEEE SP Cup 2015 | HR 估计 | 同任务经典小集 | 2 通道 PPG 125 Hz、受控 |
| Wrist PPG During Exercise | HR 估计 | 竞争集 | 含陀螺仪、3 类运动、8 人 |
| SPC 2015 (Zhang) | HR 估计 | 同任务 | 受控走跑、TROIKA |
§8.5 关键论文 Top5
- Reiss, Indlekofer, Schmidt, Van Laerhoven, Deep PPG: Large-Scale Heart Rate Estimation with CNNs, Sensors, 2019, 19(14):3079. DOI: 10.3390/s19143079 — 提出 PPG-DaLiA 数据集与 Deep PPG CNN,确立 LOSO 评测范式。官方原版。
- Risso et al., Robust and Energy-Efficient PPG-Based Heart-Rate Monitoring on an MCU, IEEE ISQED 2021. — 引入 TimePPG(TCN+NAS),把 MAE 降到 4.88,可部署 MCU。
- Burrello et al., Q-PPG: Energy-Efficient PPG-based Heart Rate Monitoring on Wearable Devices, IEEE TETC, 2022. DOI: 10.1109/TETC.2021.3091651. — NAS+量化到 int8,报 4.36 bpm,端侧落地。
- Jaskó, M. et al., Multi-Headed Conv-LSTM Network for Heart Rate Estimation, Sensors, 2021, 21(15):5212. — Conv-LSTM 改进单模型(不靠 ensemble)到 6.28 bpm。
- Kasnesis et al. (2022), Cross-Dataset PPG 特征/域泛化研究(cited in Emergentmind DALIA) — 探讨 PPG-DaLiA 上任务无关视图与跨数据集泛化(皮肤色/动作条件)。
§8.6 社区活跃度
截至 2026-09:论文 Google Scholar 引用 502、Semantic Scholar 316,属穿戴 PPG 领域被引最高的基准之一。生态活跃于:DBDP(数字生物标志物管线)、ppg-beats(脉搏检测工具箱,内置 PPG-DaLiA 载入/肤色子集)、Edge Impulse 工程示例、以及每年多篇以"PPG-DaLiA LOSO"为基准的穿戴 HR 论文。无单一官方 leaderboard,评测靠"沿用统一协议"维持可比性。
§8.7 生态快照表
| 资源/类型 | 类型 | 链接 | Star/活跃(截至 2026-09) | 推荐理由 |
|---|---|---|---|---|
| UCI 数据页 | 官方托管 | archive.ics.uci.edu/dataset/495 | 26,079 views | 权威下载+DOI |
| Uni Siegen 下载页 | 原始来源 | ubi29…/data_ppgdalia.html | — | 论文随附原链接 |
| DBDP | 预处理/转换 | github.com/DigitalBiomarkerDiscoveryPipeline | 活跃 | pkl→mat 与 HRV/预处理模块 |
| ppg-beats | 工具箱 | github.com/peterhcharlton/ppg-beats | 活跃 | 内置 PPG-DaLiA 载入、肤色子集、工具箱 |
| Sensors 论文 | 全文 | PMC6679242 | — | 官方方法/Table 2/3/11 |
§9 相关资源与引用
§9.1 官方资源
| 资源 | 类型 | 链接 / DOI | 用途 |
|---|---|---|---|
| 官方数据页(UCI) | 托管仓库 | https://archive.ics.uci.edu/dataset/495/ppg+dalia | 权威下载、DOI 引用、readme |
| 原始下载页(Uni Siegen) | 论文随附仓库 | https://ubi29.informatik.uni-siegen.de/usi/data_ppgdalia.html | 与论文同源、逐窗复现 |
| 数据集 DOI | 持久标识 | 10.24432/C53890 | 引用数据本体 |
| 原始论文全文(PMC) | 开放全文 | https://pmc.ncbi.nlm.nih.gov/articles/PMC6679242/ | 协议/Table 2/3/11 权威来源 |
| 论文 PDF(Uni Siegen) | https://ubi29.informatik.uni-siegen.de/usi/pdf/ubi_sensors2019.pdf | 全文含图/表 | |
| DBDP 转换脚本 | 代码 | github.com/DigitalBiomarkerDiscoveryPipeline | pkl→.mat 与预处理模块 |
| ppg-beats | 工具箱 | github.com/peterhcharlton/ppg-beats | 载入、肤色子集、工具箱 |
§9.1b 社区与衍生工具
- DBDP(Digital Biomarker Discovery Pipeline):提供 convert_subject_pickle_files_to_mat.py 与 HRV/预处理模块,是多数 MATLAB 工作流的入口。
- ppg-beats(peterhcharlton):内置 PPG-DaLiA 载入器、脉搏检测与肤色子集,适合做脉搏/HRV 基础研究。
- Edge Impulse 工程示例:把 PPG-DaLiA 用于 HR/HRV 回归的端侧 demo(含多标签回归块配置)。
- TimePPG / Q-PPG:作者发布的 TCN/NAS 代码与 int8 量化部署,适合复现 4-5 bpm 级结果。
- Uni Siegen / UCI 社区:以"沿用统一 LOSO 协议"方式维持跨论文可比性,无单一 leaderboard,对比时注意 §8.3 协议要点。
§9.2 BibTeX 完整引用块
@misc{reiss2019ppgdalia,
title = {{PPG-DaLiA} Dataset},
author = {Reiss, Attila and Indlekofer, Ina and Schmidt, Philip
and Van Laerhoven, Kristof},
year = {2019},
howpublished = {UCI Machine Learning Repository},
url = {https://archive.ics.uci.edu/dataset/495/ppg+dalia},
doi = {10.24432/C53890}
}
@article{reiss2019deep,
title = {Deep {PPG}: Large-Scale Heart Rate Estimation with
Convolutional Neural Networks},
author = {Reiss, Attila and Indlekofer, Ina and Schmidt, Philip
and Van Laerhoven, Kristof},
journal = {Sensors},
volume = {19},
number = {14},
pages = {3079},
year = {2019},
publisher = {MDPI},
doi = {10.3390/s19143079}
}
§9.3 引用指南
使用数据请同时引用数据集 DOI(10.24432/C53890,指向 UCI 数据)与原始论文(Reiss et al., Sensors 2019, DOI 10.3390/s19143079);若用了 DBDP/ppg-beats 工具模块,按其要求追加引用。
| 你在做什么 | 应引用的对象 | BibTeX 键 |
|---|---|---|
| 仅下载并描述数据集 | 数据集 @misc(reiss2019ppgdalia)+ 论文 @article(reiss2019deep) | 二者皆引 |
| 复现 Deep PPG 方法与 LOSO 协议 | 论文 reiss2019deep | 主引论文 |
| 用 DBDP 模块预处理 | 论文 + DBDP 引用(Bent et al., JCTS 2020) | 追加 DBDP |
| 用 ppg-beats 工具 | 论文 + ppg-beats 仓库引用 | 追加仓库 |
引用示例(正文英文句):
We evaluate on the PPG-DaLiA dataset (Reiss et al., 2019, DOI 10.24432/C53890; Reiss et al., Sensors 2019, DOI 10.3390/s19143079) under its leave-one-subject-out protocol.
提示:由于数据采集方页面附带"科学非商业"措辞而 UCI 页面标注 CC BY 4.0,论文若含商业意图,除正确引用外还应核对 §坑点 8 的授权说明。
§10 AI 使用声明卡
§10.1 AI 模型列表
本文由千方病案医数集写作 Agent(fast-model)在规范宪法 v1.0 约束下起草与排版,并经人工编辑复核。
§10.2 AI 参与范围
AI 负责:(1) 从 UCI 数据页、Uni Siegen 页、Sensors 论文全文、社区文档(DBDP/ppg-beats)与多篇复现论文中整理结构化事实;(2) 生成 §6 的 Python 载入/预处理/DataLoader/评测代码;(3) 系统化组织 §6.5 的 8 个坑点与 §7.1 偏倚表;(4) 执行 G1/G2/G3 排版规范与中英混排检查;(5) 构建 §C 统一 JSON-LD @graph。
§10.3 输入来源列表
- UCI PPG-DaLiA 数据页 — archive.ics.uci.edu/dataset/495/ppg+dalia
- Uni Siegen 原始下载页 — ubi29.informatik.uni-siegen.de/usi/data_ppgdalia.html
- Deep PPG 论文 PMC 全文 — pmc.ncbi.nlm.nih.gov/articles/PMC6679242/
- Deep PPG 论文 Sensors PDF — ubi29.informatik.uni-siegen.de/usi/pdf/ubi_sensors2019.pdf
- Deep PPG 论文 MDPI 页(resolver) — mdpi.com/resolver?pii=s19143079
- Deep PPG 论文 ResearchGate 页(含 Table 11) — researchgate.net/publication/334439277
- Q-PPG 论文(arXiv vanity) — arxiv-vanity.com/papers/2203.14907
- TimePPG/Embedding TCN 论文 — arxiv-vanity.com/papers/2203.04396
- PULSE 论文(MHCA 融合) — arxiv-vanity.com/papers/2210.11415
- Robust&Energy-Efficient (ISQED 2021) 综述页 — lacuna.tiptreesystems.com
- ppg-beats 数据集文档 — ppg-beats.readthedocs.io / github peterhcharlton/ppg-beats
- DBDP 仓库 README — github.com/DigitalBiomarkerDiscoveryPipeline/Digital_Health_Data_Repository
- EmergentMind DALIA 主题综述 — emergentmind.com/topics/dalia
- Taylor & Francis HAR 论文(8F7M、SKT 元数据) — tandfonline.com/doi/abs/10.1080/24751839.2021.1987706
- Google Scholar 引用统计 — scholar.google.com.py(引用 502)
§10.4 人工校验表
| 内容模块 | 审核者 | 审核方式 | 审核状态 |
|---|---|---|---|
| frontmatter/schema_org | 千方病案医学编辑部 | Schema v3.9 字段逐项校验 | ✅ 已通过 |
| INFOBOX/§0 免责 | 千方病案医学编辑部 | 交叉审核 | ✅ 已通过 |
| §2 医学背景与映射 | 千方病案医学编辑部 | 文献交叉审核 | ✅ 已通过 |
| §4 数据字典/§5 划分 | 千方病案医学编辑部 | 数据工程审核 | ✅ 已通过 |
| §6 坑点与代码 | 千方病案医学编辑部 | 代码复核 | ✅ 已通过 |
| §7 质量评估与 DAIMS | 千方病案医学编辑部 | 交叉审核 | ✅ 已通过 |
| §8 基准与生态 | 千方病案医学编辑部 | 文献/排行核对 | ✅ 已通过 |
| §C JSON-LD @graph | 千方病案医学编辑部 | Schema v3.9 字段逐项校验 | ✅ 已通过 |
§10.5 AI 生成章节标注
全部章节(§0-§10 与 §C)均由 AI 依据规范宪法与检索事实起草;关键硬数字(受试者、采样率、窗数、MAE、DOI、引用数)均回溯至 §10.3 所列来源并经人工核对。
§10.6 最后人工审核日期
2026-09-05
页面状态:published(全部内容已完成审核并发布)
