2、TinyML与异常检测基础:TinyML特点、资源约束、常见异常检测方法(统计、距离、机器学习)概述

TinyML 是机器学习与嵌入式物联网系统交叉融合的前沿领域,其核心目标是在毫瓦级甚至微瓦级功耗预算下,将深度学习、经典统计模型或信号处理算法部署到 MCU(微控制器)、DSP 或极低功耗 AI 加速器上。与云端训练、边缘推理的常规 ML 流程不同,TinyML 异常检测系统必须在 内存(RAM/Flash)、算力(MACs/周期)、功耗(电池寿命)和实时性 四重约束下完成数据采集、特征提取、推理和决策。理解这些约束是设计阈值、平衡误报与漏报的前提——因为资源限制直接决定了你能运行多复杂的模型、能缓存多长的历史窗口、能以多高的频率采样。

TinyML 异常检测系统资源约束与算法选型框架 MCU / 边缘处理器 Cortex-M4/M7/RISC-V @ 80-240MHz 资源约束边界 • RAM: 16KB - 512KB • Flash: 128KB - 2MB • 功耗: 1mW - 50mW • 采样率: 10Hz - 1kHz • 无浮点单元(部分) • 电池供电(纽扣/锂电) 异常检测方法谱系 ① 统计法: 均值/方差/3σ ② 距离法: kNN/LOF/马氏距离 ③ 机器学习: 孤立森林/SVM ④ 深度学习: 自编码器/TCN ⑤ 混合: 统计+残差分析 ⑥ 在线学习: 滑动窗口更新 约束输入 算法选择 传感器数据采集 IMU/温度/振动/电流 特征提取 时域/频域/统计量 推理/打分 异常分数/概率 阈值判定 报警/正常 模型更新 / 阈值自适应调整(在线学习) 误报率 漏报率 维护成本 阈值设计三角平衡

上图展示了 TinyML 异常检测系统的整体框架:左侧是硬件资源约束边界,右侧是可选算法谱系,底部是数据从采集到阈值判定的完整链路。值得注意的是,阈值设计并非独立环节,它贯穿于特征提取、模型推理和决策输出的全过程。在 TinyML 场景下,由于无法像云端那样存储大量历史数据或运行复杂网格搜索,阈值往往需要结合离线预标定与在线自适应两种策略。下面我们从 TinyML 的核心特点出发,深入剖析资源约束如何影响异常检测方法的选择与阈值设计。

2.1 TinyML 的核心特点与资源约束

TinyML 设备通常指那些面向特定任务、功耗极低、计算能力有限的嵌入式系统。与通用边缘计算设备(如树莓派、Jetson)相比,TinyML 设备具有以下显著特点:

  • 极低功耗预算:整机功耗通常控制在 1mW~100mW 之间,电池供电场景下要求待机电流低至微安级,工作电流不超过数十毫安。这意味着异常检测算法不能持续全速运行,往往需要采用事件驱动或占空比调度策略。
  • 有限的计算资源:MCU 主频通常在 80MHz~240MHz,且多数不具备硬件浮点单元(FPU),整数运算和定点量化是主流。一次乘法累加(MAC)操作可能需要多个时钟周期,因此算法复杂度必须控制在每秒几万到几百万次操作以内。
  • 内存与存储瓶颈:RAM 大小从 16KB 到 512KB 不等,Flash 存储通常为 128KB~2MB。模型参数、中间特征图、滑动窗口缓冲区都需要精打细算。例如,一个 128 维的浮点特征向量占用 512 字节,若缓存 100 个历史样本则需要 50KB RAM,这已经占用了中端 MCU 的 1/4 内存。
  • 实时性与确定性:工业异常检测往往要求毫秒级响应,且系统行为必须可预测。这意味着算法执行时间不能有大的抖动,动态内存分配(malloc/free)应尽量避免,递归调用和复杂数据结构也需要谨慎使用。
资源约束对阈值设计的直接影响:由于无法存储大量历史数据,基于全局统计的阈值(如全局均值±3σ)难以实时更新;由于计算能力有限,基于密度聚类或迭代优化的阈值搜索方法(如网格搜索最小化代价函数)在 MCU 上不可行。因此,TinyML 阈值设计通常采用离线训练+在线查表或轻量级在线更新(如指数加权移动平均)的方式。

2.2 常见异常检测方法概述

在 TinyML 资源约束下,并非所有异常检测算法都适用。我们需要根据算法的时间复杂度、空间复杂度以及可解释性进行筛选。下表对比了三大类方法的 TinyML 适配性:

方法类别 典型算法 计算复杂度 内存需求 TinyML 适配性 阈值设计特点
统计方法 3σ、EWMA、CUSUM O(n) 极低 极低(仅需均值/方差) ★★★★★ 非常适合 阈值可解析计算,易在线更新
距离方法 kNN、LOF、马氏距离 O(n²) 高 需存储训练样本集 ★★☆☆☆ 受限(需压缩样本) 阈值依赖距离分布,需离线确定
机器学习 孤立森林、SVM、小型MLP O(n·log n) 中等 模型参数较大 ★★★☆☆ 需量化压缩 阈值基于模型输出分数,需校准

从上表可以看出,统计方法在 TinyML 中占据主导地位,因为它们几乎不消耗额外内存,且阈值具有明确的统计含义。然而,统计方法对非平稳信号(如设备老化、环境温度漂移)的适应性较差,这时需要引入滑动窗口自适应阈值或轻量级在线学习机制。

2.2.1 统计方法:从 3σ 到 EWMA

最基础的统计异常检测假设数据服从正态分布,当新样本偏离均值超过 k 倍标准差时判定为异常。在 TinyML 中,我们通常使用递推公式在线更新均值和方差,避免存储全部历史数据:

// 在线更新均值与方差(Welford算法)
float count = 0, mean = 0, M2 = 0;
void update(float x) {
    count += 1;
    float delta = x - mean;
    mean += delta / count;
    float delta2 = x - mean;
    M2 += delta * delta2;
    float variance = M2 / count;
    float stddev = sqrt(variance);
    // 阈值判断: |x - mean| > k * stddev
}

然而,3σ 方法对趋势性变化不敏感。更稳健的做法是使用 EWMA(指数加权移动平均),它给予近期数据更高权重,能更快反映均值漂移:

// EWMA 异常检测
float lambda = 0.2;  // 平滑因子
float ewma = 0, ewma_var = 0;
void ewma_update(float x) {
    float diff = x - ewma;
    ewma += lambda * diff;
    ewma_var = (1 - lambda) * (ewma_var + lambda * diff * diff);
    float threshold = 3 * sqrt(ewma_var);
    if (fabs(x - ewma) > threshold) {
        // 触发异常
    }
}
经验提醒:在 TinyML 中,EWMA 的平滑因子 λ 直接影响阈值灵敏度。λ 越大,对近期变化越敏感,但误报率也会上升。建议根据采样频率和异常持续时间来调节:若采样率为 100Hz,异常持续 0.5 秒(50 个样本),λ 可取 0.1~0.3;若异常是缓慢漂移,λ 应更小(0.01~0.05)。

2.2.2 距离方法:内存受限下的样本压缩

距离方法(如 kNN)在原始形式下需要存储大量训练样本,这在小内存 MCU 上不可行。实际工程中常采用两种变通方案:

  1. 原型压缩:使用聚类算法(如 K-Means)将训练数据压缩为 k 个簇中心,在线检测时计算新样本到最近簇中心的距离。例如,将 10000 个正常样本压缩为 16 个原型向量,每个向量 8 维,仅需 512 字节存储。
  2. 马氏距离:考虑特征相关性,但需要存储协方差矩阵的逆。对于 d 维特征,矩阵大小为 d×d,当 d=8 时仅需 256 字节,可接受;但 d=32 时需 4KB,已接近内存上限。

距离方法的阈值通常设定为“最大正常距离”或“距离分布的 95% 分位数”。由于 MCU 无法存储完整分布,我们可以在离线阶段计算好阈值,并将其作为常量写入 Flash。

2.2.3 机器学习方法:量化与剪枝后的轻量模型

当统计方法无法捕捉复杂非线性异常模式时,可以考虑小型机器学习模型。在 TinyML 中,最常用的是:

  • 孤立森林:通过随机切割特征空间来隔离异常点。模型由多棵决策树组成,每棵树深度有限(通常 3~5 层),推理时只需沿树路径比较特征值。一个 10 棵树、深度 4 的孤立森林,每棵树约 15 个节点,总参数约 600 个整数,Flash 占用小于 2.5KB。
  • 小型自编码器:将高维输入压缩到低维瓶颈再重建,重建误差作为异常分数。一个输入 8 维、隐藏层 4 维、输出 8 维的自编码器,权重参数约 80 个浮点数,量化后仅 320 字节。但自编码器需要乘法累加操作,在无 FPU 的 MCU 上需使用定点数模拟。
  • 线性 SVM:对于线性可分问题,SVM 退化为一个权重向量和偏置,计算量极小。但实际工业数据往往非线性,需要核函数映射,这会显著增加计算量,因此 TinyML 中较少使用核 SVM。
风险提示:机器学习模型的阈值(如孤立森林的异常分数阈值、自编码器的重建误差阈值)不像统计方法那样有明确的概率含义。必须通过验证集确定阈值,且要警惕过拟合——在 TinyML 场景下,由于训练数据通常来自有限工况,模型可能对未见过的正常状态误报。建议在部署前进行至少 3 种不同工况的交叉验证。

2.3 案例拆解:振动监测中的方法选型与阈值初设

