news 2026/9/18 16:46:01

WiFi CSI动作识别数据集全解析:从数据采集到深度学习应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WiFi CSI动作识别数据集全解析:从数据采集到深度学习应用

WIFI CSI动作识别数据集全解析:从数据采集到深度学习应用

先说个很直白的结论:WiFi感知这个方向,尤其是基于信道状态信息(CSI)做人类动作识别,这几年之所以能火起来,核心原因就一个——WiFi设备无处不在,不需要额外买摄像头、不需要穿戴传感器,用现成的路由器就能“隔墙观人”。听起来很科幻,但实际做起来你会发现,真正卡住你的不是模型,而是数据。模型结构可以从论文里抄,训练技巧可以靠调参积累,唯独数据集这件事,你得自己一步一个脚印去解决。这篇东西就是我折腾CSI动作识别数据集全流程的记录,从硬件接线到最终喂给深度学习模型,把每一步的坑和判断都摊开讲。

不管你是刚接触WiFi感知的研究生,还是想在智能家居里加点“无感交互”的工程师,这篇文章的思路都适用。我会尽量避开论文里那种“用了XX设备、采集了XX数据、精度达到XX%”的干巴巴描述,重点讲讲中间那些论文不写的东西:网卡为什么选这个型号、采集环境怎么布、动作标签怎么定、数据清洗怎么做、模型输入为什么是那个形状。

1. 内容整体设计与思路拆解

1.1 一个反向的认知:CSI不是信号强度,是一堆复数

很多人一上来就混淆两个概念:RSSI(接收信号强度指示)和CSI(信道状态信息)。RSSI只有一个数值,表示信号整体强弱;CSI则是一组复数,描述的是信号从发射端到接收端经过多条路径之后,每个子载波上的幅度和相位变化。

打个比方,RSSI像你站在远处听到一个人说话的总音量,CSI则是你听到他说的每一个字、每一个音调。动作识别要的是“字”和“音调”,所以必须用CSI。

具体来说,在802.11n/ac标准里,一个20MHz信道被划分成56个或64个子载波。人的肢体动作会改变信号传播路径,每个子载波的幅度和相位都会随之发生细微变化。这些变化叠加在一起,就形成了你想要的“动作指纹”。

这里有个关键点:CSI数据通常是复数形式,你处理的时候要么取幅度、要么取相位,也可以两个都用。幅度相对稳定,相位会受时钟偏移、载波频偏的影响,直接拿来用经常是一片乱码。所以我的建议是,第一版系统先用幅度数据,别一上来就搞相位校正,那玩意儿能劝退一半新手。

1.2 为什么偏要用WiFi做动作识别,大家图什么

传统动作识别两条路线,一是视觉方案,二是传感器方案。视觉方案问题很直接:隐私敏感,摄像头装在卧室里,就算只做姿态估计,用户体验也有心理负担;传感器方案要求用户必须穿戴设备,智能手表、胸带、腕带,谁也不会为了“让灯自动亮”天天戴着东西。

WiFi CSI方案的价值恰好卡在两者之间:既不需要用户配合,又不涉及图像隐私。它用的是物理层的信道信息,分辨率和“语义”天然比图像低,但胜在覆盖广、成本低、无感。

拿智能家居举个例子:你可以在卧室里放一台支持CSI采集的设备,不用摄像头、不用麦克风,就能知道屋里的人是坐着、走动还是摔倒了。这种场景对“具体姿势”没要求,只需要判别“动作类型”,CSI完全够用。

1.3 我为什么建议你自己采集数据,而不是白嫖公开数据集

如果你搜过,会发现网上确实有几个公开的CSI动作识别数据集。典型的有:UT_HAR(用Intel 5300网卡采集)、SignFi(手语识别)、NTU-Fi(北京理工大学出的,规模比较大)。用这些数据集的问题是:设备不匹配、环境不匹配、动作类型不匹配。

CSI数据对环境的敏感程度超乎想象。换个房间、挪一下桌子、增加一堵隔断,之前采集的数据很可能就废了一大半。公开数据集大多是实验室常规环境采集的,你拿去做demo跑通流程没问题,但如果要部署到自己的真实场景,精度崩掉是大概率事件。

