莱彩 Flow 使用指南
YOLO · ONNX · LaiCai Flow

为莱彩 Flow 训练自定义目标检测模型

这篇教程会带你从原始截图一直做到莱彩可用的 ONNX 模型。示例来自一个小目标游戏数据集,但同一套流程也适用于 App 按钮、商品、图标、工具和其他画面目标。

已验证方案YOLO26n · 960 像素 · 17 个类别 · 符合桌面端与 Android Agent 模型契约
通用游戏场景,矿石、树木和怪物周围带有检测框
同一个模型可以识别同一场景中的多个相关类别,例如资源、角色和物体状态。
为莱彩 Flow 训练自定义目标检测模型
YouTube

完整流程

  1. 采图收集有差异的画面
  2. 标注紧贴目标画框
  3. 合并保持类别 ID 稳定
  4. 训练用未见画面验证
  5. 导出生成原始 ONNX 输出
  6. 导入补齐 config.json

开始之前

当莱彩需要知道目标在画面中的位置时,应选择目标检测。图像分类只能判断整张图片包含什么,不会返回目标框。

矿石、木材和怪物要放进同一个模型吗?

通常可以。只要它们出现在同一款游戏或 App 中,截图比例一致,并且需要在同一个 Flow 里识别,就适合放进一个模型。只有场景完全无关、类别非常多,或某一组目标需要不同输入尺寸和性能目标时,才考虑拆分模型。

01

准备真正有用的截图

使用莱彩实际会看到的设备、分辨率、缩放和画质来采图。画面的多样性,比从视频里连续保存大量几乎相同的帧更重要。

  • 覆盖不同位置、大小、光照、背景、动画阶段和部分遮挡。
  • 保留难例:很小的目标、画面边缘目标、模糊、弹窗,以及和目标很像的非目标。
  • 加入一部分完全没有目标类别的背景图;这些图片对应的标签文件为空。
  • 没有通用的最低数量。第一次试验可先保证每类至少有 50 个有差异的框;难分或相似类别通常需要 100–200 个甚至更多。
02

标注前先确定类别表

每个类别都应对应 Flow 需要做出的一个视觉判断。名称要短、唯一且保持不变,因为 YOLO 标签、data.yaml、config.json 和 vision.detect 的类别选择都会使用同一顺序。

视觉状态不同,就分成不同类别

如果资源被采集后仍然很像可采集状态,就把两种状态都标出来,例如 Copper 和 CopperDepleted。不要指望只调置信度,就能稳定区分两个真实视觉状态。

可采集铜矿与已采集铜矿的并排对比,两种状态分别带有检测框
当自动化需要对两种状态采取不同动作时,应使用两个类别。
  • 图片中所有目标类别的每一个可见实例都必须标注;漏标的目标会被当成背景学习。
  • 所有图片采用同一套画框规则:紧贴可见物体,不要留下大片空白。
  • 如果标注工具会处理空格,优先使用 CopperDepleted 或 copper_depleted 这类名称。
03

在 MakeSense.ai 中标注

MakeSense.ai 是免费的浏览器标注工具。为莱彩制作模型时,应选择 Object Detection,使用矩形框,并导出 YOLO 标注。

  1. 1

    打开 MakeSense.ai 并上传原始图片。原图文件夹要自己保留;导出的标签 ZIP 不能替代原图。

  2. 2

    选择 Object Detection,不要选择 Image Recognition。

  3. 3

    按固定顺序建立最终类别表,然后给每一个目标实例画矩形框。

  4. 4

    导出前检查空图片、漏标、错标和过松的框。

  5. 5

    把 Rect annotations 导出为 YOLO 格式的 ZIP 包。

04

整理成一个干净的 YOLO 数据集

每张图片都要有一个同名的 .txt 标签文件。训练集和验证集应按录屏批次或时间段划分,不要把相邻视频帧随机打散到两边。

Dataset
dataset/
├── images/
│   ├── train/
│   └── val/
├── labels/
│   ├── train/
│   └── val/
└── data.yaml
data.yaml
path: /absolute/path/to/dataset
train: images/train
val: images/val

names:
  0: Copper
  1: CopperDepleted
  2: Wood
  3: Monster

第一次可以从 80% 训练、20% 验证开始。验证集必须包含训练时真正没有见过的场景。

  • 新增一批标注时,不需要把旧图片重新上传到 MakeSense.ai。
  • 离线合并新旧图片和标签,再按类别名称重映射数字 ID,保证原来的类别顺序不变。
  • 使用完整的旧数据 + 新数据重新训练。只用新图片训练,可能会让旧类别逐渐被当成背景。
YOLO 数据集示例图,显示每个类别的标注实例数量和检测框尺寸
训练前先检查类别数量。某个类别只有少量样本时,即使整体分数看起来不错,它的指标也会很不稳定。
05

安装 Ultralytics 并开始训练

下面使用的是这套流程已经验证过的版本。持续检测建议先从 Nano 模型开始;目标较大时用 640,重要目标很小时可用 960。

创建独立训练环境
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install ultralytics==8.4.138 onnx==1.22.0 \
  onnxruntime==1.29.0 onnxslim==0.1.96

建议的起步参数

