简介:这是一份面向电路板元器件检测任务的YOLO格式数据集,适合从事工业质检、PCB缺陷识别及小目标密集检测的算法工程师与研究者使用。数据按YOLOv5目录结构组织,可直接投入训练与验证,覆盖保险丝、散热片、IC、电感器、晶体管、电容器等34类元器件,类别定义由classes文件统一给出。压缩包共约2000个文件,以1660个txt标注文件、339张jpg图像和1个可视化py脚本为主,整体约63.56MB,训练集约1500张、验证集约80张、测试集约40张,划分清晰。配套脚本可随机读取一张图片并绘制边界框,无需修改即可运行,便于快速核查标注质量与类别分布。目前已有834人学习下载,适合需要现成数据快速验证模型、开展小目标与密集检测实验的读者参考使用。
1. 电路板元器件检测数据集:34 类小目标密集场景,开箱即用的 YOLO 格式
手里有一批 PCB 板子照片,想训一个能认出保险丝、散热片、IC、电感、晶体管、电容器的检测模型,最耗时的往往不是调网络,而是从零标几千张图。这份资源直接给了一套已经划分好的 YOLO 数据集,34 个元器件类别,训练集约 1500 张、验证集约 80 张、测试集约 40 张,图片和同名 txt 标签一一对应,目录结构按 YOLOv5 的规范摆放,解压就能挂到训练脚本上。它还附了一个可视化 py 文件,随机传一张图进去就能把边界框画出来存到当前目录,脚本不用改。对做小目标检测、密集检测的人来说,这类板级元器件正好是天然的密集小目标场景——元件挨得近、尺寸差异大、背景纹理杂,拿来验证模型在密集排布下的召回能力很合适。下面按「数据长什么样 → 怎么接进训练 → 坑在哪 → 怎么验证」走一遍。
2. 拆开数据集:目录结构、标签格式与 34 类分布
2.1 YOLOv5 目录约定与文件对应关系
这份数据按 YOLOv5 的标准布局组织,核心是 images 和 labels 两个平行目录,训练/验证/测试各一套。图片是 jpg,标签是同名的 txt,文件名主体一致、只换扩展名,这是 YOLO 系列读取标签的硬约定——它不靠索引文件,而是拿图片路径把后缀替换成 .txt 去找标签。所以任何一张图缺了同名 txt,训练时要么报错要么被静默跳过,这点后面避坑章会细说。
典型结构长这样:
pcb_dataset/ ├── images/ │ ├── train/ # 约 1500 张 jpg │ ├── val/ # 约 80 张 jpg │ └── test/ # 约 40 张 jpg ├── labels/ │ ├── train/ # 与 train 图片同名的 txt │ ├── val/ │ └── test/ └── classes.txt # 34 类名称,按行排列classes.txt是类别的黑匣子,行号就是类别索引,第 0 行对应标签里的 class_id 0,以此类推到 33。改类别顺序等于改标签语义,千万别随手重排。
2.2 标签格式:归一化中心点加宽高
每行标签是一个目标,格式为class_id x_center y_center width height,后四个都是相对整图宽高的归一化值,范围 0 到 1。举例,一张 640×480 的图里有个 IC,框左上角 (100, 80)、右下角 (260, 200),换算后中心点是 ((100+260)/2/640, (80+200)/2/480) = (0.281, 0.292),宽高是 (160/640, 120/480) = (0.25, 0.25),那行就是2 0.281 0.292 0.25 0.25(假设 IC 是第 2 类)。
这种归一化写法的好处是图片缩放、letterbox 填充后标签不用重算,训练时按当前输入尺寸反算即可。代价是人工核对时不好直接读,所以可视化脚本才重要。
2.3 34 类的分布特点与检测难点
34 类覆盖保险丝、散热片、IC、电感器、晶体管、电容器等常见板级元件。这类数据的分布有几个共性:一是长尾明显,电容器、电阻这类数量多,散热片、特定 IC 数量少;二是尺寸跨度大,大散热片可能占图 1/4,小电容只有几十像素;三是密集,同一区域可能并排十几个同类元件。
这三点直接决定了训练策略:小目标要靠更高输入分辨率或多尺度特征,密集要靠合适的 NMS 阈值和 anchor 匹配,长尾要靠类别权重或重采样。数据集本身不解决这些,但它把「标注」这一最贵的环节省掉了,让你能把精力放在模型侧。
2.4 用可视化脚本先做一次数据体检
拿到数据别急着训,先跑可视化确认标签没错位。资源里的 py 脚本随机取一张图绘制边界框并保存到当前目录,逻辑大致是读图、读同名 txt、按归一化坐标反算像素框、画矩形和类别名、写回文件。核心片段如下:
import cv2, os, random def draw_one(img_path, label_path, classes): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: cid, xc, yc, bw, bh = line.split() cid = int(cid) # 归一化中心点+宽高 反算 像素左上右下 x1 = int((float(xc) - float(bw) / 2) * w) y1 = int((float(yc) - float(bh) / 2) * h) x2 = int((float(xc) + float(bw) / 2) * w) y2 = int((float(yc) + float(bh) / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, classes[cid], (x1, max(y1 - 5, 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imwrite("vis_" + os.path.basename(img_path), img) classes = [l.strip() for l in open("classes.txt")] img_path = random.choice([os.path.join("images/train", f) for f in os.listdir("images/train")]) draw_one(img_path, img_path.replace("images", "labels").replace(".jpg", ".txt"), classes)参数说明:classes从 classes.txt 读入,顺序必须和标签里的 class_id 对齐;img_path.replace是图片路径到标签路径的映射,靠的就是同名约定。跑几张不同图,重点看框有没有整体偏移、类别名对不对、有没有框跑到图外。框整体偏移通常是宽高和中心点顺序写反了,框跑到图外多半是归一化时除了错的基准尺寸。
3. 接进 YOLOv5/v8 训练:data.yaml、超参与小目标参数
3.1 写对 data.yaml 是第一步
YOLO 训练靠一个 yaml 描述数据位置和类别。这份数据要写三个路径加类别名,路径用绝对路径最稳,相对路径容易因为工作目录不同而找不到:
path: /abs/path/pcb_dataset train: images/train val: images/val test: images/test nc: 34 names: ['fuse', 'heatsink', 'ic', 'inductor', 'transistor', 'capacitor', ...]nc必须等于 names 的长度,也等于 classes.txt 的行数,三者不一致训练会直接报维度错。names 的顺序要和 classes.txt 完全一致,否则模型学到的类别名会张冠李戴。test 段可选,但建议写上,方便训完直接评估。
3.2 小目标与密集场景的关键超参
板级元件小且密,默认超参往往召回偏低。几个值得动的参数:
| 参数 | 默认 | 建议 | 作用 |
|---|---|---|---|
| imgsz | 640 | 960 或 1280 | 提高小目标像素占比 |
| batch | 16 | 按显存下调 | 大 imgsz 时显存吃紧 |
| iou (NMS) | 0.45 | 0.5~0.6 | 密集目标减少误抑制 |
| conf | 0.25 | 0.1~0.2 评估 | 看召回时先压低 |
| mosaic | 1.0 | 保留 | 增强小目标与密集样本 |
imgsz 提到 960 以上对小目标帮助最直接,因为小元件在 640 下可能只剩十几个像素,特征图上一两个格子,很难学。代价是显存和训练时间上升,batch 要相应减小。NMS 的 iou 阈值调高,是为了让挨得近的同类元件不被互相抑制掉——密集检测里这是最常见的漏检来源。
3.3 启动训练与断点续训
以 YOLOv5 为例,命令行大致是:
python train.py \ --data data/pcb.yaml \ --weights yolov5s.pt \ --img 960 \ --batch 8 \ --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml \ --name pcb_exp--weights用预训练权重能明显加快收敛,小数据集从零训容易过拟合。--hyp选 low 增强那套,小数据集上强增强有时反而伤性能,可以两套都试。中断后加--resume续训,它会从 last.pt 接着跑。YOLOv8 的话换成yolo detect train data=pcb.yaml model=yolov8s.pt imgsz=960 epochs=100,参数名略有差异但含义一致。
3.4 训练日志里该盯什么
loss 分三块:box、obj、cls。小目标场景重点看 box loss 是否稳定下降,如果 obj loss 震荡大,往往是密集区域正负样本划分不稳,可以调 anchor 或换更细的特征层。mAP@0.5 看整体,mAP@0.5:0.95 看定位精度。验证集只有 80 张,指标波动会比较大,别被单轮跳变带偏,看趋势。如果训练 mAP 高、验证 mAP 低很多,先怀疑过拟合,加数据增强或减模型容量。
4. 避坑与排查:标签、路径、显存、类别四类翻车
4.1 图片和标签不同名导致样本被静默丢弃
现象:训练能跑起来,但日志里显示的图片数比实际少,或者某些类别几乎学不到。原因:YOLO 靠同名替换找标签,任何一张图没有对应 txt,这张图就被跳过,不报错。解决:训前跑一遍校验,遍历 images 下所有 jpg,检查 labels 下同名 txt 是否存在且非空:
import os for split in ["train", "val", "test"]: img_dir = f"images/{split}" for f in os.listdir(img_dir): if not f.endswith(".jpg"): continue lbl = os.path.join("labels", split, f.replace(".jpg", ".txt")) if not os.path.exists(lbl) or os.path.getsize(lbl) == 0: print("缺失或空标签:", f)4.2 路径写相对导致找不到数据
现象:报No labels found或Dataset not found。原因:data.yaml 里用了相对路径,而训练脚本的工作目录和你以为的不一样。解决:path 一律写绝对路径,train/val/test 相对 path 写。改完先单独跑一次数据加载,确认能读到图再开训。
4.3 大 imgsz 直接 OOM
现象:把 imgsz 提到 1280 后显存爆掉,进程被杀。原因:显存占用大致随 imgsz 平方增长,batch 没同步降。解决:imgsz 翻倍时 batch 至少减半,或者开梯度累积模拟大 batch。实在不够就退回 960,小目标收益和显存之间取平衡。
4.4 类别顺序不一致导致标签语义错乱
现象:可视化时框的位置对,但类别名全错,或者训练后模型把电容认成 IC。原因:data.yaml 的 names 顺序和 classes.txt 不一致,class_id 指向了错误的类。解决:以 classes.txt 为准,逐行核对 names,顺序、拼写、数量三者对齐。改完重新可视化几张确认。
5. 验证与进阶:用测试集量化,再拿可视化脚本做回归
训完别只看训练曲线,拿那 40 张测试集跑一次独立评估,命令是python val.py --data data/pcb.yaml --weights runs/train/pcb_exp/weights/best.pt --img 960 --task test。重点看每类的 P、R、mAP,长尾类如果 R 明显低,说明样本太少,可以考虑对稀有类做复制增强或调类别权重。密集区域漏检多,就回头调 NMS 的 iou 阈值,从 0.45 往上试到 0.6,观察漏检和误检的平衡点。
我自己的习惯是:每次改完超参或数据,都拿可视化脚本随机抽 10 张图重画一遍,肉眼过一遍框。指标涨了但框画歪了的情况不是没有,尤其是改了 imgsz 或做了重采样之后。这个脚本不用改、直接跑,正好当回归检查用。从那以后我每次训完新权重,都强制走一遍「测试集评估 + 随机可视化」这两步,才敢说这版模型能用。希望帮到你。
本文还有配套的精品资源,点击获取