
简介这份资源面向从事电子制造质检、PCB缺陷检测及工业视觉方向的开发者与算法学习者提供了一套可直接用于YOLO目标检测训练的电路板电器元件图像数据集帮助解决元件识别与定位任务中样本获取难、标注成本高的问题。压缩包共约2000个文件以1981个txt标注文件、18张jpg图像和1个py脚本为主整体约53.66MB按YOLOv5目录结构组织训练集约1800张、验证集约60张、测试集约40张并附类别class文件涵盖电感器、变压器、传感器等45个类别。随包提供的可视化脚本无需修改即可运行随机传入一张图片便能绘制边界框并保存到当前目录便于快速核验标注质量。目前已有120人学习下载适合需要快速搭建检测基线、验证模型改进效果或开展工业元件识别实验的读者参考使用。1. 电路板元件检测数据集45 类小目标1800 张训练图能跑出什么手里这块板子上的电感、变压器、传感器肉眼数一遍要十分钟还容易漏。换成 YOLO 来数前提是你得先有一份标注到位、划分干净的数据集。这次拆的这份资源就是冲着电路板电器元件目标检测去的训练集 1800 张左右、验证集 60 张左右、测试集 40 张左右全部按 YOLOv5 的目录规范摆好图片和同名 txt 标签一一对应类别数 45具体类别名在 classes 文件里。它解决的不是从零标注这种苦力活而是让你跳过最耗时的数据准备阶段直接把精力放在模型训练和调参上。适合谁做 PCB 缺陷或元件识别方向的算法工程师、要交课程设计的学生、以及想拿一份真实工业图像数据练手 YOLO 的入门者。下面按这份数据长什么样 → 怎么接进训练流程 → 哪里会翻车的顺序拆开讲。2. 数据集结构与 YOLOv5 目录规范先看清文件再动手2.1 目录树与文件命名规则这份数据按 YOLOv5 的标准结构组织根目录下分 images 和 labels 两棵子树各自再分 train、val、test。图片是 jpg标签是同名 txtYOLO 格式每行class_id x_center y_center width height坐标全部归一化到 0~1。从项目正文给出的文件名能看出命名带_jpg.rf.哈希后缀这是标注平台导出时自动加的不影响训练但做脚本匹配时要注意别用简单字符串截断去推标签名。dataset/ ├── images/ │ ├── train/ # 约 1800 张 jpg │ ├── val/ # 约 60 张 jpg │ └── test/ # 约 40 张 jpg ├── labels/ │ ├── train/ # 与 train 图片同名的 txt │ ├── val/ │ └── test/ └── classes.txt # 45 行每行一个类别名提示images 和 labels 下的子目录名必须完全一致YOLOv5 默认按路径替换images→labels找标签大小写和复数形式都不能错。2.2 classes 文件与 data.yaml 的对应关系classes 文件是纯文本45 行顺序即 class_id。YOLOv5 训练时不直接读 classes.txt而是读 data.yaml 里的names列表所以你得把 classes 内容转成 yaml 的列表格式。常见做法是写个小脚本读 classes.txt 生成 data.yaml避免手抄 45 个类别名出错。# gen_yaml.py从 classes.txt 生成 YOLOv5 可用的 data.yaml import yaml with open(classes.txt, r, encodingutf-8) as f: names [line.strip() for line in f if line.strip()] data { path: ./dataset, # 数据集根目录按实际路径改 train: images/train, # 相对 path 的路径 val: images/val, test: images/test, nc: len(names), # 类别数应为 45 names: names # 类别名列表顺序对应 class_id } with open(data.yaml, w, encodingutf-8) as f: yaml.dump(data, f, allow_unicodeTrue, sort_keysFalse) print(fnc{len(names)})逻辑说明path是根train/val/test写相对路径YOLOv5 会拼成绝对路径找图。nc必须等于 names 长度写错会直接报维度不匹配。allow_unicodeTrue保证中文类别名不被转义成乱码。跑完打印 nc如果不是 45说明 classes 文件有空行或编码问题先修文件再训练。2.3 标签格式校验三行代码查越界和空标签拿到别人整理的数据第一件事不是开训是校验标签。YOLO 要求坐标在 0~1class_id 在 0~nc-1。越界坐标会让 loss 变 NaN空标签文件会让某些版本报错。下面这段扫一遍 train 标签把问题文件列出来。# check_labels.py校验 YOLO 标签的坐标范围和类别 id import os label_dir dataset/labels/train nc 45 bad [] for fn in os.listdir(label_dir): if not fn.endswith(.txt): continue with open(os.path.join(label_dir, fn)) as f: for i, line in enumerate(f): parts line.strip().split() if len(parts) ! 5: bad.append((fn, i, field_count)) continue cid int(parts[0]) coords list(map(float, parts[1:])) if cid 0 or cid nc: bad.append((fn, i, fclass_id{cid})) if any(c 0 or c 1 for c in coords): bad.append((fn, i, coord_out_of_range)) print(f问题条目数: {len(bad)}) for b in bad[:20]: print(b)逻辑说明逐行拆 5 个字段class_id 转 int 查范围坐标转 float 查 0~1。field_count报错通常是标注工具导出了带置信度的旧格式需要裁掉多余列。coord_out_of_range多半是归一化时除了错基准尺寸。跑完问题条目为 0 再往下走别带着脏数据开训否则调参调半天发现是标签的锅血泪经验。3. 可视化脚本怎么用随机抽图看框确认标注质量3.1 可视化脚本的运行逻辑资源里带了一个可视化 py 文件随机传一张图就能画出边界框并存到当前目录。它的核心逻辑是读图片 → 按同名找 labels 下的 txt → 逐行解析 class_id 和归一化坐标 → 乘回图片宽高 → 用 OpenCV 或 PIL 画矩形和类别名 → 保存。这类脚本不用改就能跑但前提是路径对得上。下面给一个等价实现方便你理解它内部在干什么也方便路径不对时自己改。# visualize.py随机抽一张训练图画框并保存 import os, random import cv2 img_dir dataset/images/train lbl_dir dataset/labels/train names [l.strip() for l in open(classes.txt, encodingutf-8) if l.strip()] img_name random.choice(os.listdir(img_dir)) img_path os.path.join(img_dir, img_name) img cv2.imread(img_path) h, w img.shape[:2] lbl_path os.path.join(lbl_dir, os.path.splitext(img_name)[0] .txt) if os.path.exists(lbl_path): for line in open(lbl_path): cid, x, y, bw, bh line.split() cid int(cid) x, y, bw, bh map(float, (x, y, bw, bh)) # 归一化中心点宽高 转 左上右下像素坐标 x1 int((x - bw / 2) * w) y1 int((y - bh / 2) * h) x2 int((x bw / 2) * w) y2 int((y bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, names[cid], (x1, max(y1 - 5, 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imwrite(vis_result.jpg, img) print(f已保存 vis_result.jpg来源: {img_name})逻辑说明x, y是框中心归一化坐标bw, bh是归一化宽高转像素要先减半宽高得左上角再乘图片尺寸。names[cid]取类别名cid 越界会 IndexError正好反向验证标签有没有问题。max(y1-5, 10)防止文字画到图外。跑几次换不同图看重点看小元件框有没有漏标、框有没有偏。如果发现某类元件框普遍偏大或偏小说明标注时对边界定义不一致训练前最好统一。3.2 从可视化结果判断数据能不能用看框不是看热闹要盯三件事。第一小目标密度电路板上电感、传感器这类元件尺寸差异大如果一张图里几十个框挤在一起要确认 YOLO 的 anchor 能不能覆盖这么小的尺度必要时上高分辨率输入。第二类别一致性同一个元件在不同图里被标成不同类是 45 类数据最常见的脏点可视化时多抽几张同类元件的图对比。第三遮挡和截断板子边缘的元件常被裁掉一半如果标注把截断目标也框了训练时要注意 YOLOv5 对边缘框的处理。这一步花二十分钟能省后面几小时的调参玄学。4. 接进 YOLOv5 训练参数怎么设、显存怎么省4.1 环境与训练命令数据就位后拉 YOLOv5 仓库装依赖把 data.yaml 指过去。训练命令不用花哨先把 baseline 跑通。# 克隆并安装依赖版本按仓库当前 requirements 为准 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt # 单卡训练batch 按显存调 python train.py \ --data ../data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --workers 4 \ --project runs/train \ --name pcb_45cls参数说明--img 640是输入尺寸小目标多可以提到 1024但显存翻倍--batch 16在 8G 显存上跑 yolov5s 640 大概够爆显存就降到 8--workers是数据加载线程Windows 下设 0 或 2 避免卡死--weights yolov5s.pt用预训练权重45 类数据量不大从头训容易欠拟合。--name决定输出目录方便多组实验对比。4.2 小目标场景下的输入尺寸与 anchor 调整电路板元件普遍偏小640 输入下有些元件缩到十几个像素召回上不去。常见做法是把--img提到 1024 或 1280代价是显存和训练时间。另一个手段是重算 anchorYOLOv5 默认 anchor 基于 COCO对密集小目标不一定最优。训练前跑一次 k-means 聚类自己的框尺寸替换模型配置里的 anchor。# 用自带脚本对训练集标签做 anchor 聚类 python utils/autanchor.py --data ../data.yaml --img 1024 --thr 4.0 --n 9逻辑说明--img要和训练输入一致否则聚类出的 anchor 尺度对不上--n 9是 anchor 数量对应三个检测层的 3×3--thr是聚类阈值值越大框越少。跑完把输出的 anchor 填进models/yolov5s.yaml对应位置。这一步不是必做但小目标召回差的时候值得试比盲目加 epoch 有效。4.3 训练过程看什么指标开训后盯三个数box_loss、obj_loss、mAP0.5。box_loss 震荡不降先查标签坐标obj_loss 高但 cls_loss 低多半是背景误检多可以加负样本或调--rect。mAP0.5 在验证集只有 60 张的情况下波动会大别被单轮数字带偏看趋势。验证集小是这份数据的客观限制60 张图评估 45 类平均每类不到 2 张mAP 的置信区间很宽最终判断建议以测试集 40 张的表现为准或者自己再切一部分训练集出来做交叉验证。5. 避坑与排查45 类数据最容易翻车的五个点5.1 现象训练报 Label class X is out of bounds原因标签里的 class_id 超过了 nc-1或者 classes.txt 行数和 data.yaml 的 nc 不一致。45 类数据里标注工具导出时类别表没对齐很容易出现 id 偏移一位。解决跑 2.3 的校验脚本把所有越界 id 列出来对照 classes.txt 修正同时确认 data.yaml 的 nc 等于 names 长度两者必须同步改。5.2 现象loss 变 NaN训练几轮后崩原因坐标越界或出现 0 宽高框。归一化时如果除了 0或者标注框宽高为 0YOLO 计算 IoU 时会出 NaN。解决校验脚本里加一条bw 0 or bh 0的判断把零面积框删掉或修正。另外学习率过高也会 NaNbaseline 用默认 lr00.01别一上来就调大。5.3 现象验证集 mAP 忽高忽低像开盲盒原因验证集只有 60 张样本量太小单轮评估方差大。45 类里有些类在验证集可能一张都没有那类的 AP 直接是 0拉低整体。解决训练时把--val频率调低比如每 5 轮验一次减少波动干扰最终评估用测试集或者从训练集里 stratified 切一份更大的验证集。别根据单轮 mAP 就决定停训。5.4 现象小元件漏检严重大元件框得挺好原因输入分辨率不够小目标特征在深层下采样后丢失或者 anchor 尺度偏大匹配不上小框。解决先把--img提到 1024 试再看显存是否扛得住然后跑 anchor 聚类替换默认值。如果还不行考虑在模型里加 P2 检测层更高分辨率特征图但这属于改结构先从输入尺寸和 anchor 入手。5.5 现象可视化脚本报 FileNotFoundError原因图片名和标签名对不上。正文里的文件名带_jpg.rf.哈希后缀如果脚本用split(_)[0]之类的方式推标签名会截错。解决统一用os.path.splitext(img_name)[0] .txt取同名标签别做字符串切割。另外确认 images 和 labels 子目录名一致路径拼接别写死绝对路径。6. 进阶用测试集做一次可信评估再决定要不要加数据baseline 跑完别急着看训练日志里的 mAP 就收工。这份数据的测试集 40 张是独立划分的用它做一次干净评估才是这份资源真正的价值点。命令很简单python val.py \ --data ../data.yaml \ --weights runs/train/pcb_45cls/weights/best.pt \ --img 1024 \ --task test \ --save-json--task test让评估走测试集而不是验证集--save-json导出每张图的预测结果方便你逐类看召回。跑完重点看两类指标每类的 AP 和混淆矩阵。45 类里如果有几类 AP 明显低先回去看那几类的可视化框大概率是标注不一致或样本太少。测试集只有 40 张单类样本可能个位数AP 的参考价值有限但混淆矩阵能告诉你哪些类被互相误判——比如不同封装的电感被混在一起这种是类别定义问题加数据也难救得先合并或重定义类别。我一般会拿测试集结果和验证集对比如果测试集 mAP 比验证集低超过 10 个点说明验证集划分有偏或者模型过拟合了验证集那 60 张。这时候要么重新划分要么加正则dropout、weight decay。另一个习惯是每次改完 anchor 或输入尺寸都固定用同一批测试图跑一遍记录每类 AP 的变化别只看总体 mAP。总体涨了但某几类掉了在工业场景里往往不能接受。还有个容易被忽略的点这份数据训练集 1800 张、45 类平均每类 40 张对 YOLO 来说偏少尤其是长尾类别。如果测试集显示某几类 AP 低于 0.3优先补那几类的图而不是无脑加全体数据。补数据时保持标注规范一致别引入新的标注风格。从那以后我每次拿到新数据集都强制先跑一遍标签校验和测试集评估再动模型结构——数据的问题改模型是治不好的。希望这份拆解帮到你少走点调参的弯路。本文还有配套的精品资源点击获取