基于Keras构建模型并部署到STM32F4的完整指南
基于 Keras 构建模型并部署到 STM32F4 的完整指南概述将基于 Keras 构建的模型部署到 STM32F4 微控制器上属于典型的 TinyML微型机器学习应用。由于 STM32F4 的硬件资源如 Flash 和 RAM相对有限无法直接运行完整的深度学习模型必须经过模型转换、量化压缩以及 C 代码生成等一系列步骤。本文档涵盖以下三个阶段阶段一PC 端使用 Keras 构建与训练模型Python 正弦函数模拟数据阶段二模型压缩为 INT8 并转换为 C 代码阶段三不使用 STM32CubeMX手工搭建 STM32F4 工程并部署下面是整个部署流程的概览图PC 端Keras 构建与训练模型模型保存为 .h5 文件NNoM 量化压缩为 INT8生成 C 代码net.c / weights.h手工搭建 STM32F4 工程编写业务逻辑main.c部署到 STM32F4 并推理阶段一PC 端生成数据与 Keras 模型训练1.1 环境准备在 Python 环境中安装以下依赖numpytensorflow包含 Keras1.2 生成带噪声的正弦数据使用正弦函数加高斯噪声模拟真实传感器数据importnumpyasnp np.random.seed(42)Xnp.linspace(0,2*np.pi,1000)ynp.sin(X)np.random.normal(0,0.05,X.shape)# 加入高斯噪声1.3 构建轻量级模型为了适应 MCU 的低资源特性精简隐藏层神经元数量选择轻量级架构fromtensorflowimportkerasfromtensorflow.keras.modelsimportSequentialfromtensorflow.keras.layersimportDense modelSequential([Dense(16,activationrelu,input_shape(1,)),# 隐藏层16个节点Dense(1)# 输出层])model.compile(optimizeradam,lossmse)model.fit(X,y,epochs100,batch_size32,verbose1)1.4 模型保存训练完成后将模型保存为 Keras 原生格式model.save(sine_model.h5)阶段一的完整流程如下生成带噪声的正弦数据构建轻量级 Keras 模型训练模型保存为 sine_model.h5阶段二模型 INT8 量化与 C 代码转换2.1 量化原理STM32F4 的 FPU 处理浮点较慢且 Flash/RAM 有限必须将模型量化为 INT8 并转为 C 代码。INT8 量化将模型权重和激活值从 32 位浮点数FP32转换为 8 位整数INT8。这通常可使模型体积减小 75% 以上并大幅降低内存占用和功耗。量化感知训练在训练或转换过程中模拟量化操作以尽量保持模型在低精度下的准确率。2.2 使用 NNoM 进行量化与代码生成推荐使用轻量级开源框架NNoM它专为 MCU 设计支持 Keras 模型一键转 C 代码。安装 NNoMpipinstallnnom量化与导出代码importnnomimporttensorflowastf# 加载模型modeltf.keras.models.load_model(sine_model.h5)# 使用 NNoM 进行 INT8 量化并导出 C 代码nnom_modelnnom.NNoM(model)nnom_model.build(representative_dataX[:100])# 传入部分真实数据用于校准量化参数nnom_model.save(nnom_sine_model)# 生成 weights.h, net.h, net.c 等文件说明生成的weights.h包含了量化后的权重数组net.c包含了推理逻辑。阶段二的量化与代码生成流程如下加载 Keras 模型.h5NNoM 构建模型传入校准数据X[:100]INT8 量化导出 C 代码weights.h / net.c阶段三STM32F4 端手工搭建工程与部署不使用 STM32CubeMX采用“古法”纯手工搭建工程可以让你完全掌控代码的每一个细节。以 STM32F407 为例。3.1 规划工程目录结构在电脑上新建一个无中文、无空格的文件夹创建以下目录STM32F4_Sine_AI/ ├── 01_MDK-ARM/ # Keil工程文件(.uvprojx) ├── 02_User/ # main.c 等用户业务代码 ├── 03_CMSIS/ # Cortex-M4内核文件 (core_cm4.h 等) ├── 04_Device/ # STM32F4专属文件 (启动文件, system_stm32f4xx.c) ├── 05_NNoM_Lib/ # 放入 NNoM 生成的 net.c, net.h, weights.h 及 NNoM 核心源码 └── 06_HAL_Driver/ # (可选) 如果不用寄存器可放入标准外设库/HAL库3.2 提取底层核心文件从 ST 官方的STM32CubeF4固件包中提取以下文件到对应目录文件用途存放目录startup_stm32f407xx.s启动文件04_Devicesystem_stm32f4xx.c和.h系统时钟文件04_Devicecore_cm4.h、cmsis_compiler.h等CMSIS 核心03_CMSISstm32f4xx.h,stm32f407xx.h设备头文件04_Device3.3 Keil 工程配置魔术棒设置Target 选项卡选择芯片型号如 STM32F407ZGT6勾选Use MicroLIBNNoM 依赖标准 C 库的内存分配C/C 选项卡Define 中添加宏定义STM32F407xx, USE_STDPERIPH_DRIVER若使用了标准库Include Paths 添加所有头文件所在的路径优化等级选择-O2或-O3并勾选C99 Mode添加文件到工程在 Keil 左侧 Project 树中建立对应的 Group将上述提取的.c文件、启动文件以及 NNoM 生成的net.c全部添加进去。3.4 编写业务逻辑main.c在main.c中初始化系统时钟并调用 NNoM 的推理接口#includestm32f4xx.h#includenet.h// NNoM 生成的头文件#includeweights.h// NNoM 生成的权重头文件#includestdio.hintmain(void){// 1. 初始化系统时钟 (可调用 SystemInit() 或手动配置 RCC 寄存器)SystemInit();// 2. 初始化 NNoM 模型nnom_model_t*modelnnom_model_create();// 3. 准备输入数据 (例如输入 PI/2期望输出接近 1.0)floatinput_val1.57f;int8_tq_input;// 注意需要根据 NNoM 生成的量化参数将 float 转为 int8q_input(int8_t)(input_val/model-in-tensor-q_scale)model-in-tensor-q_zero_point;// 4. 执行推理memcpy(model-in-tensor-p_data,q_input,sizeof(int8_t));nnom_predict(model);// 5. 获取并反量化输出结果int8_tq_output((int8_t*)model-out-tensor-p_data)[0];floatresult(q_output-model-out-tensor-q_zero_point)*model-out-tensor-q_scale;// result 即为模型预测的 sin(PI/2) 的值while(1){// 可以在这里通过串口打印 result或控制 LED}}阶段三的工程搭建与部署流程如下规划工程目录结构提取底层核心文件Keil 工程配置魔术棒设置添加文件到工程编写业务逻辑main.c编译、烧录并验证推理结果核心注意事项4.1 内存分配神经网络推理需要大量临时内存务必在启动文件.s中将 Stack 和 Heap 调大例如 Stack0x1000Heap0x2000否则极易发生 HardFault。4.2 量化对齐NNoM 在导出时会生成量化参数Scale 和 Zero-point在 C 端喂入数据和读取数据时必须严格按照这些参数进行浮点与定点的转换。总结与建议对于 STM32F4建议采用Keras 训练 INT8 量化 NNoM 生成代码的工作流。这条路径不仅避开了复杂的底层算子移植还能充分利用开源框架的轻量化优势是落地稳定且开发效率较高的选择。扩展方向可根据具体应用场景如语音唤醒、手势识别、传感器分类等设计更合适的轻量级模型结构并进一步优化量化策略与推理性能。整体工作流总结如下STM32F4 端PC 端Keras 训练INT8 量化NNoM 生成 C 代码手工搭建工程编写 main.c部署与推理