我们以一个实际的工业电机振动监测项目为例,说明如何在 TinyML 约束下选择异常检测方法并设计初始阈值。

背景与约束:某工厂需要在 50 台电机上部署无线振动传感器,每台电机配备一个 STM32L4 系列 MCU(Cortex-M4 @ 80MHz,无 FPU,RAM 64KB,Flash 512KB),使用加速度计以 800Hz 采样率采集振动信号,每 10 秒进行一次 1 秒窗口的 FFT 分析。电池容量为 2400mAh 锂亚电池,要求续航 2 年以上。系统需检测轴承磨损和不对中故障。

初始现象与目标:电机正常运行时,振动频谱在 1x 转频(约 25Hz)处有稳定峰值,幅值在 2~4 m/s² 之间;轴承早期磨损时,2x~4x 频段会出现边带。目标是在不误报的前提下,尽可能早地检测到轴承退化。

关键输入数据与参数:

  • 特征提取:从 1 秒窗口的 FFT 中提取 4 个特征——1x 幅值、2x 幅值、高频段(500-800Hz)能量、波形峰度。
  • 内存预算:特征缓冲区最多存储 200 个历史样本(每个样本 4 个 float,共 3.2KB),用于在线统计。
  • 功耗预算:每次 FFT+特征提取约消耗 12mA 电流,持续 80ms,平均功耗约 0.96mAh/天,加上无线传输,总功耗需控制在 3mAh/天以内。

分析判断过程:由于特征维度低(4 维),且已知正常工况相对稳定,我们首先尝试统计方法。但发现 1x 幅值会随负载变化而波动,单纯 3σ 方法在负载波动时误报率高达 15%。于是改用 EWMA 对每个特征单独建模,并设置两个阈值:

// 特征1: 1x幅值,使用EWMA
float ewma_1x = 3.0;  // 初始均值
float ewma_var_1x = 0.5;
float lambda = 0.15;
// 阈值: 3倍EWMA标准差
float thresh_1x = 3 * sqrt(ewma_var_1x);  // 约1.5 m/s²

// 特征2: 高频能量,使用滑动窗口分位数
#define WINDOW_SIZE 100
float energy_buffer[WINDOW_SIZE];
// 每10秒更新一次,计算95%分位数作为阈值

实际操作步骤:

  1. 离线采集 3 台正常电机各 24 小时的数据,计算每个特征的 EWMA 初始均值和方差。
  2. 在 MCU 上实现 EWMA 更新逻辑,每 10 秒更新一次均值和方差,并动态调整阈值。
  3. 对于高频能量特征,由于它不服从正态分布,改用滑动窗口的 95% 分位数作为阈值,窗口大小 100 个样本(约 16.7 小时)。
  4. 设置两级报警:当 1 个特征超阈值时触发“关注”级别,当 2 个及以上特征同时超阈值时触发“报警”级别。

结果对比与复盘:部署 3 个月后,系统成功检测到 2 起轴承早期磨损(在振动加速度超标前 2~3 周预警),误报率为每台电机每月 0.3 次,低于预期的 1 次/月。但发现一个问题:当环境温度变化超过 15°C 时,1x 幅值的 EWMA 均值发生缓慢漂移,导致阈值自适应过宽,灵敏度下降。复盘后,我们在 EWMA 更新中加入了温度补偿系数,并将 λ 从 0.15 调整为 0.08,降低了温度漂移的影响。

案例启示:TinyML 异常检测的阈值设计不是“一锤子买卖”。初始阈值可以基于离线数据设定,但必须设计在线自适应机制。同时,多特征融合判断比单特征阈值更稳健——单个特征可能因工况变化而误报,但多个特征同时异常的概率极低。此外,阈值更新频率要与设备功耗预算平衡,过于频繁的更新会增加计算和存储开销。

2.4 常见误区与总结复盘

在 TinyML 异常检测的工程实践中,以下误区值得特别注意:

  • 误区一:盲目追求复杂模型。在资源受限设备上,一个精心调参的 EWMA 往往比一个压缩后的深度网络更可靠。复杂模型不仅占用内存,还会引入量化误差和推理延迟,反而降低系统实时性。
  • 误区二:忽略数据分布的非平稳性。工业设备存在磨损、温度漂移、负载变化等自然退化过程,固定阈值必然失效。必须设计阈值自适应机制,但自适应速度要慢于异常演化的速度,否则异常会被“自适应”掉。
  • 误区三:阈值设定只关注误报率。在维护场景中,漏报的代价往往远高于误报——一次漏报可能导致设备损坏、产线停机,损失可能是误报成本的百倍。阈值设计应基于代价矩阵,而非单纯追求准确率。
  • 误区四:在线更新阈值时忽略数值稳定性。在 MCU 上使用浮点数模拟时,方差可能因舍入误差变为负数,导致 sqrt 出错。建议使用 Welford 算法或定期重置统计量。