晚上好🌙🌙🌙
本答案参考通义千问
你遇到的错误是:
KeyError: 14
这说明在 names[c] 这一行中,c 的值为 14,但 names 字典中没有对应的键。也就是说,模型预测出一个类别编号为 14 的对象,但在你的 yaml 文件中定义的类别数量少于 15(因为类别从 0 开始)。
✅ 问题分析
1. 类别编号超出范围
- 如果你的训练数据只包含一个类别(比如
nc=1),那么在推理时,模型应该只输出类别编号 0。 - 但你运行
detect.py 时,模型却识别到了类别编号 14,这说明:
- 模型可能被错误地加载了预训练权重(如
yolov5s.pt)而不是你自己的训练模型。 - 或者你在
detect.py 中指定的 --weights 参数不正确,导致模型使用了其他模型文件。
2. 类别名称配置错误
- 在
detect.py 中,names 是从 data.yaml 文件中读取的,如果 data.yaml 中的 names 列表长度小于模型实际输出的类别数,就会出现 KeyError。
🔧 解决方案
✅ 步骤一:确认使用的模型文件是否正确
确保你运行的是你自己训练好的模型,而不是默认的 yolov5s.pt。
修改 detect.py 中的命令行参数或代码中的 weights 参数:
# 在 detect.py 中,找到如下代码
weights = 'yolov5s.pt' # 错误!应改为你的训练模型路径
# 改为:
weights = 'runs/train/exp/weights/best.pt' # 你的训练模型路径
或者在命令行中运行时指定:
python detect.py --weights runs/train/exp/weights/best.pt --source 0
✅ 步骤二:检查 data.yaml 配置文件
确保你的 data.yaml 文件中 nc 和 names 配置正确,例如:
nc: 1 # 类别数量
names: ['your_object_name']
注意:
- 如果你有多个类别,比如
nc: 3,则 names 应该是一个长度为 3 的列表。 - 如果
nc 设置为 1,而 names 只有一个元素,那模型只能识别 0 类。
✅ 步骤三:确认训练和推理时的类别数量一致
- 训练时:在
data.yaml 中设置 nc: 1,并确保训练数据中只包含一个类别的标注。 - 推理时:在
detect.py 中使用相同配置的 data.yaml。
✅ 步骤四:检查模型是否正确加载
你可以通过打印模型信息来验证模型是否正确加载:
from models.common import DetectMultiBackend
model = DetectMultiBackend(weights='your_model.pt', device='cpu')
print(model.model.nc) # 打印模型的类别数量
print(model.model.names) # 打印模型的类别名称
如果输出的 nc 不是 1,说明模型不是你训练的,而是其他模型。
✅ 步骤五:修改 detect.py 中的 names 处理逻辑(临时解决方案)
如果你无法立刻修正模型或配置文件,可以临时修改 detect.py 中的 label = names[c] 行,避免 KeyError:
# 原代码
label = None if hide_labels else (names[c] if hide_conf else f"{names[c]} {conf:.2f}")
# 修改为:
if c < len(names):
label = None if hide_labels else (names[c] if hide_conf else f"{names[c]} {conf:.2f}")
else:
label = None
这样即使出现 c >= len(names) 的情况,也不会报错。
🛠️ 总结
| 问题原因 | 解决方法 |
|----------|----------|
| 使用了错误的模型文件(如 yolov5s.pt) | 确保使用自己训练的模型文件(如 best.pt) |
| data.yaml 中 nc 或 names 配置错误 | 检查并修正 data.yaml 中的 nc 和 names |
| 模型类别数与推理时的类别数不一致 | 确保训练和推理时使用相同的 data.yaml |
| 模型输出类别编号超过 names 长度 | 临时修改 detect.py 中的 names 处理逻辑 |
📌 最终建议
请务必检查以下几点:
- 模型路径是否正确(
--weights) data.yaml 中的 nc 和 names 是否匹配- 训练和推理时是否使用了同一个
data.yaml
如果你能提供你的 data.yaml 文件内容和训练日志,我可以更准确地帮你定位问题。