相关新闻

【在线五子棋对战】数据管理模块实现

【在线五子棋对战】数据管理模块实现

目录 表结构 Register Login SelectByName SelectById SelectOne WIn Lose 数据管理模块用于对登录与注册用户进行管理,这里采用以表为单位,每个可操作的表为一个类,构建该表的接口 表结构 用于存储用户的表为gomoku数据库下的user…

2026/9/24 17:16:23 阅读更多 →
河北智能装备工厂SolidWorks研发—一台服务器共享给10个设计用

河北智能装备工厂SolidWorks研发—一台服务器共享给10个设计用

针对河北某智能装备工厂 10 名 SolidWorks 设计师研发需求,以高性能图形服务器 云飞云共享云桌面搭建私有化部署方案,将算力、软件、图纸集中池化,实现 10 位工程师共用一台服务器并发开展三维设计。兼顾大装配流畅操作、图纸安全管控、软硬…

2026/9/24 17:16:22 阅读更多 →
SDR++ 零基础上手指南:15 分钟跑通你的软件定义无线电

SDR++ 零基础上手指南:15 分钟跑通你的软件定义无线电

SDR 零基础上手指南:15 分钟跑通你的软件定义无线电 【免费下载链接】SDRPlusPlus Cross-Platform SDR Software 项目地址: https://gitcode.com/GitHub_Trending/sd/SDRPlusPlus 深夜里你随手调到一个频率,飞行员平稳的声音突然传进耳朵——这就…

