事情本身不复杂,线索都在日志里。标注平台升级后内部 label_id 重新分配,训练配置里还是旧的 id 映射,导出数据里 cat 变成 3、dog 变成 1,模型训出来把猫认成狗,分类报告里两个类别的指标完全对调。

第一反应是「训练脚本按 id 排序建类别表,顺序变了也不报错」,验证下来不成立。

真正麻烦的地方在于,几个原因的现象几乎一样。平台升级重排了 label_id,配置文件没跟着改。另一种情况是导出默认用 id 而不是名称,名称映射留在旧版本。

另外,评测脚本用的是另一份映射,两边不一致。

动手时先打印导出文件里的 id 与名称对应

python -c "import json;print({d['label_id']:d['label'] for d in json.load(open('export.json'))['categories']})"

随后改成按名称排序生成新映射

python -c "import json;c=json.load(open('export.json'))['categories'];print({x['label']:i for i,x in enumerate(sorted(c,key=lambda v:v['label']))})"

训练前断言映射与配置一致

python train.py --label-map label_map.json --assert-labels

剩下的就是重训后用混淆矩阵核对类别方向

python eval.py --ckpt out/best.pt --report confusion

怎么算真的好了,看的是同一批现象。映射表里 cat 与 dog 的顺序和配置一致,混淆矩阵对角线集中在正确类别,分类报告不再对调。

把类别名称当唯一标识、id 只当内部索引,平台升级重排 id 时才不会连累训练配置。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189