智能花园 · 2026/5/24
GardenHome 薄荷/月季小模型训练与部署技术记录
记录 GardenHome 薄荷/月季边缘识别小模型从数据清洗、类别平衡、绿色裁剪、ONNX 导出到树莓派部署和历史照片重识别的完整优化过程。
这是一份关于 GardenHome 植物识别小模型的训练复盘。目标很明确:解决一张明显是薄荷的照片被识别为月季的问题,并把这次修正沉淀成后续可重复使用的训练、导出、部署和验证流程。
这次优化不是单纯“多训一次模型”,而是把数据来源、标签可信度、类别平衡、图像预处理、ONNX 导出、树莓派端部署、历史照片重识别等环节一起梳理了一遍。最终新版模型已经部署到设备端,并修正了原来的薄荷误判案例。
背景问题
设备页面中有一张用户确认是薄荷的照片,却被模型识别成了月季。这个错误说明模型在真实环境下对薄荷和月季叶片的边界还不稳,尤其是在下面这些条件下容易偏向月季:
- 训练集中月季样本相对更多,类别分布不平衡。
- 部分样本来自旧模型预测或 teacher 初标,不能直接当作可靠真值。
- 原图里背景、花盆、桌面和摄像头角度会影响模型判断。
- 训练时看到的图像区域和树莓派推理时输入的图像区域不完全一致。
- 页面上的历史识别结果可能来自旧模型,部署新模型后需要重新处理历史照片。
所以,这次处理重点不是换一个更大的模型,而是先把小模型训练链路做扎实。
数据来源
这次综合使用了两类照片:
- 本地采集照片:来自本地训练项目的
data/raw目录,包含薄荷和月季。 - 树莓派现场照片:来自设备端真实抓拍,包含真实光照、背景、角度、模糊和遮挡情况。
树莓派现场照片很重要。干净的本地照片可以帮助模型学习基础特征,但真实部署效果往往取决于现场照片,因为设备看到的不是实验室环境,而是花盆、墙面、自然光、摄像头视角和偶发模糊一起构成的复杂场景。
最终用于本轮训练的数据被整理成平衡后的裁剪数据集:
总数: 642 张
薄荷: 321 张
月季: 321 张
训练集: 450 张
验证集: 128 张
测试集: 64 张
测试集类别分布: 薄荷 32 张,月季 32 张
标签处理原则
这次最重要的原则是:只把人工复核后的植物标签当作训练真值。
在 GardenHome 样本里,不能简单把通用 label 字段当成植物类别。它可能表示图片质量或状态,比如 normal、bad_image。用于植物种类训练的字段应该是人工确认后的 plant_label。
另外,旧模型预测和 teacher 初标都不能直接当作最终标签。它们可以用来提高标注效率,也可以帮助发现 hard case,但不能未经复核就进入最终训练集。否则模型会把自己的旧错误重新学进去,形成“错误自举”。
本轮训练采用的原则是:
plant_label优先作为植物种类真值。- teacher 初标只作为草稿,不作为无条件真值。
- 旧模型预测只用于排查和发现难例,不直接作为标签。
- 明显无效、模糊、主体不清、标签冲突的照片从训练集中剔除。
类别平衡
旧模型偏向月季,一个直接原因是训练数据里月季样本更多。模型在不确定时更容易预测成训练集中更常见的类别。
本轮训练把薄荷和月季平衡到各 321 张。这个处理比盲目增加照片数量更重要。更多照片不一定带来更高准确率,如果新增照片继续偏向月季,模型可能会更加偏向月季。
对这种二分类小模型来说,数据质量和类别平衡通常比模型大小更关键。
绿色植物区域裁剪
原图里有很多与植物种类无关的内容,比如花盆、桌面、墙面、支架、边框和光照阴影。直接把整张图缩放到模型输入尺寸,会让这些背景信息混进模型判断。
本轮训练加入了绿色植物区域裁剪:先尽量定位图中的绿色植物主体,再把主体区域送入模型。这样模型更多关注叶片纹理、形态、颜色和边缘,而不是背景。
关键点是:训练端和推理端必须使用一致的预处理。
树莓派端运行时也同步加入了绿色裁剪逻辑,当前预处理可以概括为:
image_128_green_crop_imagenet_normalized
如果训练时使用裁剪图,而线上推理仍然使用完整原图,模型在验证集上可能表现很好,但部署后仍然容易出错。这类“训练和推理输入不一致”是边缘 AI 小模型很常见的坑。
模型训练与导出
本轮模型版本为:
mint_rose_v7_cropped_hardcase_128
模型使用 128 尺寸输入,并导出为 ONNX,便于树莓派端通过轻量运行时加载。
导出的主要文件包括:
plant_multitask.onnx
plant_multitask.onnx.data
labels.yaml
labels.yaml 用于保持类别顺序和模型输出一致。对于分类模型来说,类别顺序非常关键。如果训练端和推理端的类别索引不一致,即使模型本身正确,显示结果也会错。
验证结果
在本地测试集上,植物种类分类结果为:
薄荷: 32/32
月季: 32/32
species accuracy: 100%
这个结果说明当前测试集上的薄荷/月季分类已经明显改善。但它不代表真实世界里永远不会错。真实场景会继续出现新的光照、角度、遮挡、叶片状态和背景组合,所以后续仍然需要 hard case 回流。
原来的关键误判样本已经被修正:
样本: 20260523-232554-wide_1-wide_1
人工判断: 薄荷
旧问题: 被识别为月季
新版结果: 薄荷
置信度: 约 0.68
这里的置信度只有中等水平,说明模型已经纠正方向,但边界还可以继续变厚。这样的样本应该保留为下一轮 hard-case 训练材料。
部署方式
这次没有简单把 ONNX 文件手工复制到树莓派后就结束,而是通过 GardenHome 的模型导入和部署流程完成。
这样做的原因是:
- 页面状态需要知道当前哪个模型处于 active。
- 中心数据库需要记录模型版本和部署状态。
- 设备端需要收到正式部署命令。
- 旧模型需要标记为 superseded,避免页面误导用户。
- 部署后需要对历史照片重新识别,页面才会显示新模型结果。
最终激活的模型为:
模型 ID: 6
模型名称: mint_rose_v7_cropped_hardcase_128
状态: active
旧模型被标记为 superseded,以减少 UI 上的状态混乱。
部署后必须重跑历史照片
模型部署成功,并不代表页面上已有照片会自动变成新结果。如果页面仍然显示旧识别结果,用户会误以为新模型没有生效。
所以部署后需要触发历史照片重新识别。重新处理后,页面上的旧照片才会用当前 active 模型重新计算结果。
这个步骤对产品体验很重要:模型文件更新、设备加载成功、页面结果更新,是三个不同层面的事情,需要都完成才算闭环。
本轮关键改进总结
这次提升准确度主要来自下面几个改动:
- 冻结已有照片,停止继续盲目采集未复核数据。
- 从本地照片和树莓派现场照片中筛选有效样本。
- 只使用人工复核后的
plant_label作为植物种类真值。 - 不把旧模型预测直接当作训练标签。
- 平衡薄荷和月季样本,各 321 张。
- 使用绿色植物主体裁剪,减少背景干扰。
- 树莓派推理端同步使用相同预处理。
- 导出 ONNX 和 labels 文件,保持类别顺序一致。
- 通过 GardenHome 中心流程部署,而不是手工覆盖。
- 部署后重跑历史照片,验证旧误判样本是否被修正。
注意事项
后续继续训练时,建议遵守这些规则:
- 不要混用
label和plant_label。 - 不要把 teacher 初标当作最终真值。
- 不要把模型预测结果不经复核地写回训练集。
- 不要只追求照片数量,要关注类别平衡和场景覆盖。
- 不要只在训练端做裁剪,推理端必须保持一致。
- 不要只看本地测试集准确率,还要检查真实页面中的 hard case。
- 每次部署新模型后,都要确认 active 状态、设备加载日志和历史照片重识别结果。
下一轮优化方向
下一轮可以重点补充这些照片:
- 同一摄像头角度下的薄荷。
- 没有花、只看叶子的月季。
- 背景复杂、花盆明显、叶片被遮挡的照片。
- 夜间、逆光、弱光、轻微模糊照片。
- 同一植物的全景图和局部近景。
- 模型低置信度或与人工判断冲突的样本。
更进一步,可以把网页里的人工复核变成主动学习入口:低置信度照片自动进入复核队列,人工修正后进入下一轮训练集。这样 GardenHome 的植物识别能力就不是一次性模型,而是一个可以持续自我改进的闭环系统。