news 2026/2/9 9:16:32

YOLOv9标签映射修改:自定义类别名称方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv9标签映射修改:自定义类别名称方法

YOLOv9标签映射修改:自定义类别名称方法

你训练完自己的YOLOv9模型,推理时框里却只显示数字0、1、2……而不是“person”“car”“dog”这些看得懂的类别名?或者你用官方预训练权重做检测,结果输出全是“0”“1”“2”,完全不知道对应什么物体?别急——这不是模型坏了,而是类别名称映射没改对。本文就带你从零开始,手把手在YOLOv9官方镜像中完成标签映射的完整修改,让检测结果真正“说人话”。

整个过程不碰模型结构、不重写训练逻辑,只改3个关键位置,5分钟内搞定。无论你是刚跑通第一个demo的新手,还是正在调试自定义数据集的开发者,都能照着操作一步到位。


1. 为什么YOLOv9默认只显示数字?

YOLOv9(包括v5/v8)内部用整数索引表示类别,比如0代表第1个类别,1代表第2个类别……这个映射关系由一个叫names的列表控制。但很多用户没意识到:这个列表既存在于训练配置文件中,也硬编码在推理脚本里,还可能被权重文件自带的names覆盖。三者不一致,就会出现“训练时叫cat,推理时显示0”的混乱。

更关键的是,YOLOv9官方代码(尤其是detect_dual.py这类双分支检测脚本)默认读取权重文件中保存的names,而官方发布的yolov9-s.pt里存的是COCO数据集的80类名称。如果你的数据集只有3类,或者类别顺序不同,直接加载就会错位。

所以,修改不是“选一个地方改”,而是同步校准三个环节:数据配置、推理脚本、权重兼容性。


2. 修改前准备:确认当前环境与路径

我们使用的镜像是基于YOLOv9官方代码构建的开箱即用环境,所有路径和依赖已预置好。请先确保你已完成以下两步:

  • 启动镜像后,执行conda activate yolov9激活专用环境
  • 进入代码根目录:cd /root/yolov9

验证当前状态:运行以下命令查看官方权重中保存的类别名

python -c "import torch; w = torch.load('./yolov9-s.pt', map_location='cpu'); print('Names in weight:', w['model'].names if 'names' in w['model'].__dict__ else 'Not found')"

你会看到类似['person', 'bicycle', 'car', ...]的80个COCO类别——这就是当前推理时默认显示的内容来源。


3. 三步完成自定义类别名称映射

3.1 第一步:修改data.yaml中的names字段(训练与评估依据)

YOLOv9通过data.yaml文件定义数据集结构。即使你只是做推理,这个文件也是类别映射的“权威源头”。

打开/root/yolov9/data.yaml(如果不存在可复制一份示例):

cp data/coco.yaml data/mydataset.yaml nano data/mydataset.yaml

找到names:字段,将其改为你的实际类别。例如,你要检测“apple”“banana”“orange”三类水果:

train: ../mydata/images/train val: ../mydata/images/val test: ../mydata/images/test nc: 3 # number of classes names: ['apple', 'banana', 'orange'] # ← 唯一需要修改的行!必须是Python列表格式

关键提醒

  • nc(number of classes)必须与names列表长度严格一致
  • 类别名用英文单引号包裹,逗号后加空格(符合YAML语法)
  • 不要写成names: apple, banana, orangenames: [apple, banana, orange]——会报错

改完保存,这一步确保了:
✔ 训练时模型知道每个数字对应哪个名字
✔ 评估指标(mAP)能正确按名统计
✔ 后续推理脚本能从中读取标准映射


3.2 第二步:修改detect_dual.py中的names赋值(推理显示核心)

YOLOv9的detect_dual.py是主推理脚本,它默认优先从权重文件读names。但我们要强制它使用你定义的data.yaml里的names,避免被预训练权重“带偏”。

打开/root/yolov9/detect_dual.py,定位到约第170行附近的if __name__ == '__main__':下方,找到模型加载后的处理段。在model = attempt_load(weights, map_location=device)之后,插入以下代码:

# --- 新增:强制从data.yaml加载names,覆盖权重中保存的names --- if opt.data: # 如果指定了data.yaml路径 import yaml with open(opt.data) as f: data = yaml.safe_load(f) if 'names' in data and isinstance(data['names'], list): model.names = data['names'] print(f" 已从 {opt.data} 加载自定义类别名: {model.names}") else: print(" data.yaml 中未找到有效的 names 字段,继续使用权重内置names") # ---

同时,确保你在运行命令时显式传入--data参数,指向你修改好的yaml:

python detect_dual.py \ --source './data/images/horses.jpg' \ --img 640 \ --device 0 \ --weights './yolov9-s.pt' \ --data './data/mydataset.yaml' \ # ← 关键!告诉脚本去哪读names --name yolov9_s_custom_detect

效果验证
运行后你会看到控制台打印已从 ./data/mydataset.yaml 加载自定义类别名: ['apple', 'banana', 'orange'],且生成的检测图中框标签将显示为文字而非数字。


3.3 第三步:保存自定义权重(一劳永逸,避免每次传参)

如果你已经用自定义数据集重新训练过模型,新权重文件会自动保存names。但若只是用官方权重做迁移推理,可以手动“注入”names:

python -c " import torch w = torch.load('./yolov9-s.pt', map_location='cpu') # 从data.yaml读取names import yaml with open('./data/mydataset.yaml') as f: data = yaml.safe_load(f) w['model'].names = data['names'] torch.save(w, './yolov9-s-custom.pt') print(' 自定义权重已保存:yolov9-s-custom.pt') "

之后,你就可以直接用新权重,无需再传--data

python detect_dual.py --source './data/images/test.jpg' --weights './yolov9-s-custom.pt'

优势

  • 推理命令更简洁
  • 权重文件自带语义,分享给同事时不会因缺少data.yaml而显示错误标签
  • 兼容所有YOLOv9相关脚本(train_dual.py、val.py等)

4. 常见问题与避坑指南

4.1 问题:改了data.yaml,但检测结果还是显示0/1/2?

→ 检查是否在detect_dual.py中漏加了--data参数,或新增代码未生效。
→ 运行时看控制台是否有已从...加载自定义类别名提示。没有则说明代码未执行到。

4.2 问题:names改了,但绘图时中文乱码或显示方块?

YOLOv9默认使用DejaVuSans字体,不支持中文。如需中文标签:

  1. 下载中文字体(如simhei.ttf)放入/root/yolov9/目录
  2. detect_dual.py中搜索cv2.FONT_HERSHEY_SIMPLEX,替换为:
    from PIL import ImageFont, ImageDraw, Image font = ImageFont.truetype('simhei.ttf', 32) # 调整字号
  3. 修改绘图逻辑(需重写plot_one_box函数),此处不展开——强烈建议英文命名,避免字体、编码、宽高计算等连锁问题。

4.3 问题:训练时类别名正确,但验证结果(val.py)里还是数字?

val.py同样依赖data.yaml,确保运行时指定--data

python val.py --data ./data/mydataset.yaml --weights ./runs/train/yolov9-s/weights/best.pt

4.4 问题:修改后报错AttributeError: 'NoneType' object has no attribute 'names'

→ 检查model = attempt_load(...)是否成功。常见原因:

  • GPU显存不足导致加载失败(加--device cpu测试)
  • 权重路径错误(用ls ./yolov9-s.pt确认存在)
  • PyTorch版本不匹配(本镜像为1.10.0,勿升级)

5. 进阶技巧:动态切换类别名(多任务场景)

假设你有一个通用模型,需在“水果检测”和“工业零件检测”两个任务间切换。不必反复修改文件,可用以下方式动态传入:

# 定义环境变量,在命令中直接注入 NAMES="['bolt','nut','washer']" python detect_dual.py \ --source './images/' \ --weights './yolov9-s.pt' \ --name industrial_detect

