智能花园 · 2026/5/24
把花园摄像头变成可迭代的小模型:一次薄荷/月季识别纠错复盘
从本地采集、AI 初标、人工复核、平衡训练、ONNX 导出到树莓派部署,记录一次把薄荷误判为月季的问题修正为可迭代闭环的过程。
把花园摄像头变成可迭代的小模型:一次薄荷/月季识别纠错复盘
这次优化的起点很具体:一张明明是薄荷的照片,被设备端小模型识别成了月季。单看这件事,它像是一次普通的分类错误;但如果把它放到真实部署环境里看,它暴露的是整条链路的问题:数据从哪里来、标签是否可信、训练集是否平衡、模型输入和线上推理是否一致、部署状态是否能被页面准确反映。
最后我们把这条链路补成了一个更可靠的闭环:本地和树莓派照片合并、人工标签优先、类别平衡、绿色植物区域裁剪、ONNX 导出、通过 GardenHome 中心下发部署,并用历史照片重跑验证。
这次具体改进了什么
1. 停止继续盲目采集,先冻结训练数据
照片数量已经足够时,继续自动采集不一定带来提升,反而可能持续引入未复核样本。我们先停止自动采集流水线,把数据集冻结下来,再做标签清洗和训练。
这一步听起来朴素,但很关键。训练模型不是“越多照片越好”,而是“越多正确、均衡、覆盖真实场景的照片越好”。
2. 只把人工确认的 plant_label 当作真实标签
GardenHome 样本里有多个字段。一个很容易踩坑的点是:不要把通用 label 字段当植物类别,因为它可能表达的是图片状态或质量,比如 normal、bad_image。真正可用于植物种类训练的是人工复核后的 plant_label。
同时,旧模型的预测也不能直接当真。预测结果可以帮助我们发现 hard case,但除非经过人工确认,否则不能变成训练标签。否则模型会把自己的错误重新吃回去,越训越自信,越自信越错。
3. 合并本地照片和树莓派现场照片
最终训练集同时用了两类数据:本地目录里的原始照片,以及树莓派在真实设备环境中抓拍并已复核的样本。
关键数字如下:
- 树莓派中心端已复核样本:508 张,其中月季 339 张,薄荷 169 张。
- 最终裁剪增强训练集:642 张。
- 薄荷/月季平衡后:各 321 张。
- 数据切分:训练 450 张,验证 128 张,测试 64 张。
- 测试集每类 32 张。
这里最重要的不是 642 这个数,而是“真实部署场景”和“类别平衡”。本地拍摄的干净样本能提供基础特征,树莓派现场样本能提供真实光照、背景、角度和噪声。
4. 做类别平衡,降低模型偏向月季
之前的样本更偏向月季,模型在不确定时更容易猜月季。新版训练集把薄荷和月季平衡到各 321 张,让模型少一点“默认站队”。
这也是很多小模型项目里最容易忽略的地方:准确率低不一定是模型结构差,常常是数据分布在悄悄投票。
5. 加入绿色植物区域裁剪,减少背景干扰
这次我们训练的是绿色植物区域裁剪后的图片,而不是直接把整张图缩到模型输入尺寸。这样可以减少花盆、桌面、墙面、摄像头角度等背景因素对分类的影响。
更重要的是,树莓派运行端也同步加入了同样的绿色区域裁剪预处理。也就是说,训练时模型看到什么,线上推理时也尽量看到相同类型的输入。
树莓派端现在的预处理特征可概括为:
image_128_green_crop_imagenet_normalized
这一步的原则是:训练和部署的预处理必须对齐。只在训练端做增强,线上端不做,验证结果可能很好,真实页面上却继续翻车。
6. 重新训练并导出 ONNX
新模型名为:
mint_rose_v7_cropped_hardcase_128
导出的部署文件包括:
plant_multitask.onnx
plant_multitask.onnx.data
labels.yaml
树莓派端加载后确认:输入尺寸为 128,类别为 mint 和 rose。
7. 通过 GardenHome 中心部署,而不是手工覆盖文件
模型不是简单拷贝到树莓派就结束。我们通过 GardenHome 的模型导入和部署流程完成下发,这样页面状态、中心数据库、部署命令、设备端模型才是一致的。
最终线上模型状态:
模型 ID: 6
名称: mint_rose_v7_cropped_hardcase_128
状态: active
旧模型被标记为 superseded,避免页面上同时出现多个“已启用”模型,让用户误以为设备还在用旧模型。
8. 部署后重跑历史照片
部署完成后,我们下发了历史照片重新识别命令。否则页面上仍可能显示旧模型留下的识别结果,用户看到的就不是当前模型的真实效果。
最关键的错图被纠正:
样本 ID: 3094
样本 key: 20260523-232554-wide_1-wide_1
人工标签: 薄荷
旧问题: 被识别为月季
新版结果: 薄荷
置信度: 约 0.68
这张图虽然已经纠正,但置信度还不是特别高,所以它应该继续留在 hard-case 集合里,作为下一轮训练重点。
验证结果
在本地测试集上,植物种类分类结果为:
薄荷: 32/32
月季: 32/32
species accuracy: 100%
需要注意的是,这个结果只说明当前测试集上的薄荷/月季分类已经很好,不代表未来所有光照、角度、遮挡场景都不会错。真实系统要持续靠 hard case 回流来变稳。
这次得到的几个经验
第一,标签比模型更重要。小模型最怕脏标签,尤其怕把旧模型预测当作新训练真相。
第二,类别平衡比盲目扩充数量更重要。如果多出来的照片集中在一个类别上,模型可能更偏而不是更准。
第三,训练预处理和线上预处理必须一致。裁剪、resize、normalize 这些细节看着不起眼,却经常决定部署后是否翻车。
第四,部署要走产品链路。只有通过中心导入、部署、ack、状态更新、历史重识别,页面看到的结果才可信。
第五,置信度中等的纠错样本很宝贵。它说明模型方向对了,但边界还不够厚,下一轮应该围绕这类样本继续补数据。
下一步可以怎么做
下一轮优化可以专门采集这些场景:
- 同角度、同光照下的薄荷;
- 没有花的月季叶片;
- 背景复杂、花盆明显、叶片遮挡的照片;
- 逆光、夜间、轻微模糊的照片;
- 同一植物的整体图和局部近景。
更进一步,可以把页面里的“人工复核”变成主动学习入口:模型低置信度或与人工标签冲突的照片自动进入复核队列,复核后进入下一轮训练。这样,系统就不只是一个一次性模型,而是一个会在真实花园里越用越稳的小模型闭环。