YOLOv8 data.yaml 报错?用 TaoToken 接的 Codex 对着 PCB 数据集目录查
2026/9/21 17:51:33 网站建设 项目流程

1. 原问题与场景:train_yolo() 报 data.yaml not found,PyQt5 检测框标签错乱

YOLOv8 + PyQt5 做 PCB 缺陷检测时,最磨人的往往不是模型结构,而是数据集配置和标签绘制这些小细节。我最近在调 pcb_dataset 数据集时,train_yolo() 一上来就打印 data.yaml not found,后面 PyQt5 加载自定义 .pt 后画框又全是乱标签。这篇文章就记录我怎样用 TaoToken 接上 Codex 当排错助手,一步步把 data.yaml 的 train/val/test 路径、nc: 3、names 列表和实际目录对齐,再回头核对 detect_defects 的 box.xyxy / box.cls 取值,最终让 PCB 缺陷检测界面能正常显示 defect1、defect2、normal。

先还原一下当时 train.py 里的核心逻辑。它是这样写的:

import os def train_yolo(): from ultralytics import YOLO data_path = './pcb_dataset/data.yaml' if not os.path.exists(data_path): print(f"Data configuration file {data_path} not found.") return weights_path = 'yolov8n.pt' if not os.path.exists(weights_path): print(f"Weights file {weights_path} not found.") return model = YOLO(weights_path) model.train(data=data_path, imgsz=640, batch=16, epochs=100, name='yolov8_pcb')

这段逻辑本身没毛病,问题在于它假设当前工作目录下直接就有pcb_dataset文件夹。我试过在 PyCharm 里右键运行,有时工作目录是项目根目录,有时是src目录,目录一不对就报 not found。当时我第一反应是“data.yaml 写错了”,但其实根本原因是路径基准不对。

另一边 PyQt5 界面里,detect_defects也有类似问题。它先box.xyxy[0].tolist(),再box.cls[0].item(),然后从self.model.names[int(label)]里取名字。表面看上去没问题,但如果你用的模型是别人训练的,他的 names 顺序和你的data.yaml不一致,画出来的标签就会张冠李戴。比如把normal标记成defect1,或者干脆 index out of range。

这类问题用眼睛看很费时间,尤其当你同时面对路径、标注、类别三个变量时。我决定把 Codex 接上 TaoToken,让它直接分析这些配置和代码,而不是自己一行行猜。

2. TaoToken 前置:创建 API Key 并配置 Codex Base URL

TaoToken 在这里只负责两件事:给你一把 Key,以及提供一个统一的 API 通道。Codex 默认连 OpenAI,但国内网络环境下直连不稳定,而且我手上也没有 OpenAI 的付费 Key。用 TaoToken 把它指到https://taotoken.net/api之后,Codex 就能通过这个中转正常工作了。

操作分两步。

第一步,打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册并创建一个 API Key。创建完会得到一串类似sk-xxxxxxxx的字符串,复制保存好。

第二步,配置 Codex 的 Base URL。我用的是 Codex CLI,只需要在环境变量里设置两个值:

export OPENAI_API_KEY="sk-你的TaoToken Key" export OPENAI_BASE_URL="https://taotoken.net/api"

注意这里不带/v1,也不加任何 UTM 参数。如果你用的是配置文件方式,可以在~/.codex/config.toml里加:

model_providers = [ { name = "taotoken", base_url = "https://taotoken.net/api", api_key_env_var = "OPENAI_API_KEY" } ]

设置完跑codex随便问一句,能收到回复就说明通道通了。我用同一把 Key 完成了后面所有排错对话,不需要再申请别的。

3. 可复制配置:将 data.yaml 与 pcb_dataset 目录结构喂给 Codex

通道就绪后,我把手头所有相关信息一股脑贴给 Codex。不是简单说“帮我看看为什么报错”,而是给它完整的快照,让它像看本地项目一样分析。

我整理的排查信息包括四部分:data.yaml 内容、目录树、训练命令、报错截图文字。贴给 Codex 的 prompt 大概是这样的:

我在跑 YOLOv8 PCB 缺陷检测训练,遇到 data.yaml not found。 下面是我的配置和目录结构,请帮我分析可能的原因。 data.yaml 内容: train: ./pcb_dataset/images/train val: ./pcb_dataset/images/val test: ./pcb_dataset/images/test nc: 3 names: ['defect1', 'defect2', 'normal'] pcb_dataset 目录树: pcb_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/ 训练命令: python train.py --data ./pcb_dataset/data.yaml --img 640 --batch 16 --epochs 100 --name yolov8_pcb --weights yolov8n.pt 报错: Data configuration file ./pcb_dataset/data.yaml not found.

注意,目录树我只写了 images 和 labels 下的子文件夹,没有列出里面的图片和标注文件。Codex 立刻指出:data.yaml里的 train/val/test 路径指向的是images下的子目录,这本身没问题,但train.pyos.path.exists(data_path)是相对路径,如果你不是从项目根目录启动 Python,就会找不到pcb_dataset。它建议我把路径改成基于__file__的绝对路径。

这个建议很直接。我把 train.py 开头改成:

import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent data_path = BASE_DIR / 'pcb_dataset' / 'data.yaml'

改完后,无论我从哪个目录启动脚本,都能正确找到 data.yaml。Codex 还提醒我检查labels/train里是否每个.txt都有内容,因为 YOLOv8 训练时如果某个类别没有标注,可能不会直接报错,但会严重影响 mAP。我顺手写了个脚本统计:

from pathlib import Path for split in ['train', 'val', 'test']: label_dir = Path(f'pcb_dataset/labels/{split}') empty = sum(1 for f in label_dir.glob('*.txt') if f.stat().st_size == 0) total = len(list(label_dir.glob('*.txt'))) print(f'{split}: {total} 个标注,其中 {empty} 个空文件')