然后在detect_dual.py中,于模型加载后添加:

import os if os.getenv('NAMES'): try: import ast model.names = ast.literal_eval(os.getenv('NAMES')) print(f"🔧 动态加载NAMES环境变量: {model.names}") except: print("❌ NAMES环境变量格式错误,请用Python列表格式")

这样,同一份代码+权重,通过环境变量即可秒切任务,适合部署到Docker或CI/CD流程。


6. 总结:标签映射修改的本质与要点

YOLOv9的类别名不是“写死”的,而是一套三层映射系统

  • 数据层(data.yaml):定义“真实世界类别” → “数字ID”的原始映射
  • 模型层(weights):存储训练时确定的映射快照,用于快速加载
  • 应用层(detect_dual.py等):决定运行时采用哪套映射,是最终显示效果的开关

你只需抓住三个动作:

  1. data.yaml中写对namesnc
  2. 在推理脚本中强制从yaml读取,覆盖权重默认值
  3. --data参数或保存新权重,让修改落地

改完你会发现:检测框旁不再是冰冷的数字,而是清晰的“apple”“banana”——这才是AI该有的样子。下一步,你可以基于此进一步优化:给不同类别配不同颜色框、添加置信度阈值过滤、导出带标签的JSON结果……而这一切,都建立在“名字对得上”这个最基础却最关键的环节之上。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 10:04:35

TurboDiffusion持续学习机制:在线更新部署实战教程

TurboDiffusion持续学习机制:在线更新部署实战教程 1. 什么是TurboDiffusion?——不只是加速,更是可进化的视频生成引擎 TurboDiffusion不是又一个“跑得更快”的视频生成工具。它是清华大学、生数科技与加州大学伯克利分校联合打磨出的具备…

作者头像 李华
网站建设 2026/2/8 21:49:53

FSMN VAD服务器端口7860冲突?修改应用配置实战教程

FSMN VAD服务器端口7860冲突?修改应用配置实战教程 1. 为什么端口7860会冲突?真实场景还原 你兴冲冲地执行完 /bin/bash /root/run.sh,终端显示“Gradio server started”,满心期待打开浏览器输入 http://localhost:7860 —— 结…

作者头像 李华
网站建设 2026/2/8 15:49:03

Qwen3-Embedding-4B代码实例:openai.Client调用完整指南

Qwen3-Embedding-4B代码实例:openai.Client调用完整指南 1. Qwen3-Embedding-4B是什么?它能帮你解决什么问题? 你有没有遇到过这样的场景: 想从上万篇技术文档里快速找到和“PyTorch分布式训练”最相关的几条,但关键…

作者头像 李华
网站建设 2026/2/8 9:55:21

Cute_Animal_For_Kids_Qwen_Image负载均衡:高流量场景部署架构设计

Cute_Animal_For_Kids_Qwen_Image负载均衡:高流量场景部署架构设计 1. 这不是普通图片生成器,而是专为孩子设计的“可爱动物画师” 你有没有试过陪孩子一起找一张小熊猫在彩虹云朵上打滚的图?或者一只戴蝴蝶结的柴犬正用爪子托着星星&#…

作者头像 李华
网站建设 2026/2/4 7:52:42

Qwen3-14B高并发:批量请求处理优化部署实战

Qwen3-14B高并发:批量请求处理优化部署实战 1. 为什么是Qwen3-14B?单卡跑出30B级效果的“守门员” 你有没有遇到过这样的困境:业务需要强推理能力,但预算只够一张4090;想处理超长合同或技术文档,又怕模型…

作者头像 李华
网站建设 2026/2/6 17:46:06

儿童语音交互设计:用SenseVoiceSmall识别孩子的情绪状态

儿童语音交互设计:用SenseVoiceSmall识别孩子的情绪状态 【免费下载链接】SenseVoiceSmall 多语言语音理解模型(富文本/情感识别版) 项目地址: https://gitcode.com/gh_mirrors/se/SenseVoice 你有没有试过听孩子讲完一段话,却不…

作者头像 李华