
AI-on-the-edge-device 模拟表盘识别参数 CNNGoodThreshold 详解模拟指针 CNN 置信度阈值的配置原理与源码实现【免费下载链接】AI-on-the-edge-deviceEasy to use device for connecting old measuring units (water, power, gas, ...) to the digital world项目地址: https://gitcode.com/GitHub_Trending/ai/AI-on-the-edge-device导读本文聚焦 AI-on-the-edge-device 固件中用于模拟指针式表盘读数的专家级配置参数CNNGoodThreshold讲解其默认值、适用模型范围、在config.ini中的写法以及它在ClassFlowCNNGeneral源码中如何决定一次模拟读数是否被接受、被拒绝。读完本文你将理解置信度阈值在混合型hybrid模拟表盘模型中的真实作用掌握何时以及如何安全地调整该参数并能通过日志与配置实例验证其行为。说明本文面向使用ana-class100100 类输出模拟表盘模型的用户CNNGoodThreshold在数字轮区域dig-class100同样存在但语义一致本文以[Analog]段为主展开。参数速览默认值与适用模型属性值参数名CNNGoodThreshold所属配置段[Analog]也存在于[Digits]默认值0.5参数类型浮点数阈值官方定性Expert Parameter专家参数仅当理解其作用时才修改适用模型仅ana-class100类模型对应源码中的Analogue100类型在官方参数文档 param-docs/parameter-pages/Analog/CNNGoodThreshold.md 中该参数被描述为Threshold above which the classification should be to accept the value分类结果需高于该阈值才接受该读数。仓库默认配置 sd-card/config/config.ini 中[Analog]段给出的真实示例为[Analog] Model /config/ana-cont_1500_s2_q.tflite CNNGoodThreshold 0.5 ;ROIImagesLocation /log/analog ;ROIImagesRetention 3 main.ana1 432 230 92 92 false main.ana2 379 332 92 92 false main.ana3 283 374 92 92 false main.ana4 155 328 92 92 false为什么模拟表盘也需要分类置信度ana-class100模型的工作方式要理解CNNGoodThreshold必须先理解模拟表盘模型在固件中的推理方式。AI-on-the-edge-device 在加载 tflite 模型时会自动探测输出维度并确定 CNN 类型相关逻辑位于 ClassFlowCNNGeneral.cpp 的getNetworkParameter()输出维度为100、且输入尺寸为 32×32 时判定为Analogue100即ana-class100模型输出维度为 2 时判定为旧式Analogue正弦/余弦双输出回归输出维度为 10 时判定为DoubleHyprid10输出维度为 11 时判定为Digit。ana-class100模型的本质是把一个模拟表盘的读数区间离散化为100 个类推理时tflite-GetOutClassification()返回 099 的类别索引随后在 doNeuralNetwork() 的Digit100/Analogue100分支 中换算为 0.010.0 的读数_num tflite-GetOutClassification(); if(GENERAL[n]-ROI[roi]-CCW) { GENERAL[n]-ROI[roi]-result_float 10 - ((float)_num / 10.0); } else { GENERAL[n]-ROI[roi]-result_float (float)_num / 10.0; }即默认每 0.1 读数对应一个类别。但请注意在这个Analogue100分支中代码直接将类别索引换算为读数并硬编码isReject false并未使用CNNGoodThreshold做判定——阈值判定实际发生在另一个分支中见下文。阈值判定的真正位置DoubleHyprid10分支尽管参数文档标注仅ana-class100模型支持但源码中CNNGoodThreshold的实际消费点位于doNeuralNetwork()的DoubleHyprid10分支ClassFlowCNNGeneral.cpp。这也印证了官方文档中只对数字类读数有意义only meaningful for digits的表述——DoubleHyprid10是 10 类数字 亚像素插值的混合模型其推理流程为_num tflite-GetOutClassification(0, 9); // 主分类0~9 中置信度最高的数字 _numplus (_num 1) % 10; _numminus (_num - 1 10) % 10; _val tflite-GetOutputValue(_num); // 主分类的原始输出值 _valplus tflite-GetOutputValue(_numplus); _valminus tflite-GetOutputValue(_numminus); float result _num; if (_valplus _valminus) { result result _valplus / (_valplus _val); _fit _val _valplus; } else { result result - _valminus / (_val _valminus); _fit _val _valminus; }这里_fit是一个介于 01 之间的拟合置信度由主分类及其相邻数字的模型输出共同合成。随后便是阈值判定的核心逻辑ClassFlowCNNGeneral.cppif (_fit CNNGoodThreshold) { GENERAL[n]-ROI[roi]-isReject true; result -1; _result_save_file 100; // 拒绝时仍保存结果形如 -10x.y string zw Value Rejected due to Threshold (Fit: to_string(_fit) , Threshold: to_string(CNNGoodThreshold) ); LogFile.WriteToFile(ESP_LOG_WARN, TAG, zw); } else { GENERAL[n]-ROI[roi]-isReject false; }由此可以归纳出该参数的真实行为链路模型推理得到主数字类别与相邻数字输出合成_fit若_fit CNNGoodThreshold该 ROI 被标记为isReject true读数置为-1触发ESP_LOG_WARN级日志内容形如Value Rejected due to Threshold (Fit: 0.42, Threshold: 0.500000)可在 logfile 工具或 Web 界面的日志页中检索被拒绝的 ROI 不再参与后续读数汇总后处理PostProcessing阶段会据此产生错误标记。从源码结构看Digit100/Analogue100分支当前并未实现_fit合成与阈值比较因此即使配置了CNNGoodThreshold纯ana-class100/dig-class100模型的分类结果也直接按类别索引接受阈值真正的生效场景是DoubleHyprid1010 类混合模型。这是配置该参数前需要知悉的实现细节。参数解析与默认值初始化CNNGoodThreshold在 ClassFlowCNNGeneral.h 中声明为成员变量float CNNGoodThreshold;其初始化与解析位于 ClassFlowCNNGeneral.cpp 的ReadParameter()if ((toUpper(splitted[0]) CNNGOODTHRESHOLD) (splitted.size() 1)) { if (isStringNumeric(splitted[1])) { CNNGoodThreshold std::stof(splitted[1]); } }解析要点键名不区分大小写toUpper归一化后比较故CNNGoodThreshold、cnngoodthreshold均可仅当值是合法数字时才写入非法值会被静默忽略保持上一次赋值解析入口同时覆盖[ANALOG]、[DIGIT]、[DIGITS]三个段落见 ReadParameter 的段落匹配因此[Digits]段同样可以配置该参数若段落以;开头注释掉整个段该 CNN 通道将被整体禁用disabled true参数自然不生效。配置入口与 UI 支持该参数在 Web 配置界面中同样可见可改前端渲染[sd-card/html/readconfigparam.js](https://link.gitcode.com/i/7a87d97882af7af8cd19193d19f41b96)中通过ParamAddValue(param, catname, CNNGoodThreshold, 1)注册该参数编辑表单[sd-card/html/edit_config_template.html](https://link.gitcode.com/i/26ea99c19721216d8b4bffd7cac03889)为数字段Digits_CNNGoodThreshold提供了typenumber输入框并约束取值范围min0 max1 step0.1即合法区间为0.01.0步长 0.1读写逻辑同文件中WriteParameter(...)与ReadParameter(...)负责将该参数写入/读回config.ini。CNNGoodThreshold同时也被列入 param-docs/expert-params.txt第 31 行意味着它在 UI 中会被标记为专家参数默认对普通用户隐藏。如何安全地调整CNNGoodThreshold结合默认配置与源码行为给出可落地的调参建议先确认你的模型类型只有ana-class100[Analog]段与dig-class100[Digits]段模型才支持该参数旧式ana-cont_*连续回归模型输出维度为 2不适用。当前仓库默认配置 sd-card/config/config.ini 中[Analog]使用的正是ana-cont_1500_s2_q.tflite属连续回归模型其CNNGoodThreshold条目不参与阈值判定[Digits]段默认使用dig-cont_0900_s3_q.tflite亦同。若要让该参数实际生效需要切换到 100 类输出的模型如sd-card/config/下提供的dig-class100-*.tflite系列并在[Analog]/[Digits]段中修改Model路径。从默认值 0.5 开始观察保持CNNGoodThreshold 0.5运行若干轮读表在日志中检索Value Rejected due to Threshold。如果几乎不出现该日志说明当前读数置信度普遍高于 0.5如果频繁出现说明表盘图像质量差或 ROI 框选不准。按需微调0.01.0Web 界面允许的范围为 0.01.0步长 0.1。提高阈值 → 更多读数被拒绝更保守宁缺毋滥降低阈值 → 更多读数被接受更激进但误读风险上升。修改后需保存并重启固件使参数重新解析生效。结合 ROIImagesLocation 调试开启ROIImagesLocation/ROIImagesRetention记录 ROI 图像配合日志判断被拒绝是因为阈值过高还是 ROI 本身框错了位置。小结CNNGoodThreshold是 AI-on-the-edge-device 中控制模拟/数字读数接受与否的置信度闸门默认值 0.5取值范围 0.01.0仅对ana-class100/dig-class100类模型有意义属于 UI 中默认隐藏的专家参数。其判定逻辑由ClassFlowCNNGeneral::doNeuralNetwork()中DoubleHyprid10分支的_fit合成值与阈值比较完成拒绝时读数置-1并写入Value Rejected due to Threshold警告日志。实际部署中建议先确认模型类型再结合日志与 ROI 图像决定是否以及如何微调该参数从而在读数缺失与误读数之间取得平衡。【免费下载链接】AI-on-the-edge-deviceEasy to use device for connecting old measuring units (water, power, gas, ...) to the digital world项目地址: https://gitcode.com/GitHub_Trending/ai/AI-on-the-edge-device创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考