ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ESP-DL 端侧自学习整图分类示例:基于原型网络的免重训练本地分类方案

2026/9/19 23:57:33 拓冰建站 浏览量
ESP-DL 端侧自学习整图分类示例:基于原型网络的免重训练本地分类方案 物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载导读本文围绕 esp-iot-solution 仓库中的 self_learning_classification 示例系统讲解如何在 ESP32-P4 / ESP32-S31 上基于 ESP-DL 框架实现端侧、离线、免重训练的整图分类。该方案通过 MobileNetV2 特征提取器把图像映射为特征向量由用户直接在设备上录入样本、存储特征原型再以最近邻匹配完成分类无需云端参与。读完本文你将掌握该示例的硬件/软件要求、构建烧录流程、交互操作方式以及SelfLearningClassifier的源码级实现原理与调优手段可直接将其复用到固定视角、固定背景的物体/类别识别场景中。示例定位免重训练的自学习分类传统嵌入式视觉分类需要离线收集数据集、训练模型、量化并重新部署固件迭代周期长。而本示例采用原型网络Prototype Network思路把“训练”搬到设备端预训练好的 MobileNetV2 只负责把输入图像编码成 1280 维的特征向量见 imagenet_cls.cpp用户点击“Record”按钮即可把当前画面作为某类别的样本录入设备点击“Recog”按钮设备将当前画面的特征向量与已录入的特征原型逐一比对输出类别与置信度。整个过程不需要重训练模型、不需要云端服务分类依据完全来自设备本地记录的样本特征因此特别适合相机视角与背景相对固定的场景例如固定工位上的物体/类别识别、固定拍摄区域内的物品区分。原文档特别强调为了获得最佳识别效果录入enroll与识别recog之间的环境条件应尽量保持一致包括光照强度与色温illumination/color temperature相机曝光与白平衡设置exposure/white balance物体距离与尺度object distance/scale摆放角度placement angle。工作原理从分类头到特征向量本示例的核心思想是“去掉分类头只留特征”。在模型量化部署阶段官方教程对应的 quantize_torch_model.py 脚本 中MobileNetV2 的分类层被替换为恒等映射使网络只输出特征向量model torchvision.models.mobilenet.mobilenet_v2( weightsMobileNet_V2_Weights.IMAGENET1K_V1 ) model.classifier torch.nn.Identity()这样做的好处是特征向量是“通用描述符”不绑定任何预定义类别因此可以在设备端任意新建类别、动态扩展。后续识别时只需将当前图像的特征向量与已录入的特征向量做距离比较即可完成本地分类。模型量化与部署的整体流程遵循 How to deploy MobileNetV2 教程的步骤。在仓库中量化部署后的模型文件位于 components/imagenet_cls/model/p4/imagenet_cls_mobilenetv2_s8_v1.espdl由 imagenet_cls.cpp 封装为MobileNetV2FeatureExtractor类加载执行。从运行日志可知该模型的特征维度为 1280I (2703) self_learning: SelfLearningClassifier created, feature dim: 1280, max prototypes/class: 7特征提取器的预处理细节imagenet_cls.cpp 中创建模型时同步配置了 ImageNet 风格的标准化参数m_image_preprocessor new dl::image::ImagePreprocessor(m_model, {123.675, 116.28, 103.53}, // mean {58.395, 57.12, 57.375}); // std每次推理时按preprocess → model run → output assign三步执行imagenet_cls.cpp并借助DL_LOG_INFER_LATENCY_*宏统计各阶段耗时。此外模型在构造后调用了m_model-minimize()删除推理不需要的中间变量日志中会出现对应提示W (2701) dl::Model: Minimize() will delete variables not used in model inference, which will make it impossible to test or debug the model.软硬件要求支持的芯片与 ESP-IDF 版本目标芯片ESP-IDF 要求ESP32-P4release/v5.5 及更高版本ESP32-S31需要 ESP-IDF master 分支并以预览目标方式配置idf.py --preview set-target esp32s31开发环境按 ESP-IDF 编程指南搭建建议先完成“Build Your First Project”示例确认工具链正常后再构建本工程。对应目标的默认配置保存在仓库的 sdkconfig.defaults.esp32p4 与 sdkconfig.defaults.esp32s31 中。开发板与硬件连接本示例支持以下两种开发板ESP32-S31-Korvo板载 DVP 摄像头、800×480 RGB LCD 以及 GT1151 触摸面板ESP32-P4-Function-EV-Board搭配 MIPI-CSI 摄像头SC2336与 1024×600 MIPI-DSI LCDEK79007。将摄像头和 LCD 连接到开发板后用 USB-C 线连接USB-UART端口到 PC即可同时完成供电与串口日志输出。从运行日志中可以看到典型的外设初始化序列README.md 中的示例输出MIPI DSI PHY 上电、EK79007 面板初始化、GT911 触摸芯片探测、SC2336 传感器识别以及 MIPI-CSI 视频流建立。构建、烧录与监视在终端中执行将PORT替换为开发板实际串口名idf.py -p PORT flash monitor该命令会依次完成编译、烧录并打开串口监视器查看串口输出退出串口监视器请按Ctrl-]。本工程共用的配置项定义在 sdkconfig.defaults 中包括16MB 外部 Flash、自定义分区表partitions.csv分区表偏移 0x9000、开启 PSRAM 及 PSRAM XIPCONFIG_SPIRAM_XIP_FROM_PSRAMy、FreeRTOS 时钟节拍 1000Hz、LVGL Montserrat 20/30 号字体等。其中CONFIG_SPIRAMy与CONFIG_SPIRAM_XIP_FROM_PSRAMy对端侧视觉应用至关重要——大尺寸模型与特征缓存依赖 PSRAM 空间。运行与交互录入与识别示例默认预留5 个类别用于识别。程序启动后LCD 上实时显示摄像头画面由display_task以约 50fps 的节拍刷新见 app_classifier.cpp。界面交互通过三个控件完成app_classifier.cpp控件作用ui_ClassRoller滚轮选择当前要录入的类别 IDui_RecordButton点击后将当前画面作为样本录入到选中类别ui_RecogButton点击后对当前画面执行识别并显示结果事件驱动的工作流程App 层使用 FreeRTOS 事件组把 UI 点击与识别任务解耦app_classifier.cpp按下Record→ 设置RECORD_BIT事件位按下Recog→ 设置RECOG_BIT事件位recognition_task在独立的 CPU 核心上阻塞等待事件xEventGroupWaitBits收到事件后从摄像头取一帧 RGB565 图像构造dl::image::img_t交给分类器的enroll()或predict()。识别结果会叠加显示在预览画面上当class_id 0时显示Class %d %.0f%%类别号与置信度否则显示Unknown。录入的样本越多识别准确率越高。类别识别仅在置信度大于等于80%默认阈值定义于 self_learning_classifier.cpp时才被接受否则视为无有效类别匹配class_id -1。分类器源码解析SelfLearningClassifier分类核心类 SelfLearningClassifier 是一个基于原型网络的 few-shot 自学习分类器对外暴露三个核心接口SelfLearningClassifier(const char *model_name, int max_prototypes 7); void enroll(const dl::image::img_t img, int class_id); PredictResult predict(const dl::image::img_t img);其中PredictResult结构体包含struct PredictResult { int class_id; /// 预测类别 ID-1 表示未知 float distance; /// 到最近原型的距离 float confidence; /// 置信度0~100% };录入流程enrollenroll() 的执行链路为调用特征提取器run()得到 1280 维特征向量对特征做L2 归一化normalize使用dl::math::sqrt_newton计算范数见 self_learning_classifier.cpp若该class_id首次出现则创建新类别日志打印Created new class %d通过add_prototype()将特征加入类别原型集合。原型集合的管理策略每个类别最多保存max_prototypes默认7个特征原型。当样本数未超过上限时直接追加超过上限后add_prototype()self_learning_classifier.cpp采用多样性替换策略找到与该新特征距离最近的原型若新特征与最近原型的距离大于当前类内平均距离的 0.6 倍min_dist cat-avg_intra_dist * 0.6f说明新样本携带了额外信息则替换该原型从而控制原型数量、提升类内覆盖度否则丢弃新样本不改变原型集合。每次录入后都会重算类内平均距离avg_intra_dist所有原型两两欧氏距离的均值该指标在替换决策与日志观测中都很有用。从日志可以看到录入过程中avg_intra_dist随样本数增长而上升并趋于稳定I (7869) self_learning: Created new class 0 I (7869) self_learning: Enrolled to class 0: 1/7 prototypes, 1 total samples, avg_intra_dist0.0000 I (9384) self_learning: Enrolled to class 0: 2/7 prototypes, 2 total samples, avg_intra_dist0.3002 I (10791) self_learning: Enrolled to class 0: 3/7 prototypes, 3 total samples, avg_intra_dist0.4023 ... I (17778) self_learning: Enrolled to class 0: 7/7 prototypes, 7 total samples, avg_intra_dist0.5137注意原型数量达到上限7/7后total samples仍会继续累加但原型集合保持不变或按替换策略更新。识别流程predictpredict()) 的执行逻辑为提取并归一化当前图像的特征向量遍历所有类别的所有原型计算欧氏距离同时记录最近距离与次近距离用于置信度计算用最近距离计算相似度分数similarity_score (1 - distance² / 2) × 100并裁剪到 0~100 区间self_learning_classifier.cpp。由于特征已 L2 归一化该式本质上是把余弦相似度映射为百分比置信度若置信度 ≥ 80%返回对应类别否则返回class_id -1Unknown。内存管理细节从源码可见实现者对内存分配有精细考量self_learning_classifier.cpp原型指针数组使用heap_caps_calloc(..., MALLOC_CAP_INTERNAL)分配在内部 RAM保证访问速度每个特征原型本体使用heap_caps_malloc(..., MALLOC_CAP_SPIRAM)分配在 PSRAM因为 1280 维 float 数组约 5KB/个乘以多个类别后总量可观放在 PSRAM 更合理析构函数与free_category()会完整释放所有原型与指针数组避免内存泄漏。应用入口程序入口 self_learning_classification.cpp 的app_main()依次完成app_lcd_init(); auto cam new Camera(VIDEO_PIX_FMT_RGB565, 4, V4L2_MEMORY_MMAP, false); auto classifier new SelfLearningClassifier(imagenet_cls.espdl); auto app new AppClassifier(cam, classifier); app-start();摄像头以 RGB565 格式、4 个 MMAP 帧缓冲采集画面Camera类封装了 V4L2 视频采集、帧缓冲队列、PPA 硬件后处理字节交换/旋转/镜像等能力app_camera.hppAppClassifier::start()将显示任务与识别任务分别固定到两个 CPU 核心实现流水线并行。性能指标README 中给出了本示例实测的延迟数据平均类别录入时间class enrollment750 ms—— 主要消耗在特征提取推理平均距离计算时间distance computation1 ms—— 特征向量比对极快因为每类最多 7 个原型、默认 5 类最坏也只需几十次 1280 维向量点积。若需要更快的端到端推理可以将 MobileNetV2 替换为其他更轻量的分类/主干网络backbone进一步压缩录入与识别延迟。模型选择与部署配置components/imagenet_cls/Kconfig 提供了两组配置选项默认模型FLASH_IMAGENET_CLS_MOBILENETV2_S8_V1默认开启对应imagenet_cls_mobilenetv2_s8_v1模型模型存放位置flash_rodata默认模型以 rodata 形式链接进固件imagenet_cls.cpp 通过_binary_..._start符号引用flash_partition模型放在独立 Flash 分区分区名imagenet_cls。构建时可通过idf.py menuconfig调整上述选项。若启用CONFIG_SPIRAM_RODATA或CONFIG_SPIRAM_XIP_FROM_PSRAM模型会被拷贝到 PSRAM 执行日志中会有对应提示W (2626) FbsLoader: CONFIG_SPIRAM_RODATA or CONFIG_SPIRAM_XIP_FROM_PSRAM option is on, fbs model is copied to PSRAM.完整的运行日志解读README.md 提供了一份完整的启动与交互日志可观察到几个关键阶段启动阶段bootloader 加载固件ESP-IDF v5.5.2-737-...、检测 16MB Flash 与 32MB PSRAM、初始化双核应用外设阶段LVGL 任务启动、MIPI DSI/EK79007 LCD 初始化1024×600、GT911 触摸探测、SC2336 摄像头识别1280×720、MIPI-CSI 视频流建立模型加载阶段FbsLoader将 flatbuffers 模型加载必要时拷贝到 PSRAMdl::Model::Minimize()精简模型分类器就绪打印feature dim: 1280, max prototypes/class: 7交互阶段依次录入类别 0、类别 1 的多个样本原型数、总样本数、类内平均距离逐步更新最后识别输出I (42464) self_learning: Predict: best_class1, dist0.3092, confidence95.2%该行说明当前画面与类别 1 的某个原型距离为 0.3092置信度 95.2%超过 80% 阈值判定为类别 1。调优建议与注意事项置信度阈值默认 80%confidence 80.0f见 self_learning_classifier.cpp。误识别偏高时可以提高阈值漏识别偏高时可以适当降低原型数量max_prototypes默认 7构造函数第二个参数可通过构造函数传入调整。原型越多对类内变化容忍度越高但内存与比对耗时也随之增加类别数量示例默认 5 个类别识别时会遍历所有类别的全部原型做最近邻匹配类别越多单次距离计算时间越长当前约 1ms余量充足环境一致性录入与识别阶段的光照、曝光、白平衡、距离与角度尽量一致这是本方案准确率的决定性因素样本多样性每个类别多录入不同角度/位置的样本让原型覆盖类内变化可显著提升识别鲁棒性硬件选型若追求更低延迟可参考“性能”一节替换更轻量的 backbone 模型并结合 sdkconfig.defaults 中的 PSRAM XIP 配置保持推理带宽。小结self_learning_classification 示例为嵌入式端侧提供了一条“零重训练、即录即用”的分类路径以去分类头的 MobileNetV2 作为通用特征提取器设备端录入样本即生成特征原型识别时以归一化欧氏距离 相似度置信度完成最近邻分类。其核心价值在于把“样本采集—特征存储—类别扩展”全部下沉到本地非常适合固定视角、固定背景的工业工位识别与设备端视觉交互场景也为基于 ESP-DL 的原型网络类应用提供了清晰的可复用代码骨架SelfLearningClassifier。赞分享物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载相关推荐Flax 文本分类实战基于 SST-2 情感分类示例训练 BiLSTM Attention 分类器Flax 文本分类实战基于 SST 2 情感分类示例训练 BiLSTM Attention 分类器 本文围绕 Flax 官方示例 examples/sst人工智能深度学习机器学习MNN 预训练模型 Finetune 实战基于 MobileNetV2 的图像分类迁移学习MNN 预训练模型 Finetune 实战基于 MobileNetV2 的图像分类迁移学习 本文围绕 MNN 训练框架中的 Finetune迁移学习/微调人工智能推理引擎深度学习本地部署大模型使用 PyTorch Lightning 训练图神经网络PyG 官方示例全解析节点分类、图分类与异质图使用 PyTorch Lightning 训练图神经网络PyG 官方示例全解析节点分类、图分类与异质图 导读 本文基于 PyGPyTorch Geome人工智能机器学习深度学习图计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考