所以我的建议很明确:用公开数据集做算法验证和baseline对比,然后尽快搭建自己的采集环境。自己采集的数据集虽然费时费力,但你能完全掌控采集频段、天线配置、动作集合、标签体系,后续每一步都走得踏实。

2. 数据采集环境搭建:硬件选型与部署细节

2.1 网卡芯片怎么选,别在这上面交学费

CSI数据不是随便一块无线网卡就能读出来的。商用网卡的固件会把物理层信息直接丢进芯片里的硬件加速器处理,用户态根本拿不到。你需要的是一块能在驱动层导出CSI的工具。

目前主流的方案就那么几个:

  • Intel 5300网卡 + Linux 802.11n CSI Tool:这是老牌方案,支持3根天线,能提取30个CSI子载波。优点是资料多、论文里最常用,缺点是只能工作在2.4GHz、且只支持802.11n协议,想上5GHz或WiFi 6没戏。
  • Atheros CSI Tool:支持更多子载波(最高可达114个),在一些研究组里用得比较多。但兼容性和稳定性一般,驱动需要自己打补丁。
  • Intel AX200/AX210 + Linux 802.11ax CSI Tool:这是最近几年比较主流的方案。支持WiFi 6协议,能拿到更多子载波和更细的信道信息,适配现代路由器的能力更强。

我自己主力用的是AX200方案。为什么?因为它能吃5GHz频段,实际动作识别时5GHz频段的波长更短,对微小动作的敏感度更高;而且AX200模块便宜,淘宝一百多块钱就能搞定,驱动开源社区维护得也勤。

注意:无论你用哪块网卡,都需要在Linux环境下编译对应的CSI采集工具。这个过程涉及内核模块、固件版本甚至网卡硬件版本匹配,一定先看README,别跳过依赖检查。

2.2 接收端和发送端怎么布局

CSI动作识别系统通常是“一发一收”结构:发送端持续发射数据包,接收端解析CSI。职责分配建议这样:

  • 发送端:一台普通的无线路由器,或者另一台装有无线网卡的设备,设为AP模式或Ad-hoc模式,持续向接收端发包。不要用手机热点,因为它的发射功率管理和发包频率都不稳定。
  • 接收端:装了支持CSI采集网卡的设备,Linux系统,进入Monitor模式或与发送端建立连接后采集。

部署位置是首个大坑。我踩过最典型的例子:把接收端放在墙角、天线朝向错误,导致采集到的CSI幅度波动极小,任何动作看起来都差不多。后来总结出的经验是:

  1. 发送端和接收端之间,不要有贯穿的人行通道,避免无关人员反复横穿。
  2. 设备高度放在0.8米到1.2米之间,大致是人体躯干的高度。太低了捕捉腿部动作,太高了捕捉肩部和手臂动作,都会有视野盲区。
  3. 两根天线不要平行摆放,最好呈一定角度。平行天线在某些动作方向上几乎收不到多径变化。

2.3 采集场景里的遮挡物,是你的朋友不是敌人

很多人做实验喜欢清空房间,恨不得中间一片空地。这样做出来的数据虽然“干净”,但真到实际应用时你会被打脸——真实的家庭环境有沙发、有茶几、有人走来走去、门还会开关。

我的建议是:保留常见的家具布置,只在采集期间保持相对静止。道理很简单,CSI信号是“多径叠加”的结果,固定障碍物会让多径环境更丰富,动作引起的信号变化反而更明显;而频繁移动的家具会让信道状态发生突变,那不是动作信号,是环境噪声。

如果你有条件,最好在两种环境各采一遍:空旷环境采一遍用于算法开发,模拟居家环境采一遍用于测试鲁棒性。两部分数据混在一起训练,测试精度可能不如“纯环境”高,但泛化能力会明显强一截。

2.4 数据帧率、包长这些参数怎么定