2026/9/24 17:16:22 阅读更多 →

最新新闻

从设计到落地:手把手教你写一个好用的Agent Skill

从设计到落地:手把手教你写一个好用的Agent Skill

写 Agent Skill 这事儿,我从去年开始反复折腾。先说结论:好用的 Skill 不是“一段能跑的脚本”,而是一套把边界、输入输出、错误处理、提示词节奏都提前定义好的小系统。Model 再聪明,也扛不住糊里糊涂的调用方式,真正…

2026/9/24 20:10:32 阅读更多 →
构建Agent Skill专项评估系统:从量化指标到工程化实践

构建Agent Skill专项评估系统:从量化指标到工程化实践

先说一个我最近特别深的感受:GitHub 上 Skill 类项目越来越多,Claude Code、Codex、Cursor 这些 Agent 工具也都开始支持加载自定义 Skills,但真正能把“某个 Skill 到底有没有用、值不值得装、会不会把别的任务搞坏”说清楚的项目&#xff0…

2026/9/24 20:10:32 阅读更多 →
Jiagu中文NLP工具包:轻量级分词、词性、NER与依存分析一体化方案

Jiagu中文NLP工具包:轻量级分词、词性、NER与依存分析一体化方案

简介:本资源是基于Python开发的Jiagu深度学习自然语言处理工具完整源码包,面向NLP初学者、算法工程师及中文文本分析实践者,提供开箱即用的工业级中文NLP能力支持。包内共30个文件,含15个核心Python脚本(覆盖分词、词性…

2026/9/24 20:10:32 阅读更多 →
Jiagu:轻量级中文NLP工具链实战指南

Jiagu:轻量级中文NLP工具链实战指南

简介:本资源是一套基于Python实现的Jiagu深度学习自然语言处理工具完整源码,面向NLP初学者、高校学生及中文文本分析开发者,提供开箱即用的轻量级中文NLP解决方案。包内共30个文件,含15个核心Python脚本(覆盖分词、词性…

2026/9/24 20:10:32 阅读更多 →
分布式能源管理物联网系统落地指南:从MQTT到负荷预测的完整架构

分布式能源管理物联网系统落地指南:从MQTT到负荷预测的完整架构

1. 项目缘起:从一张电费单说起先讲个我去年遇到的事。一个做精密铸造的老板拿着厂里的电费单来找我,问我能不能帮他看看怎么回事。那张单子上,基本电费占比高得离谱,而且每个月峰段用电量都顶在容量上限附近。细聊才知道&#xff…

2026/9/24 20:10:32 阅读更多 →
家庭WiFi安全自检指南:用Kali与aircrack-ng验证防护水位

家庭WiFi安全自检指南:用Kali与aircrack-ng验证防护水位

我不能按照您的要求生成涉及非法入侵、未经授权的网络访问或密码破解相关内容的博文。根据中国法律法规及网络安全法,未经授权对他人网络设备、无线路由器或任何信息系统进行渗透测试、密码破解、流量劫持等行为,属于违法行为。即使针对“自己家的WiFi”…

2026/9/24 20:09:32 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →