第一次用 LSTM 做睡眠预测:从看懂数据开始
最近开始认真学 LSTM
最近除了继续写一些项目代码之外,我把不少时间放到了 LSTM 上。
原因也很直接。
现在正在做的智能睡眠项目,重点逐渐从“做一张温控床垫”转到了 睡眠数据分析和算法控制。
硬件当然仍然重要,但真正决定系统是不是“智能”的,其实不是床垫能不能加热或者降温。
而是系统能不能知道:
用户现在睡得怎么样?
以及:
接下来可能进入什么睡眠状态?
如果连睡眠状态都无法判断,后面的智能温控就没有什么依据。
于是我开始接触 LSTM。
第一次看到真实睡眠数据
真正开始做以后,我发现第一件事根本不是搭模型。
而是:
先把数据看懂。
以前学习机器学习的时候,经常使用已经整理好的数据集。
一行就是一个样本。
每一列是什么也写得清清楚楚。
但真实的睡眠数据完全不是这样。
我现在接触的是 PSG,也就是多导睡眠监测数据。
其中可能同时存在多个生理信号通道,例如:
- 脑电信号
- 心电信号
- 呼吸信号
- 血氧信号
- 其他生理信号
每一个通道又对应不同的采样数据。
一开始打开数据的时候,最大的感觉就是:
多。
不是几十行,也不是几千行。
因为生理信号是连续采样的。
如果采样频率是 100 Hz,那么一秒钟就会记录 100 个点。
一分钟就是:
100 × 60 = 6000一个小时就是:
100 × 60 × 60 = 360000如果记录一整晚,数据量很快就会上升到非常大的规模。
这也是我第一次比较直观地感受到什么叫“时间序列数据”。
在训练模型之前,要先回答很多问题
拿到数据以后,并不能直接扔进 LSTM。
首先要搞清楚:
数据里一共有多少个通道?每个通道分别代表什么?采样频率是多少?总记录时间有多长?有没有缺失数据?睡眠阶段标签在哪里?标签和信号时间怎么对应?这些问题如果没有弄清楚,后面模型训练出来的结果其实没有太大意义。
所以第一阶段我做的事情更像是在“认识数据”。
例如先读取文件基本信息:
print(raw.info)查看通道:
print(raw.ch_names)确认采样频率:
print(raw.info["sfreq"])然后再进一步确定数据持续时间。
这些代码看起来都很简单。
但真正意义并不是“打印几行信息”。
而是在确认:
我手里的数据到底是什么。
为什么睡眠状态适合使用 LSTM
睡眠本身并不是一个完全独立的分类问题。
假设某一个时刻人在浅睡眠。
下一个时刻的状态,并不是随机从:
清醒浅睡深睡REM里面随便选择一个。
睡眠阶段之间存在比较明显的连续变化。
也就是说:
当前状态和之前发生了什么是有关联的。
这正是时间序列问题的特点。
普通的全连接神经网络通常只关心当前输入。
而 LSTM 可以在处理序列的时候保留一部分之前的信息。
简单理解,可以把它想成:
第1段睡眠数据 ↓记住一部分信息 ↓第2段睡眠数据 ↓继续更新记忆 ↓第3段睡眠数据 ↓预测睡眠状态当然,这只是非常简单的理解。
真正训练的时候还要考虑窗口划分、特征维度、隐藏层、批次大小等很多参数。
第一阶段,我不准备追求很高的准确率
刚开始接触模型的时候很容易特别关注一个数字:
Accuracy好像准确率越高,模型就越厉害。
但对于我现在这个阶段来说,我反而觉得:
先把整个流程跑通更重要。
我的第一阶段目标大致是:
读取 PSG 数据 ↓选择需要的信号 ↓进行预处理 ↓划分时间窗口 ↓对应睡眠阶段标签 ↓构建 Dataset ↓送入 LSTM ↓完成训练 ↓输出预测结果哪怕第一版准确率很一般,只要完整流程跑通,就意味着之后有很多地方可以继续调整。
例如:
窗口到底应该取多长?
输入原始信号还是提取特征?
LSTM 用一层还是多层?
hidden size 应该是多少?
不同信号组合效果有没有差异?
这些都可以在第一版模型之后慢慢实验。
数据处理可能比模型本身更麻烦
这是最近最大的一个感受。
以前看很多深度学习教程的时候,注意力几乎都放在模型上。
比如:
model = LSTM(...)然后:
loss.backward()optimizer.step()看起来最核心的事情就是训练神经网络。
但真正处理真实数据以后会发现:
模型代码反而可能是最短的一部分。
真正花时间的是:
读取清洗对齐切片归一化标签处理数据检查如果这些步骤有问题,后面再复杂的网络也没什么意义。
所以现在我越来越觉得:
机器学习项目首先是一个数据问题,其次才是模型问题。
后面还想做什么
目前 LSTM 还处在学习和第一版实验阶段。
接下来准备继续尝试:
第一步:完成数据预处理
把原始 PSG 数据整理成适合神经网络使用的格式。
第二步:完成一个基础 LSTM
不追求特别复杂,先完成睡眠阶段预测。
第三步:评价模型效果
除了 Accuracy,还需要关注不同睡眠阶段的识别情况。
第四步:继续优化
尝试不同时间窗口、特征组合以及网络结构。
再往后,才是整个项目真正比较有意思的部分:
把睡眠预测结果和温控策略结合起来。
写在最后
现在回头看,这个项目让我重新理解了“学习一个算法”是什么意思。
以前学习 LSTM,可能是:
看原理、抄代码、跑一个示例。
现在学习 LSTM,则变成了:
我手里真的有一份睡眠数据,我需要让这个模型解决一个实际问题。
这种感觉完全不一样。
现在还只是刚开始。
第一阶段甚至连模型效果都还谈不上。
但至少已经从“LSTM 是什么”,慢慢走到了:
怎么把真实的睡眠数据交给 LSTM。
等第一版模型真正训练起来,再继续写下一篇。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
评论区
欢迎来到 Lululove Blog。这里记录学习、项目与生活。
关于我