采集工具的很多参数直接决定了后续数据质量。我用的典型配置:

  • 发包频率:1000包/秒。这个频率能捕捉到绝大多数人体动作的频率成分。走路约1-2Hz,够用了。
  • 子载波数量:30个(Intel 5300方案)或114个(Athelos方案)。AX200方案能拿更多,但计算量也更大。第一版模型建议先用30个子载波验证流程。
  • 数据包大小:用默认值即可,CSI提取和包大小关系不大。
  • 天线数量:发送端1根、接收端3根,这样能拿到3条链路的CSI,数据维度更丰富。

如果你的采集工具支持多天线,优先用接收端3根天线。多天线捕获的空间信息更多,尤其对“朝向不同方向的同一动作”,3根天线的区分度比单天线好不少。

3. 数据集构建全流程:从原始采集到可以直接训练

3.1 动作集合设计与标签规范

动作集合别拍脑袋定,有一个原则:先确认应用场景,再定动作类别。你做跌倒检测,动作集合里就没必要包含“挥左手”“挥右手”这种细粒度动作;你做手势控制,就别把“走路”“坐下”这种全身动作混进来。

以智能家居场景为例,我常用的基础动作集是:

动作编号动作名称持续时间参考
0无动作(静止)3秒以上
1走路动态持续
2坐下约2秒完成
3站起约2秒完成
4挥手约2秒连续
5弯腰捡东西约3秒完成
6跌倒约1-2秒完成

标签设计用两套体系:一套是离散标签(0-6),用于分类任务;一套是事件标签(动作开始时间、结束时间),用于后续做动作检测或时序分割。从一开始就养成记录“动作区间”的习惯,后面做时序模型会省很多事。

建议:每个动作至少采集3轮,每轮之间间隔10秒以上。间隔期间保持静止,这样自然而然就产生了“负样本”和“动作起止边界”,对训练非常有帮助。

3.2 采集流程脚本化:别指望手工按键盘能采集出好数据

采集CSI数据看似简单,实际操作时会发现,手工控制采集起始和结束是非常不靠谱的。你一个人又要做动作,又要拿键盘按开始/停止,手忙脚乱之间就会产生大量脏数据。

我的做法是写一个简单的数据采集脚本,实现半自动采集流程:

import time import subprocess import os def collect_sample(output_dir, action_label, sample_id, duration=5): os.makedirs(f"{output_dir}/{action_label}", exist_ok=True) # 假设csi_tool的采集命令格式如下 cmd = f"sudo ./log_to_file -c {duration*1000} -o {output_dir}/{action_label}/{sample_id}.dat" print(f"[INFO] 3秒后开始采集动作: {action_label}, 样本: {sample_id}") time.sleep(3) subprocess.run(cmd, shell=True) print(f"[INFO] 采集完成,保存至 {sample_id}.dat") time.sleep(5) # 动作间隔,留出静默期 # 示例调用 collect_sample("./dataset", "walk", "s01_01", duration=5)

脚本里在采集前加了3秒倒计时,给操作者从电脑前走到动作区域的时间;采集结束后强制等待5秒再开始下一轮,确保信道状态恢复稳定。这比手动按Ctrl+C靠谱多了。

3.3 数据整理与格式统一

CSI采集工具输出的原始文件通常是二进制或专用文本格式,里面混杂了时间戳、MAC地址、序列号、CSI矩阵等一堆东西。你不能直接拿这些文件训练模型,得先转成统一格式。

我的处理流程是三步:

  1. 写一个解析脚本,从原始文件中提取CSI复数矩阵。
  2. 以“样本ID + 动作标签 + 链路编号”为维度,整理成NumPy数组。
  3. 保存格式统一使用.npy.npz,方便后续加载。

每一步都做日志输出,记录文件来源、对应动作、样本数量。这能帮你快速定位“哪个样本数据异常”。

3.4 数据清洗:哪些样本必须扔,哪些信号必须滤

数据清洗是整个流程里最枯燥但最重要的一环。CSI数据常见的脏数据有:

  • 静默段混入:采集启动时设备的短暂状态切换会导致前几百个数据包异常,表现为幅度尖峰或持续为0。处理办法是丢弃每个样本前5%的数据。
  • 突发脉冲噪声:可能是设备调度、其他WiFi干扰引起的,表现为某一时刻所有子载波幅度同时跳变。用中值滤波可以压掉大部分。
  • 动态环境干扰:比如采集过程中有旁人走过,导致多径环境突变。这类数据靠肉眼很难发现,建议做一次简单的运动检测——如果一段数据的方差异常大,就标出来人工确认。

滤波器的选择,推荐顺序是:先做均值滤波/滑动平均,再看效果决定是否上巴特沃斯带通滤波。人体动作的频率主要集中在0.5Hz到5Hz之间,超过这个范围的成分大多是环境噪声。

举一个带通滤波的实现示例:

from scipy.signal import butter, sosfiltfilt def butter_bandpass(lowcut, highcut, fs, order=4): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq sos = butter(order, [low, high], btype='band', output='sos') return sos def apply_filter(data, fs=1000): sos = butter_bandpass(0.5, 5.0, fs) return sosfiltfilt(sos, data, axis=-1)

这里用的是filtfilt,它做了前后向滤波,不会引入相位偏移,对于CSI这种需要保留波形形态的数据尤其合适。

3.5 数据划分策略:别让同一段连续数据同时出现在训练集和测试集

划分数据集时犯的最典型的错误是:把连续采集的数据随机打乱后按比例划分。表面看没问题,实际操作中你会发现,同一段连续时间内采集的数据,前后相关性强得吓人——模型可能不是学到了“动作特征”,而是记住了“这个时间段的环境特征”。

正确做法是以“采集批次”或“轮次”为单位划分。比如每轮采集10个动作,训练集取第1、3、5轮,测试集取第2、4轮,这样测试数据是模型完全没见过的独立批次,评估结果才有说服力。

如果你有多个受试者,划分时尽量保证同一个人的数据不跨集合,这才叫“人无关”评估。跨人评估的精度一般比同人低10到20个百分点,这是正常现象,别慌。

4. 深度学习建模:动作识别的核心环节

4.1 模型输入怎么构造:从CSI矩阵到特征张量

CSI数据的原始形态是“[数据包索引, 子载波索引, 天线链路索引]”的三维结构。以3天线、30子载波为例,每个时间点上你拿到的是一张3×30的特征图。

直接把这个三维结构展开成一维向量丢给全连接网络是可行的,但效果一般。更好的做法是把CSI序列看作“图像”——时间维度相当于图像的宽度,子载波维度相当于图像的高度,天线链路相当于图像的通道。这样一个动作片段就变成了一张多通道的“CSI图像”。

以1秒数据(1000个包)为例,输入张量形状是[1000, 30, 3](时间×子载波×链路)。你可以把它转成[30, 1000, 3][3, 30, 1000],根据模型设计来选择通道顺序。

我的习惯是:时间维度放最前面,子载波维度放中间,天线链路放最后,也就是[time_steps, subcarriers, antenna]。这样设计单纯是因为PyTorch里nn.Conv1d默认输入是[batch, channels, length],我可以把天线链路数当通道,直接在时间维度上做一维卷积。

4.2 网络结构如何选:从经典CNN到轻量Transformer

CSI动作识别模型的选择,大致分为这么几代:

  • 第一代:手工特征 + 传统机器学习。比如从CSI序列中提取均值和方差,丢给SVM或随机森林。这种方案精度不高,但在样本量极小时是一个不错的baseline。
  • 第二代:CNN。把CSI时间序列当作图像,用二维CNN或一维CNN提取空间和时间特征。代表作是很多基于ResNet的变体。有几个经验点:小网络(3-4层卷积)往往比大网络更稳,因为CSI数据的语义远比图像简单,用不着ResNet-50这种大模型。
  • 第三代:CNN + RNN。前面用CNN提取子载波间的空间特征,后面接LSTM/GRU建模时间依赖。这种结构在动作识别任务里依然是性价比最高的方案。
  • 第四代:Transformer。把CSI序列切成patch,丢给标准的Vision Transformer。优势是能捕捉长时间依赖,劣势是训练数据量要求高,数据量不足时容易训不动。

如果你是第一次做,我建议先跑通一个三层的1D CNN,隔一阵再试CNN+LSTM。别绕开baseline直接上Transformer,那会让你在调参的海洋里迷失方向。

一个简单的1D CNN模型定义如下:

import torch.nn as nn class CSICNN(nn.Module): def __init__(self, n_channels=3, num_classes=7): super().__init__() self.conv1 = nn.Conv1d(n_channels, 32, kernel_size=5, padding=2) self.conv2 = nn.Conv1d(32, 64, kernel_size=5, padding=2) self.conv3 = nn.Conv1d(64, 128, kernel_size=3, padding=1) self.pool = nn.MaxPool1d(2) self.relu = nn.ReLU() self.dropout = nn.Dropout(0.3) self.fc = nn.Linear(128 * (1000 // 8), num_classes) def forward(self, x): x = x.permute(0, 2, 1) # [batch, time, channels] -> [batch, channels, time] x = self.relu(self.conv1(x)) x = self.pool(x) x = self.relu(self.conv2(x)) x = self.pool(x) x = self.relu(self.conv3(x)) x = self.pool(x) x = x.flatten(1) x = self.dropout(x) return self.fc(x)

4.3 训练细节:学习率、数据增强和过拟合

训练CSI模型和训练图像模型有相似之处,但有几个特殊点。

学习率建议从1e-3开始,用CosineAnnealing或ReduceLROnPlateau调度。CSI数据的信噪比没那么高,学习率太大容易震荡,太小又收敛太慢。

数据增强是一个值得重点探索的方向。CSI数据不像图像那样可以随便旋转裁剪,但可以做这几类增强:

  • 加噪声:在训练样本上叠加高斯噪声,模拟环境扰动。
  • 时间拉伸/压缩:对样本在时间维度上缩放,模拟不同动作速度。
  • 幅度缩放:整体乘以一个随机系数,模拟人在不同距离位置时的信号强弱差异。
  • 频段扰动:对部分子载波做随机Mask,模拟多径环境的局部变化。

过拟合是CSI模型最常踩的坑。因为公开数据集规模通常不大,几千个样本已经算多的了。判断过拟合别只看训练精度,关键看验证集精度的波动幅度。如果验证集精度比训练集低超过8个百分点,先加Dropout,再加数据增强,最后才考虑换小模型。

4.4 评估指标怎么看:别只盯着平均精度

分类任务大家习惯用Accuracy,但动作识别场景里,样本不均衡问题非常突出。

比如“走路”这个动作,一次走3秒(3000个数据包),你可以切出很多窗口样本;而“跌倒”动作只持续1秒,窗口数量天然少。如果用整体精度评估,模型很可能把所有样本都判为“走路”,精度看起来仍有70%以上,实际毫无用处。

我在评估时固定看这几个指标:

  • 混淆矩阵:看类别之间的具体混淆情况,尤其关注“跌倒”是否被误判为“坐下”。
  • F1-score(每个类别的宏平均):比Accuracy更能反映小类别的识别效果。
  • 召回率(对关键类别):在跌倒检测这类场景里,“漏报”的代价远比“误报”高,必须单独看召回率。

建议在训练过程中定期在验证集上计算混淆矩阵,打印出来看一眼。模型精度涨了但混淆矩阵没变化,大概率是样本不均衡的问题被整个验证集的平均数掩盖了。

5. 常见问题与排查技巧实录

5.1 采集端“有数据但全是噪声”:先看天线,再看环境

遇到CSI数据完全不可用的情况,优先排查天线是否松动。CSI采集是物理层的工作,天线接触不良会导致接收信号功率波动剧烈。我之前就遇到过采集了半天,发现连接器松了,数据全程是噪声,那叫一个心塞。

另一种常见情况是采集环境里有强干扰源。检查一下周围有没有微波炉、蓝牙音箱、USB 3.0设备在工作。这些设备在2.4GHz频段的影响尤其明显,有条件就切到5GHz频段。

5.2 模型训练精度高、测试精度崩塌:八成是数据划分问题

前面提到的“连续数据随机划分”是最常见原因。另一个隐蔽原因是:测试集和训练集采集时间间隔太近,环境几乎没变化。解决方式是隔天再采一遍测试数据,或者移动几个家具位置后再采,让测试集环境真实独立。

5.3 跌倒检测总是漏报:数据增强和阈值两手都要抓

跌倒检测是CSI动作识别里最有应用价值也最难的任务。难点在于:跌倒是一个瞬时动作,持续时间短、CSI变化幅度大但样本少;而和跌倒相似的动作(快速坐下、蹲下)在CSI特征上非常接近。

解决手段有两个方向:

  • 数据层面:至少采集500次以上的跌倒样本,并且在多个方向、多个位置采集。如果不够,就用时间拉伸和加噪声增强。
  • 模型层面:不用标准的多分类输出,改成“跌倒检测”二分类,并引入事件级别的判断逻辑。比如连续N帧都说“跌倒”,再触发告警,大幅降低误报。

5.4 不同时段的同一动作,特征差异为什么这么大

这是CSI感知最核心的痛点之一。早上、中午、晚上的温湿度不同,房间内物体的微小位移不同,甚至人的体表含水率变化都会影响多径传播。因此你会发现:上午采集的训练数据,下午测试精度明显下降。

应对手段:

  • 多次分时采集,把一天中不同时段的数据都覆盖到。别嫌麻烦,这在真实部署中非常关键。
  • 训练时加入频段扰动和幅度缩放,一定程度模拟环境变化。
  • 定期用新采集的数据做增量训练或微调,让模型跟上环境变化。

这套流程走下来,你手上就有一套完整的从“网卡到模型”的方案。整个过程中,我最大的体会是:CSI动作识别里,90%的精力都耗在数据上,模型反而是最轻松的一环。不管你是准备发论文还是做产品原型,先把数据管道打磨顺了,后面的一切都会顺畅很多。

最后再分享一个细节:每采集完一批数据,立刻画一下CSI波形图,肉眼扫一遍。好数据有清晰的规律波动,坏数据一眼就能看出来。千万不要攒了一堆数据到最后才清洗,那时候返工的代价真的很大。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 16:42:06

从矩阵分析到STM32:卡尔曼滤波工程落地指南

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

作者头像 李华
网站建设 2026/9/18 16:42:02

精益与DevOps合流:价值流映射驱动的CI/CD流水线交付优化

简介:这份PDF资料围绕精益实践与DevOps融合的产品开发体系展开,面向产品经理、研发负责人及运维工程师,用于解决交付周期长、协作割裂、质量波动等常见问题。内容从精益消除浪费、流程优化讲到DevOps的自动化、持续集成与交付、监控反馈&…

作者头像 李华
网站建设 2026/9/18 16:39:47

德国宣誓翻译留学材料包含哪些?怎么办理?完整清单汇总

申请德国留学,宣誓翻译是绝大多数同学都会卡住的关键环节,区别于普通翻译,它是德国官方认可、具备法律效力的专属翻译形式,也是高校申请、签证递交、材料审核的硬性要求。很多留学生因材料不全、翻译不规范、无宣誓资质&#xff0…

作者头像 李华
网站建设 2026/9/18 16:34:18

Spring Boot 3整合MyBatis-Plus连接MySQL完整指南与避坑实践

1. 为什么 Spring Boot 3 让很多人卡在了第一步 说个真实经历,我接手过一个老项目升级的活儿,pom 文件里 Spring Boot 版本从 2.7 升到 3.2,结果编译报错差点把人整崩溃。不是业务代码的问题,而是依赖之间的版本兼容关系全变了。…

作者头像 李华
网站建设 2026/9/18 16:33:12

正弦稳态电路向量法:从复数阻抗到功率计算全解析

简介:《用向量法表示电路》PPT学习教案面向电路分析初学者与教学者,系统讲解如何以复数与相量法表示和求解正弦交流电路,帮助读者突破从时域到相量域的抽象难点。压缩包内仅有1个pptx文件,大小482KB,以图文教案形式呈现…

作者头像 李华
网站建设 2026/9/18 16:33:10

基于51单片机的电子密码锁设计:矩阵键盘、状态机与AT24C02掉电存储

简介:一份基于51单片机的电子密码锁设计完整报告,适用于单片机课程设计、毕业设计及实训报告撰写,适合初、中级学习者参考。压缩包仅含1个docx文档,整体约1.52MB,轻量便于下载阅读,目前已有177人浏览学习。…

作者头像 李华