
1. 先搞清楚 ST 的 Model Zoo 到底给了什么ST 官方这几年在嵌入式 AI 上动作不小STM32Cube.AI 加上 Model Zoo基本上把“能在 MCU 上跑的模型”这件事的门槛拉低了一大截。很多人第一次打开 Model Zoo 的仓库看到人体活动识别、图像分类、音频事件检测、异常检测这些现成模型第一反应就是那我是不是不用自己设计模型了直接拿来用就行我一开始也这么想。但实际做过几个项目之后我的结论是Model Zoo 解决的是“从零到一”的问题解决不了“从一到一百”的问题。它给你的是参考实现和验证过的网络结构不是给你量身定做的产品方案。你要不要自己设计模型取决于你的输入数据形态、算力预算、内存约束、精度要求和产品迭代节奏这五个维度里只要有一个跟 Model Zoo 里的示例对不上你就得动手改。这篇文章我想把这件事讲透。不是泛泛地说“要看情况”而是把 Model Zoo 里到底有什么、它的边界在哪、什么场景下可以直接抄、什么场景下必须自己设计、自己设计又该怎么做一条一条拆开讲。如果你正在用 STM32 做嵌入式 AI 相关的项目或者正在评估要不要上 ST 的 AI 工具链这篇应该能帮你省掉不少试错时间。1.1 Model Zoo 的本质是“参考设计”而不是“产品方案”先明确一个概念。ST 的 Model Zoo 不是一个模型市场它更像是一个经过验证的参考设计集合。里面的模型大多来自公开数据集上的经典网络结构比如用于人体活动识别的 CNN、用于关键词唤醒的 DS-CNN、用于图像分类的 MobileNet 变体。ST 把这些模型拿过来做了量化、剪枝、适配 Cube.AI 的转换流程然后开源出来。这意味着什么意味着这些模型的输入格式、输出类别、网络深度、参数量都是固定的。你拿过来能跑通是因为你喂给它的数据恰好符合它的输入要求。但真实项目里你的传感器型号、采样率、数据维度、类别定义几乎不可能跟示例完全一致。举个例子。Model Zoo 里有一个基于加速度计的人体活动识别模型输入是三轴加速度的滑动窗口输出是走路、跑步、静止等几个类别。如果你的项目用的是六轴 IMU或者你的类别定义是“正常行走、跌倒、上下楼”那这个模型你只能拿来参考它的网络结构不能直接部署。你得重新组织数据、重新定义输出层、重新训练。提示把 Model Zoo 当成“菜谱”而不是“外卖”。菜谱告诉你火候和配料比例但食材你得自己买、自己切。1.2 直接复用 Model Zoo 的三个前提条件那什么情况下可以直接用我总结下来满足以下三个条件的时候你可以先拿 Model Zoo 的模型跑一版基线输入数据形态完全一致传感器类型、采样率、窗口大小、归一化方式都跟示例对齐。输出类别和业务逻辑一致示例输出的类别就是你产品要输出的类别不需要增删改。精度和延迟满足产品要求在目标芯片上跑出来的推理时间和准确率都在可接受范围内。这三个条件同时满足的概率其实不高。我做过一个电机异常检测的项目一开始想直接用 Model Zoo 里的异常检测模型结果发现它的输入是振动信号的频谱图而我们的传感器输出的是原始时域波形光做特征转换就花了一周多最后还是自己重新设计了网络结构。所以我的建议是先花半天时间把 Model Zoo 里跟你场景最接近的模型跑通把它当作基线。然后拿你的真实数据去测看差距有多大。如果差距在可接受范围内那就微调如果差距很大那就自己设计。这个“半天”的投入非常值得因为它能帮你快速判断问题的难度级别。2. 什么情况下必须自己设计模型Model Zoo 覆盖不到的场景其实比想象中多。我梳理了几类典型情况如果你中了其中任何一条基本就得自己动手了。2.1 输入数据维度跟示例对不上这是最常见的情况。Model Zoo 里的模型大多针对特定传感器和特定数据格式。比如音频事件检测的模型输入是 MFCC 特征图像分类的模型输入是 RGB 三通道图像。但你的项目可能是多传感器融合加速度计 陀螺仪 磁力计九轴数据非图像二维数据雷达点云、红外热成像、电容阵列一维时序信号ECG、EEG、电流波形这些数据形态在 Model Zoo 里基本找不到直接对应的模型。你得自己设计输入层、自己决定特征提取方式、自己定义网络结构。我做过一个基于电容阵列的手势识别项目输入是 4x4 的电容值矩阵时序上是连续帧。Model Zoo 里没有任何跟电容阵列相关的模型。最后我自己设计了一个轻量级的 CNN输入层改成 4x4xT 的张量用了几层深度可分离卷积参数量控制在 20KB 以内在 STM32F4 上跑到了 15ms 以内的推理时间。2.2 算力和内存约束比示例更紧Model Zoo 里的模型是在 STM32H7 或者 STM32F7 这类高性能 MCU 上验证的。但你的项目可能用的是 STM32F0、STM32G0 或者 STM32L4 这类低功耗、低资源的芯片。这时候 Model Zoo 里的模型可能根本跑不起来或者跑起来之后 Flash 和 RAM 都不够用。我整理了一个简单的对照表帮你快速判断芯片系列典型 Flash典型 RAM能跑的模型量级Model Zoo 适配度STM32F0/G032-256KB8-32KB极轻量级参数量 10KB低基本要自己设计STM32L4256KB-1MB64-320KB轻量级参数量 50KB中部分模型可裁剪STM32F4512KB-2MB128-384KB中等参数量 200KB中高多数可跑但需优化STM32F7/H71-2MB512KB-1MB较复杂参数量 500KB高基本可直接跑如果你用的是 F0 或 G0 这类芯片Model Zoo 里的模型基本都要大幅裁剪裁剪到最后可能还不如自己从头设计一个更贴合任务的轻量网络。2.3 输出类别需要定制Model Zoo 里的模型输出类别是固定的。比如人体活动识别就是那几类关键词唤醒就是那几个词。但你的产品可能需要输出连续值而不是离散类别回归任务输出多个标签多标签分类输出带置信度的异常分数异常检测输出目标框目标检测这些输出形态在 Model Zoo 里覆盖不全。特别是回归任务和多标签分类基本找不到现成的。你得自己设计输出层和损失函数然后重新训练。2.4 需要持续迭代和增量学习产品上线之后数据分布会漂移用户行为会变化这时候你需要更新模型。如果用的是 Model Zoo 里的固定模型你只能重新训练整个网络。但如果你自己设计的网络结构你可以只更新最后几层迁移学习用增量学习的方式逐步更新针对特定用户做个性化微调这些能力在 Model Zoo 的固定模型上是很难实现的。所以如果你的产品需要长期迭代自己设计模型是更合理的选择。3. 自己设计模型的完整流程和实操要点好假设你已经决定要自己设计模型了。接下来我按实际项目流程从数据准备到部署上线一步一步讲清楚每个环节该怎么做、要注意什么。3.1 数据采集和预处理决定模型上限的关键一步很多人一上来就想着用什么网络结构其实数据质量才是决定模型上限的关键。你喂给模型的数据如果噪声大、标注不准、分布不均衡再好的网络结构也救不回来。数据采集阶段要注意几点采样率要足够根据奈奎斯特采样定理采样率至少是信号最高频率的两倍。但实际项目中我建议留 2.5 到 3 倍的余量因为抗混叠滤波器不是理想的。标注要一致如果是分类任务标注标准要统一。我见过一个项目两个人标注同一批数据一个人把“快速行走”标成“跑步”另一个人标成“走路”最后模型怎么训都训不好。要覆盖边缘情况不能只采集“正常”数据异常情况、边界情况都要有。比如做跌倒检测不能只采集跌倒和静止还要采集坐下、弯腰、快速蹲下这些容易混淆的动作。预处理阶段我通常会把数据分成三个部分训练集用来训练模型参数验证集用来调超参数和早停测试集用来最终评估绝对不能参与训练过程比例上我一般用 70/15/15 或者 80/10/10。如果数据量很大测试集可以小一点如果数据量小就要用交叉验证。归一化也是关键。我习惯把输入数据归一化到 [-1, 1] 或者 [0, 1] 区间。具体用哪个取决于激活函数。如果用 tanh就用 [-1, 1]如果用 ReLU就用 [0, 1]。归一化的参数均值和方差要从训练集算出来然后应用到验证集和测试集不能各自算各自的。注意归一化参数要保存下来部署的时候要用同样的参数做预处理。我见过有人训练时归一化了部署时忘了结果模型输出完全不对。3.2 网络结构设计从简单开始逐步加复杂度设计网络结构的时候我的原则是从简单开始逐步加复杂度。不要一上来就搞很深的网络先用一个浅层的、参数量小的网络跑一版基线看效果怎么样。如果不够再逐步加深、加宽。对于嵌入式 AI 场景我常用的几种轻量级结构深度可分离卷积把标准卷积拆成深度卷积和逐点卷积参数量和计算量都能大幅降低。MobileNet 系列就是基于这个思想。瓶颈结构先用 1x1 卷积降维再用 3x3 卷积再用 1x1 卷积升维。ResNet 的 bottleneck 就是这个结构。分组卷积把输入通道分成几组每组单独卷积。ShuffleNet 用了这个思想。注意力机制轻量级的通道注意力比如 SE 模块可以小幅增加参数量但显著提升精度。具体选哪种要看你的任务复杂度和算力预算。我一般会先试深度可分离卷积如果精度不够再加注意力如果还不够就加深网络。网络深度方面对于大多数嵌入式任务5 到 15 层就够了。再深的话参数量和计算量都会上去而且容易过拟合。我做过一个音频分类的项目最后用的网络只有 8 层参数量 30KB在 STM32F4 上跑到了 92% 的准确率。3.3 训练和量化让模型能在 MCU 上跑起来训练模型的时候我建议用 Python 生态PyTorch 或者 TensorFlow 都可以。PyTorch 更灵活适合做实验TensorFlow 的部署工具链更成熟特别是 TFLite Micro 和 STM32Cube.AI 的配合。训练过程中要注意学习率调度不要用固定学习率用余弦退火或者阶梯下降。我一般初始学习率设 0.001然后每 20 个 epoch 降一半。正则化Dropout 和权重衰减都要用。Dropout 比例一般 0.2 到 0.5权重衰减一般 1e-4 到 1e-5。早停验证集损失连续几个 epoch 不下降就停避免过拟合。训练完之后最关键的一步是量化。MCU 上一般用 int8 量化把 float32 的权重和激活值转成 int8。量化之后模型大小能缩小到原来的四分之一推理速度也能提升两三倍。量化的关键是校准。你需要拿一批代表性数据跑一遍统计每一层的激活值范围然后确定量化参数。校准数据要从训练集里选不能太少一般几百到几千个样本就够了。STM32Cube.AI 支持从 Keras、TensorFlow Lite、ONNX 等格式导入模型然后自动做量化。但我建议先在 Python 里用量化工具比如 TFLite 的 post-training quantization做一版看看精度损失有多大。如果精度损失在 1% 以内就可以接受如果损失太大就要考虑量化感知训练。3.4 部署和优化从模型到固件的最后一公里模型量化完之后用 STM32Cube.AI 转换成 C 代码然后集成到你的工程里。这一步有几个坑要注意内存分配Cube.AI 会生成一个内存池用来存放中间激活值。这个内存池的大小要跟你的 RAM 预算匹配。如果太大就要裁剪网络或者用外部 RAM。推理时间Cube.AI 会给出每一层的计算量估计。你可以根据这个来优化网络结构把计算量大的层放在前面或者后面减少中间激活值的内存占用。硬件加速STM32H7 系列有硬件 FPU 和 DSP 指令可以加速浮点运算。但如果你用量化后的 int8 模型就要用 CMSIS-NN 库来加速。CMSIS-NN 对卷积、全连接、池化等操作都有优化实现。我一般会在部署之后做一个性能剖析看看每一层花了多少时间。如果某一层特别慢就针对性地优化。比如把 3x3 卷积换成两个 1x3 和 3x1 的卷积计算量能降低三分之一。4. 常见问题与排查技巧实录这一部分我整理了几个实际项目中经常遇到的问题以及我的排查思路和解决方法。4.1 模型在 PC 上精度很高部署到 MCU 上就不行了这是最常见的问题。原因通常有几个量化误差int8 量化的精度损失。排查方法在 PC 上模拟量化看精度掉多少。如果掉太多就要做量化感知训练。预处理不一致PC 上的预处理和 MCU 上的预处理不一样。排查方法把 MCU 上的预处理结果打印出来跟 PC 上的对比。数据格式问题比如 PC 上是 float32MCU 上是 int8转换的时候出了错。排查方法检查每一层的输入输出范围。我遇到过一次PC 上准确率 95%MCU 上只有 60%。查了半天发现是归一化参数搞错了PC 上用的是训练集的均值和方差MCU 上用的是 0 和 1。改过来之后MCU 上准确率恢复到 94%。4.2 推理时间太长满足不了实时性要求推理时间太长通常是因为网络太深或者计算量太大。排查思路用 Cube.AI 的分析工具看每一层的计算量和内存占用找出计算量最大的几层针对性优化如果还是不行就裁剪网络或者降低输入分辨率我做过一个图像分类的项目输入是 96x96 的灰度图网络有 12 层在 STM32F4 上跑一次要 200ms。后来把输入降到 64x64网络减到 8 层推理时间降到 45ms准确率只掉了 2%。4.3 模型太大Flash 和 RAM 都不够用模型太大通常是因为参数量太多。排查思路参数量统计用工具统计每一层的参数量找出参数量最大的几层剪枝把不重要的权重置零然后稀疏存储知识蒸馏用大模型教小模型让小模型达到接近大模型的精度换更轻量的结构比如把标准卷积换成深度可分离卷积我一般会先试剪枝如果剪枝之后精度掉太多就换更轻量的结构。知识蒸馏比较复杂一般用在精度要求很高的场景。4.4 常见问题速查表问题现象可能原因排查方法解决方案PC 精度高MCU 精度低量化误差、预处理不一致模拟量化、对比预处理量化感知训练、统一预处理推理时间太长网络太深、计算量大逐层分析计算量裁剪网络、降低分辨率模型太大参数量多统计每层参数量剪枝、换轻量结构输出不稳定输入噪声大、归一化问题检查输入数据范围增加滤波、重新归一化内存不够中间激活值太大查看内存池大小减少 batch size、用外部 RAM5. 我的实际项目经验总结最后分享几个我在实际项目里踩过的坑和总结的经验。第一个经验不要过早优化网络结构。我一开始做嵌入式 AI 的时候总想着一步到位设计一个完美的网络。结果花了两周设计了一个很复杂的结构训练出来精度还不如一个简单的 5 层 CNN。后来我学乖了先用简单结构跑基线然后逐步改进效率高很多。第二个经验数据比模型重要。我做过一个电机故障诊断的项目一开始在模型结构上花了很多时间精度一直上不去。后来花了一周时间重新采集数据、清洗数据、做数据增强精度直接提升了 15 个百分点。所以如果你精度不够先看看数据有没有问题再考虑改模型。第三个经验量化不是万能的。int8 量化确实能大幅减小模型体积和推理时间但不是所有模型都适合量化。有些模型对量化很敏感量化之后精度掉很多。这时候可以考虑混合量化只量化部分层或者用 float16 量化。第四个经验部署之后要持续监控。模型上线之后要收集实际运行数据看精度有没有下降、推理时间有没有波动。如果发现问题要及时更新模型。我一般会在固件里加一个简单的统计模块记录推理结果的分布定期回传分析。第五个经验工具链要熟悉。STM32Cube.AI 和 CMSIS-NN 是 ST 生态里最重要的两个工具。Cube.AI 负责模型转换和代码生成CMSIS-NN 负责底层加速。这两个工具用熟了部署效率能提升很多。我建议花点时间读一读 CMSIS-NN 的源码了解它怎么优化卷积和全连接这样你在设计网络的时候就能有针对性地选择结构。回到最初的问题ST 已经有 Model Zoo 了我们还需要自己设计模型吗我的答案是Model Zoo 是起点不是终点。它能帮你快速验证想法、建立基线但真正要做出有竞争力的产品你几乎一定需要自己设计模型。这个投入是值得的因为只有你自己设计的模型才能真正贴合你的数据、你的算力、你的产品需求。