参数起步值原因
modelYOLO26n体积小、速度快,适合第一轮验证。
imgsz960 / 640小目标使用 960;目标较大或更重视速度时使用 640。
epochs200给足训练上限,同时允许早停提前结束。
patience40验证指标连续 40 个 epoch 没有提升就停止。
batch8显存不足时先降到 4 或 2;只有实际测量后才提高。
devicemps / 0 / cpuApple 芯片使用 mps,NVIDIA 使用 0,任何机器都可以使用 cpu。
workers4一个较保守的跨平台起点。
seed42便于重复比较数据集和不同训练版本。
close_mosaic15最后阶段关闭 mosaic,让模型在更自然的图片上收尾。
train.py
from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model.train(
    data="dataset/data.yaml",
    imgsz=960,
    epochs=200,
    patience=40,
    batch=8,
    device="mps",  # NVIDIA: 0 · CPU: "cpu"
    workers=4,
    seed=42,
    close_mosaic=15,
)
06

验证模型,而不只是看损失曲线

使用最佳 checkpoint,在未见过的截图上检查预测,并分别查看每一个类别。整体高分可能掩盖某个稀有类别很弱。

  • Precision:模型报出的目标中,有多少是真的。
  • Recall:画面中的真实目标,有多少被找到。
  • mAP50 和 mAP50-95:在不同阈值下综合衡量定位和分类质量。
  • 混淆矩阵:哪些类别会互相认错,或被认成背景。
Ultralytics 训练损失和验证指标曲线示例
训练损失应总体下降,验证指标逐渐稳定。应使用保存下来的 best.pt,而不是默认取最后一个 epoch。
多类别游戏目标检测模型的归一化混淆矩阵示例
重点查看对角线和 background 行列;相似状态类别要单独检查。
07

导出莱彩兼容的 ONNX 模型

莱彩导入的是 ONNX,不是训练用的 .pt。应导出单个静态 NCHW RGB 输入、batch 1、float32 或 float16,以及原始 one-to-many 预测,让莱彩执行置信度过滤和 NMS。

export.py
from ultralytics import YOLO

model = YOLO("runs/detect/train/weights/best.pt")
model.export(
    format="onnx",
    imgsz=960,
    batch=1,
    dynamic=False,
    simplify=True,
    nms=None,
)

打包模型目录

在莱彩模型库中选择的是整个目录。目录内必须同时有 config.json 和 modelFile 指定的 ONNX 文件;类别 ID 必须从 0 开始连续排列。

Model directory
game-objects/
├── config.json
└── model.onnx
config.json
{
  "id": "game-objects-v1",
  "name": "Game Objects v1",
  "type": "yolo",
  "modelFile": "model.onnx",
  "outputFormat": "raw_yolo_no_objectness",
  "id2label": {
    "0": "Copper",
    "1": "CopperDepleted",
    "2": "Wood",
    "3": "Monster"
  },
  "label2id": {
    "Copper": 0,
    "CopperDepleted": 1,
    "Wood": 2,
    "Monster": 3
  }
}

为什么显示“导入成功,但有警告”?

如果莱彩提示 config.json 缺失或无法读取,说明你选择了单独的 ONNX 文件,或目录内容不完整。请导入完整模型目录,并确认 id2label 或 label2id 定义了全部类别。

08

导入莱彩并实际测试

打开莱彩 Flow,进入模型库,导入准备好的目录;确认模型显示为“兼容”后,再用于 vision.detect。

  • 在模型库中选中模型,核对输入、输出、输出格式和类别表。
  • 使用“测试当前画面”,选择一个类别,并从 0.5 这类合理阈值开始测试。
  • 既要测有目标的画面,也要测没有目标或容易混淆的画面。推理调用成功,不等于一定检测到了物体。
  • 如果 Flow 最终要在手机上运行,桌面端验证后,还要在 Android Agent 上单独验证同一模型。
V2+

下一版如何继续加强

把原图、YOLO 标签、类别表、data.yaml、训练命令和 best.pt 放在一起保存。它们才是可以持续迭代的数据源;只有导出的 ONNX,无法可靠重训。

  1. 从真实运行中收集误报、漏报、新环境和新的视觉状态。
  2. 只把新图片放进 MakeSense.ai,按照最终类别规则完成标注。
  3. 合并新旧数据,按名称保持类别 ID,再按录屏批次重新划分训练集和验证集。
  4. 类别映射兼容时,从上一版 best.pt 开始新训练,并同时回归旧场景和新场景。
新图片里只要出现旧类别,就必须继续标注;否则训练会把它当成背景。

常见问题

需要把所有旧图片重新导入 MakeSense.ai 吗?

不需要。标注新批次、导出后,与保存好的旧数据集离线合并即可。只有需要修正旧标注时,才重新导入旧数据。

可以只新增一个类别吗?

可以,但要把新类别追加在旧类别之后,并按类别名称重映射新导出的标签。然后使用完整数据集重训,保证旧类别仍有样本。

为什么已采集的资源仍然会被识别?

两种状态外观接近,而模型没有学会区别。增加独立的已采集状态类别,或加入经过确认的难负样本,然后重新训练并检查混淆矩阵。

把置信度调高,能解决所有误报吗?

不能。阈值只能在召回率和准确率之间取舍,无法替代缺失类别、一致的标注规则或容易混淆的负样本。

官方参考资料

本教程中的命令和兼容性选择,已经按照当前官方文档与莱彩真实模型契约核对。

继续在莱彩 Flow 中使用

模型兼容后,在 vision.detect 中选择类别、阈值和画面区域,再把成功或失败路径连接到下一步 Flow 动作。