结果 val 里有 5 个空文件,Codex 建议要么补标注,要么干脆删掉这些图片,避免训练时出现“无目标”的 batch。我把空文件对应的图片移到了pcb_dataset/ignore/下,重新跑。

4. 验证请求:重跑 train.py 并核对 detect_defects 绘制逻辑

路径问题解决后,我回到终端重新执行训练:

python train.py --data ./pcb_dataset/data.yaml --img 640 --batch 16 --epochs 100 --name yolov8_pcb --weights yolov8n.pt

这次没有再报 not found,训练正常启动。训练结束后,我把 PyQt5 的detect_defects代码也贴给 Codex,让它逐行核对。

for result in results: boxes = result.boxes for box in boxes: x1, y1, x2, y2 = box.xyxy[0].tolist() label = box.cls[0].item() confidence = box.conf[0].item() cv2.rectangle(self.image, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.putText(self.image, f"{self.model.names[int(label)]}: {confidence:.2f}", (int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0,255,0), 2)

Codex 指出两个隐患:

第一,box.cls[0].item()返回的是浮点数,虽然int(label)能转成整数,但如果类别数很多,建议直接用int(box.cls.item())。这个只是风格问题。

第二,更关键的是,self.model.names在 YOLOv8 中是一个字典,索引从 0 开始。如果训练时data.yaml的 names 是['defect1', 'defect2', 'normal'],模型保存的 names 也应该是这个顺序。但如果你加载的是别人训练的.pt,而他的 data.yaml 顺序是['normal', 'defect1', 'defect2'],那么你的int(label)取到的名字就会错位。解决办法是强制让模型使用当前项目的 names:

self.model.names = {0: 'defect1', 1: 'defect2', 2: 'normal'}

或者从本地 data.yaml 读取:

import yaml with open('pcb_dataset/data.yaml', 'r', encoding='utf-8') as f: cfg = yaml.safe_load(f) self.model.names = {i: name for i, name in enumerate(cfg['names'])}

我采用了第二种方式,这样不管加载哪个模型,标签都会以项目配置为准。改完后,我用 PyQt5 加载了训练好的runs/detect/yolov8_pcb/weights/best.pt,随便挑了几张测试图,检测框和标签终于对上了。

5. 本篇常见错排查:data.yaml 路径与 box.cls 标签对不上

这次排错过程里,我遇到的最典型的三个坑,值得单独拿出来说。

第一个坑:data.yaml 里路径基准不对。很多人习惯写./pcb_dataset/images/train,但运行脚本时工作目录不是项目根目录。解决方案就是用Path(__file__).resolve().parent拼绝对路径,或者用os.chdir切到项目根目录。建议在 train.py 最前面打印一下当前工作目录:

import os print("当前工作目录:", os.getcwd())

这样报错时一眼就能看出是不是目录跑偏了。

第二个坑:标注文件缺失但不报错。YOLO 训练允许某张图片没有对应标注文件,或者标注文件为空,它不会中断训练,但会拉低模型效果。我用 Codex 排查后写了个统计脚本,发现部分图片确实没有标注。这种情况需要先确认是漏标还是故意忽略。如果是漏标,用 LabelImg 或 Roboflow 补上;如果是背景样板,应该把图片移到单独的background目录,并在训练时用background作为负样本。

第三个坑:box.clsnames不同步。训练时用的 names 顺序和推测时加载的模型内嵌 names 不一致,导致标签错乱。YOLOv8 训练时会把 names 存进模型里,但如果你用了外部下载的.pt文件,它就只认自己训练时的 names。所以在 PyQt5 加载模型后,建议立刻打印model.names看一眼:

print("模型 names:", self.model.names)

如果和你预期不一致,就在推理前覆盖掉。用本地 data.yaml 里的 names 强制覆盖是最稳的。

还有一个容易忽略的点:box.xyxy返回的是一个 1x4 的 tensor,tolist()后得到[x1, y1, x2, y2],这四个值都是浮点数,画框时需要转成 int。如果原始图片是 BGR 格式,cv2.rectangle直接画没问题;如果是 RGB 格式,先转换再画,否则颜色会偏蓝红颠倒。

6. 让排错助手长期可用:API Keys 与接入文档

这次经历之后,我把 Codex + TaoToken 固定成了自己的标准排错流程。路径报错、标签错乱、训练异常,第一反应不是去搜索引擎翻帖子,而是把上下文完整丢给 Codex,让它先做一轮静态分析。TaoToken 只提供 Key 和统一通道,不碰模型本身,所以不用担心它会影响 PyTorch 或 YOLO 的底层行为。

如果你也想这样接,先到 TaoToken 官网创建 API Key:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。然后把 Codex 的 Base URL 配置成 https://taotoken.net/api ,注意不要带/v1,也不要加 UTM 参数。创建完 Key 后,如果忘了怎么配置,可以随时打开接入文档查看环境变量和配置文件样例:https://taotoken.net/doc 。配置完以后,建议先用一个 5 行的 Python 脚本测试连通性,比如让 Codex 解释一段 YOLOv8 的推理代码,确认它能正常返回结果再开始正式排错。

如果你是长期跑 YOLO 训练或者做 Agent 自动化,还可以考虑 TaoToken 的 Coding Plan,它把高频模型调用和长上下文对话打包成更划算的模式。但不管选哪个方案,核心思路都是:把 TaoToken 当成你与 Codex 之间的稳定通道,让 AI 专注于读代码、找问题,你专注于改配置、跑实验。这次 PCB 缺陷检测系统从报错到正常运行,我只用了不到半小时,换了以前手动查资料至少要折腾一下午。你遇到类似问题时,也值得试一试。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询