简介:本资源为面向电力巡检与目标检测方向的YOLO绝缘子缺陷检测数据集,适合从事电力设备智能巡检研究的学生、算法工程师及竞赛选手使用,可解决绝缘子缺陷样本获取难、标注格式不统一的问题。压缩包共2000个文件,约57.16MB,包含1000张真实场景高质量图片,以及voc格式xml、yolo格式txt等标注文件,另附yaml配置文件、Python划分脚本与html教程文档,覆盖数据标注、格式转换到模型训练的完整链路。资源已吸引853人学习下载,配套训练集、验证集、测试集划分脚本,可按需重新切分数据,并附Windows与Linux双平台的YOLO环境搭建及训练案例教程,帮助读者快速将数据集接入YOLO系列模型并复现训练流程,同时理解三种标签格式的对应关系与目录组织方式,为后续模型调优与工程落地提供可靠的数据基础。
1. 拆开这个绝缘子数据集:1000 张图、三套标签和一套能跑通的训练链路
电力巡检的兄弟多半遇到过这种场景:无人机拍回来几百张绝缘子照片,想用 YOLO 训一个缺陷检测模型,结果卡在第一步——没有标注好的数据。自己标吧,1000 张图用 labelImg 一张张画框,眼睛都花了;网上找的开源数据集要么是通用 COCO 里挑出来的几张,要么格式对不上,VOC 的 xml 转 YOLO 的 txt 又得写脚本。这个资源包就是冲着这个痛点来的:1000 张真实电力场景的绝缘子图片,用 labelImg 标注,同时给了 voc(xml)、coco(json)、yolo(txt) 三种格式标签,还附了数据集划分脚本和 Linux/Windows 两套环境搭建与训练教程。适合谁?刚接触 YOLO 目标检测、手头有电力巡检需求、想快速跑通「数据→训练→推理」全流程的工程师。下面我按自己拆包复现的顺序,把这份资源从结构到落地讲清楚。
2. 数据集结构与三种标签格式:先搞懂目录再动手
2.1 目录布局与文件对应关系
拿到压缩包解压后,第一件事不是急着跑训练,而是把目录结构摸清楚。这类数据集常见的组织方式是按格式分文件夹,图片和标签分开存放。我拆过的包大致是这样:
dataset/ ├── images/ # 原始图片,1000 张 jpg ├── annotations_voc/ # VOC 格式 xml 标签 ├── annotations_coco/ # COCO 格式 json 标签 ├── labels_yolo/ # YOLO 格式 txt 标签 ├── ImageSets/ # 划分后的 txt 列表 │ ├── train.txt │ ├── val.txt │ └── test.txt └── scripts/ # 划分脚本关键点在于:图片只有一份,三套标签是同一批标注的不同导出格式。labelImg 本身支持 PascalVOC 和 YOLO 两种保存格式,COCO 的 json 一般是 VOC 转出来的。所以三套标签的框坐标本质一致,只是表达方式不同。理解这一点,后面转换和校验才不会乱。
2.2 VOC、COCO、YOLO 三种格式的差异与选用
三种格式的核心区别在坐标表示和文件组织:
| 格式 | 文件类型 | 坐标表示 | 坐标基准 | 适用场景 |
|---|---|---|---|---|
| VOC | 每图一个 xml | xmin,ymin,xmax,ymax | 绝对像素 | labelImg 默认、传统检测框架 |
| COCO | 单个 json | x,y,width,height | 绝对像素 | 多任务、实例分割、pycocotools 评估 |
| YOLO | 每图一个 txt | cx,cy,w,h | 归一化 0~1 | YOLO 系列训练直接读取 |
YOLO 格式的归一化坐标是新手最容易翻车的地方。cx、cy 是框中心点相对图宽图高的比例,w、h 是框宽高相对图宽图高的比例,全部在 0 到 1 之间。如果你直接把 VOC 的像素坐标塞进 txt,训练时 loss 会直接炸掉或者模型完全不收敛。这个包里三套格式都给了,省去了自己转的麻烦,但用之前一定要抽查几个文件确认坐标范围。
2.3 用脚本校验标签一致性
在正式划分之前,我习惯先写个小脚本抽查标签是否对齐。下面这段代码读取一张图的 YOLO 标签,把归一化坐标还原成像素框,再和 VOC 的 xml 对比,确认两者描述的是同一个目标:
import os import xml.etree.ElementTree as ET from PIL import Image img_path = "dataset/images/000001.jpg" yolo_path = "dataset/labels_yolo/000001.txt" voc_path = "dataset/annotations_voc/000001.xml" # 读图片尺寸,YOLO 归一化坐标需要乘回宽高 w, h = Image.open(img_path).size print(f"图片尺寸: {w}x{h}") # 解析 YOLO txt with open(yolo_path) as f: for line in f: cls, cx, cy, bw, bh = map(float, line.split()) # 还原为像素坐标 xmin = (cx - bw / 2) * w ymin = (cy - bh / 2) * h xmax = (cx + bw / 2) * w ymax = (cy + bh / 2) * h print(f"YOLO 还原框: {xmin:.1f},{ymin:.1f},{xmax:.1f},{ymax:.1f}") # 解析 VOC xml tree = ET.parse(voc_path) for obj in tree.findall("object"): name = obj.find("name").text bbox = obj.find("bndbox") xmin = float(bbox.find("xmin").text) ymin = float(bbox.find("ymin").text) xmax = float(bbox.find("xmax").text) ymax = float(bbox.find("ymax").text) print(f"VOC 框 [{name}]: {xmin:.1f},{ymin:.1f},{xmax:.1f},{ymax:.1f}")逻辑说明:YOLO 的 cx、cy、bw、bh 都是相对整图的归一化值,乘以宽高才能和 VOC 的绝对像素坐标对齐。参数上注意map(float, ...)处理的是每行五个值,第一个是类别索引。如果两边框的像素坐标差在几个像素以内,说明标注一致;差得离谱,要么是标签没对齐,要么是图片被 resize 过而标签没同步更新。这一步花五分钟,能省掉后面训练几小时的无效等待。
3. 数据集划分脚本:train/val/test 怎么切才不翻车
3.1 划分脚本的三种模式
包里给了三个划分脚本,名字就能看出用途:训练集、验证集、测试集划分脚本(图片标签划分写入新文件夹).py、训练集、验证集划分脚本(图片标签划分写入新文件夹).py、split_train_val生成ImageSets下txt文件划分脚本.py。前两个是物理复制文件到新文件夹,第三个是只生成 ImageSets 下的 txt 列表文件,不移动图片。
这两种思路各有适用场景。物理复制的好处是划分结果直观,每个子文件夹里图片和标签成对出现,适合直接喂给某些要求固定目录结构的训练框架。生成 txt 列表的好处是不占额外磁盘空间,YOLO 官方训练脚本就是读 txt 列表的。我一般优先用 txt 列表方式,1000 张图虽然不大,但养成不复制数据的习惯,以后上万张图时磁盘不会爆。
3.2 按比例划分并固定随机种子
划分最怕的是每次跑结果不一样,导致实验无法复现。下面是我改写过的划分脚本,核心是固定随机种子,并按 8:1:1 切分:
import os import random random.seed(42) # 固定种子,保证每次划分结果一致 img_dir = "dataset/images" label_dir = "dataset/labels_yolo" out_dir = "dataset/ImageSets" os.makedirs(out_dir, exist_ok=True) # 收集所有图片名(不含扩展名),确保标签存在 names = [] for f in os.listdir(img_dir): if f.endswith(".jpg"): stem = os.path.splitext(f)[0] if os.path.exists(os.path.join(label_dir, stem + ".txt")): names.append(stem) random.shuffle(names) n = len(names) n_train = int(n * 0.8) n_val = int(n * 0.1) splits = { "train": names[:n_train], "val": names[n_train:n_train + n_val], "test": names[n_train + n_val:] } for split, items in splits.items(): with open(os.path.join(out_dir, split + ".txt"), "w") as f: for stem in items: # 写绝对路径或相对路径,按训练脚本要求调整 f.write(os.path.join(img_dir, stem + ".jpg") + "\n") print(f"{split}: {len(items)} 张")逻辑说明:random.seed(42)是复现的关键,不固定种子的话每次划分不同,模型指标波动你都不知道是数据划分导致的还是模型本身的问题。参数上 8:1:1 是常见起点,数据量小的时候可以调成 7:2:1 让验证集多一点。注意写入 txt 的路径要和训练脚本里的读取逻辑匹配,有的 YOLO 版本要求图片路径,有的要求图片和标签路径成对,改之前先看训练脚本怎么读。
3.3 划分后的完整性检查
划分完别急着训练,先做两件事。第一,确认 train、val、test 三个列表没有交集,否则验证集里出现训练过的图,指标虚高。第二,确认每个列表里的图片都能找到对应标签。下面这段检查脚本我每次划分后都跑:
def check_split(txt_path, img_dir, label_dir): with open(txt_path) as f: lines = [l.strip() for l in f if l.strip()] stems = [os.path.splitext(os.path.basename(l))[0] for l in lines] # 检查重复 assert len(stems) == len(set(stems)), f"{txt_path} 存在重复" # 检查图片和标签是否都存在 missing = [] for s in stems: if not os.path.exists(os.path.join(img_dir, s + ".jpg")): missing.append(s + ".jpg") if not os.path.exists(os.path.join(label_dir, s + ".txt")): missing.append(s + ".txt") print(f"{txt_path}: {len(stems)} 条, 缺失 {len(missing)}") return set(stems) train = check_split("dataset/ImageSets/train.txt", img_dir, label_dir) val = check_split("dataset/ImageSets/val.txt", img_dir, label_dir) test = check_split("dataset/ImageSets/test.txt", img_dir, label_dir) # 检查交集 print("train∩val:", len(train & val)) print("train∩test:", len(train & test)) print("val∩test:", len(val & test))逻辑说明:assert那行拦截重复项,交集检查拦截数据泄漏。三个交集都应该是 0。如果发现交集不为 0,说明划分脚本有 bug 或者手动改过列表。这一步是血泪经验,我曾经因为验证集混进训练图,模型在验证集上 mAP 0.95,一上测试集掉到 0.6,排查了半天才发现是划分问题。
4. 环境搭建与训练:Linux 和 Windows 两条路
4.1 Linux 下的环境搭建要点
包里给了YOLO环境搭建Linux版本.html和Linux之Ubuntu环境安装教程.html。Linux 下搭 YOLO 环境,核心是 CUDA、cuDNN 和 PyTorch 版本三者对齐。常见做法是用 conda 建独立环境,避免污染系统 Python:
conda create -n yolo python=3.9 -y conda activate yolo # 根据显卡驱动版本选 CUDA 版本,这里以 CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics opencv-python lxml逻辑说明:python=3.9是 YOLOv5/v8 都兼容的版本,太新或太旧都可能遇到依赖冲突。--index-url指定 PyTorch 官方 CUDA 源,比默认源快且版本明确。装完用python -c "import torch; print(torch.cuda.is_available())"验证,输出 True 才算 GPU 可用。如果输出 False,八成是 CUDA 版本和驱动不匹配,nvidia-smi看驱动支持的 CUDA 上限,别超过它。
4.2 Windows 下的环境搭建与 Anaconda 配置
Windows 版本教程对应YOLO环境搭建Windows版本.html。Windows 下我强烈建议用 Anaconda,因为原生 pip 装 CUDA 相关包容易出玄学问题。步骤和 Linux 类似,但有几个 Windows 特有的坑:路径里的反斜杠在 Python 字符串里要转义,或者统一用正斜杠;num_workers设大于 0 有时会卡死,Windows 下建议设 0 或 2。
conda create -n yolo python=3.9 -y conda activate yolo pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics逻辑说明:Windows 下ultralytics会自动装依赖,但 opencv 有时需要单独pip install opencv-python。验证 GPU 可用性和 Linux 一样。如果遇到DLL load failed,通常是 Visual C++ Redistributable 没装,去微软官网下最新的装上。
4.3 用案例数据跑通第一次训练
环境好了之后,别急着上自己的数据,先用包里教程的案例跑一遍,确认链路通。YOLOv8 的训练命令很简洁:
yolo detect train \ data=dataset.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ project=runs/insulator \ name=exp1逻辑说明:data=dataset.yaml是数据集配置文件,里面写 train、val、test 的 txt 路径和类别名。model=yolov8n.pt用 nano 版本先跑通,速度快,确认没问题再换 s 或 m。imgsz=640是输入尺寸,绝缘子缺陷目标通常不大,640 够用,显存紧张可以降到 416。batch=16按显存调,8G 显存跑 640 大概能到 16。project和name控制输出目录,方便对比不同实验。
dataset.yaml 的内容大致是:
path: /home/user/dataset train: ImageSets/train.txt val: ImageSets/val.txt test: ImageSets/test.txt nc: 1 names: ['defect']逻辑说明:nc是类别数,绝缘子缺陷检测通常就一类「缺陷」,如果区分自爆、破损等可以改。names的顺序要和标签里的类别索引对应,YOLO 标签第一列是索引,0 对应 names[0]。这里最容易翻车的是路径,path是根目录,train/val 是相对路径,写错了会报找不到文件。
4.4 训练过程监控与指标解读
训练启动后,终端会打印每个 epoch 的 loss 和 mAP。重点看三个指标:box_loss 持续下降说明框回归在学;cls_loss 下降说明分类在学;mAP50 上升说明整体检测能力在提升。如果 box_loss 不降反升,检查学习率是不是太大,或者标签坐标有没有越界。如果 mAP 一直上不去,先确认验证集标签格式对不对,再考虑加数据增强。
训练完在runs/insulator/exp1/weights/下会有best.pt和last.pt。best.pt 是验证集指标最好的权重,推理用它。下面这段代码跑单张图推理,确认模型真的能检出缺陷:
from ultralytics import YOLO model = YOLO("runs/insulator/exp1/weights/best.pt") results = model("dataset/images/000001.jpg", conf=0.25) results[0].save("output.jpg") for box in results[0].boxes: print(f"类别: {box.cls}, 置信度: {box.conf:.2f}, 坐标: {box.xyxy}")逻辑说明:conf=0.25是置信度门限,低于这个值的框不输出。绝缘子缺陷检测里,门限调低召回高但误检多,调高误检少但漏检多,实际部署时按业务容忍度调。box.xyxy是左上右下像素坐标,可以直接画到原图上。
5. 避坑与排查:绝缘子数据集训练常见的五个翻车点
5.1 现象:训练 loss 为 nan 或直接不收敛
原因:YOLO 标签坐标越界,归一化值大于 1 或小于 0。labelImg 导出 YOLO 格式时,如果框画到了图片边界外,坐标可能超出 0~1 范围。解决:写脚本扫描所有 txt,把越界坐标 clamp 到 [0,1],或者直接删掉这些异常标注重新标。我一般用awk快速扫:
awk '{if($2<0||$2>1||$3<0||$3>1||$4<0||$4>1||$5<0||$5>1) print FILENAME": "$0}' dataset/labels_yolo/*.txt5.2 现象:验证集 mAP 很高但测试集一塌糊涂
原因:数据泄漏,train 和 val 有重叠图片,或者同一张图的不同增强版本同时进了 train 和 val。解决:跑 3.3 节的交集检查脚本,确保三个集合互斥。另外划分前先按图片去重,同一场景连拍的相似图要分到同一个集合,否则验证集指标虚高。
5.3 现象:训练时提示找不到标签文件
原因:txt 列表里的路径和实际标签路径不匹配。有的脚本写的是图片路径,训练框架自动把images替换成labels找标签,如果你的目录名不是这个约定,就找不到。解决:要么改目录名对齐约定,要么改训练脚本的路径解析逻辑。最稳的办法是 txt 里直接写图片绝对路径,标签路径按规则推导。
5.4 现象:GPU 显存够但训练报 OOM
原因:batch或imgsz设太大,或者num_workers太多导致内存爆。解决:先降 batch 到 8 或 4,再降 imgsz 到 416。Windows 下num_workers设 0 能规避多进程卡死。另外检查是不是同时跑了多个训练任务占显存。
5.5 现象:推理时框位置偏移或框到背景
原因:训练时的 imgsz 和推理时的 imgsz 不一致,或者标签坐标在 resize 时没同步缩放。解决:训练和推理用同一个 imgsz,YOLO 内部会自动处理 letterbox 缩放,但如果你自己预处理过图片,要确保标签也跟着缩放。推理时conf门限太低也会框到背景,适当调高到 0.3~0.5 试试。
6. 从跑通到用好:置信度门限调优与批量推理技巧
模型训完只是开始,真正落地时置信度门限的调整比训练本身还磨人。绝缘子缺陷检测有个特点:缺陷目标通常只占图片一小块,背景是大片天空或杆塔,模型容易把纹理误判成缺陷。我一般会先在验证集上跑一遍不同门限的指标,画个 P-R 曲线找平衡点。下面这段代码批量推理验证集,输出不同 conf 下的检出数量,帮你判断门限该设多少:
from ultralytics import YOLO import os model = YOLO("runs/insulator/exp1/weights/best.pt") val_dir = "dataset/images" confs = [0.1, 0.25, 0.4, 0.5, 0.6] for conf in confs: total_boxes = 0 for f in os.listdir(val_dir): if f.endswith(".jpg"): r = model(os.path.join(val_dir, f), conf=conf, verbose=False) total_boxes += len(r[0].boxes) print(f"conf={conf}: 总检出框数 {total_boxes}")逻辑说明:verbose=False关掉每张图的打印,避免刷屏。观察总框数随 conf 的变化,如果从 0.25 到 0.4 框数骤降,说明很多框置信度在 0.25~0.4 之间,这些多半是误检,门限可以往 0.4 靠。如果框数很平稳,说明模型置信度分布比较集中,门限选择不敏感。实际部署时我习惯把门限设得比验证集最优值略高一点,宁可漏检几个也不让误检触发告警,毕竟巡检工人跑一趟现场的成本远高于漏掉一个可疑框。
还有一个技巧是批量推理时把图片尺寸统一。绝缘子图片如果来自不同相机,分辨率可能不一致,推理前统一 resize 到训练时的 imgsz,能避免 letterbox 引入的额外偏移。另外model.predict支持传文件夹路径,一次跑完整个目录,比循环单张快不少。最后提醒一句:这个数据集只有 1000 张,训出来的模型泛化能力有限,实际项目里我一般会先用它跑通流程,再拿现场数据做增量训练,效果才稳。从那以后我每次拿到新数据集,都强制先跑一遍标签校验和划分检查,再开始训练——这个习惯帮我省了太多返工时间。希望帮到你。
本文还有配套的精品资源,点击获取