2301_77204477 2026-03-12 19:35 采纳率: 0%
浏览 3

yolov5训练后运行detect,摄像头打开就闪退报这个错误,但是我训练用的yaml文件只有一个物品,而且我看训练的结果也没有问题,运行后就报这个错误,为什么啊求解

yolov5训练后运行detect,摄像头打开就闪退报这个错误,但是我训练用的yaml文件只有一个物品,而且我看训练的结果也没有问题,运行后就报这个错误,为什么啊求解


Traceback (most recent call last):
  File "D:\yolov5-master\detect.py", line 429, in <module>
    main(opt)
  File "D:\yolov5-master\detect.py", line 424, in main
    run(**vars(opt))
  File "D:\anaconda\envs\yolov5\lib\site-packages\torch\autograd\grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "D:\yolov5-master\detect.py", line 275, in run
    label = None if hide_labels else (names[c] if hide_conf else f"{names[c]} {conf:.2f}")
KeyError: 14
  • 写回答

3条回答 默认 最新

  • 檀越@新空间 2026-03-12 19:36
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你遇到的错误是:

    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 文件中 ncnames 配置正确,例如:

    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.yamlncnames 配置错误 | 检查并修正 data.yaml 中的 ncnames | | 模型类别数与推理时的类别数不一致 | 确保训练和推理时使用相同的 data.yaml | | 模型输出类别编号超过 names 长度 | 临时修改 detect.py 中的 names 处理逻辑 |


    📌 最终建议

    请务必检查以下几点:

    1. 模型路径是否正确--weights
    2. data.yaml 中的 ncnames 是否匹配
    3. 训练和推理时是否使用了同一个 data.yaml

    如果你能提供你的 data.yaml 文件内容和训练日志,我可以更准确地帮你定位问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月12日