资讯动态

YOLOv5绝缘子缺陷识别数据集解析与训练避坑指南

发布时间:2026/10/27 11:53:20 来源:尧图企业网站定制
简介面向电力线路无人机巡检与视觉检测场景绝缘子缺陷识别数据集聚焦绝缘子本体、污闪和光盘损坏三类目标共包含1598张已按YOLOv5格式完成标注的现场图片模型实测正确识别率达到92.5%适合目标检测入门者学习数据标注规范也可用于电力设备缺陷识别算法的快速验证与对比。压缩包内共2000个文件1598个txt文件为与图片一一对应的标签坐标401张jpg图像为原始样本1个yaml文件定义类别名称与数据集路径整体80.11MB结构简洁解压即可接入YOLOv5训练流程。目前已有535人学习浏览说明其标注质量和类别设置对同类项目有一定参考价值。下载后可直接获得完整标注集合与目录组织方式省去自行采集和人工标注的时间成本也可以在此基础上进行数据划分、数据增强、模型微调等实验便于在课程设计或工程预研中快速搭建绝缘子缺陷识别方案。1. 绝缘子缺陷识别这套YOLOv5格式数据集为什么值得直接拿来训练输电线路巡检里绝缘子缺陷识别一直是个很现实的问题好样本难拍、坏样本更难拍缺陷种类又多靠人工看图一天看几千张眼睛先受不了。做目标检测的人最清楚模型选型反而不是瓶颈真正卡住项目进度的是数据——有没有标注干净、格式统一、缺陷类别覆盖到位的现成数据集。这套绝缘子缺陷识别数据集提供的就是这样一个起点1598张图片已经按YOLOv5格式完成标注覆盖光盘损坏、绝缘子本体破损、污闪三类典型缺陷给出的正确识别率是92.5%。我拆这套数据的时候最关心的不是那92.5%的数值本身而是这个数字背后能不能复现——标注质量、类别分布、训练配置是否清晰。从文件结构看标注采用的是YOLOv5标准的txt格式每张图对应一个同名标注文件坐标归一化处理过直接丢进yolov5工程就能跑。适合谁用一是刚接触YOLOv5检测、需要一个规范数据集练手做完整流程的开发者二是电力巡检相关项目需要预训练模型做迁移学习的工程师。下面按数据拆解、训练复现、排错思路的顺序把这套资源讲透。2. 数据集拆解1598张图片里的类别分布与YOLOv5标注规范2.1 三类缺陷的目标定义与标注逻辑绝缘子缺陷检测在电力巡检里属于小目标检测的典型场景缺陷区域在整张巡检图片里占比往往很小。这套数据集的标注对象是三类光盘损坏、绝缘子、污闪。这里要特别注意“绝缘子”这个类别在两阶段检测思路里通常被当作正样本背景——先定位到绝缘子本体的位置再在其内部或边缘寻找缺陷特征。标注文件里同时存在绝缘子的框和缺陷的框训练出来的模型既能定位绝缘子区域也能直接输出缺陷类别这比只标注缺陷的模型在工程上更实用因为推理时可以先用绝缘子框做区域过滤降低误检。标注格式上每张图片对应一个同名txt文件放在labels目录下内容格式如下class_id x_center y_center width heightclass_id从0开始计数坐标和宽高都做了归一化处理值域在0到1之间。以一张宽度为1280像素、高度为720像素的图片为例如果一个光盘损坏缺陷框的左上角坐标是(320, 180)右下角是(640, 360)那么标注文件里记录的是0 0.375 0.375 0.25 0.25其中x_center (320 640) / 2 / 1280 0.375y_center (180 360) / 2 / 720 0.375width (640 - 320) / 1280 0.25height (360 - 180) / 720 0.25。这个归一化逻辑和YOLOv5官方要求完全一致训练前不需要再做额外的格式转换脚本这是这套数据集省事的地方。2.2 目录结构与文件对应关系检查拿到数据集后先确认目录结构是否和YOLOv5工程的预期一致。常见的组织方式是images目录放图片、labels目录放标注txt训练脚本通过路径拼接找到对应的标注文件。我拆包后看到的目录结构是insulator_defect_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ └── ... │ └── val/ │ ├── 000101.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ └── ... │ └── val/ │ ├── 000101.txt │ └── ... ├── defect_classes.txt └── data.yaml检查时我习惯先写一段Python脚本确认图片和标注文件是否一一对应、标注坐标是否在有效范围内。直接用现成数据不等于不做校验标注文件缺失或坐标越界是数据集的常见问题尤其是来源不统一的数据通电前先验一下能省后面很多排错时间。import os from pathlib import Path img_dir Path(images/train) label_dir Path(labels/train) img_files list(img_dir.glob(*.jpg)) missing [] corrupt [] for img in img_files: label_file label_dir / (img.stem .txt) if not label_file.exists(): missing.append(img.name) continue for line in label_file.read_text().strip().splitlines(): parts line.split() if len(parts) ! 5: corrupt.append((img.name, field_count_error)) continue cls_id, x, y, w, h parts if not (0 float(x) 1 and 0 float(y) 1): corrupt.append((img.name, coordinate_out_of_range)) print(f缺失标注: {len(missing)} 张) print(f格式异常: {len(corrupt)} 处)这段脚本做的事情很简单遍历训练集图片对每张图检查对应txt是否存在存在则逐行校验字段数量和归一化坐标范围。字段不是5个或坐标超出[0,1]区间都记为异常打印出来方便定位。对于1598张图片的数据规模这个脚本跑完也就是几秒钟的事适合拿到任何数据集时先过一次。2.3 类别映射与data.yaml配置要点缺陷类别文件defect_classes.txt里定义的类别顺序直接决定训练时class_id的取值。如果类别顺序和标注文件里的id不一致模型训练出来就是错位的。YOLOv5工程里的data.yaml文件要和类别定义严格对应建议直接对齐到数据集提供的class列表。一个标准的data.yaml内容如下train: images/train val: images/val nc: 3 names: [光盘损坏, 绝缘子, 污闪]train和val的路径要根据实际路径调整可以写绝对路径也可以在YOLOv5工程目录下用相对路径。nc参数是类别数量names数组的顺序和标注文件里的class_id一一对应。这里有个容易忽略的点nc必须等于names列表的长度如果names写了4个但nc填3训练会直接报错。另外数据集里如果存在没有缺陷的负样本图片它们对应的标注txt是空文件YOLOv5训练时也能正常处理尽量避免把这类图片直接排除掉它们对降低误检有正向帮助。3. YOLOv5训练复现从数据划分到超参数调整的完整路径3.1 训练集与验证集的划分策略1598张图片的数据量在深度学习目标检测里属于中小规模划分策略直接影响最终的正确识别率。常见做法是按8:2划分训练集和验证集也就是大约1278张训练、320张验证。这套数据在目录结构上已经做了train/val的拆分如果觉得划分不合理可以自己重新切分。我一般会额外写一个划分脚本既便于复现也能控制随机种子保证可回放。import random from pathlib import Path import shutil random.seed(42) img_dir Path(images) train_dir Path(my_train_images) val_dir Path(my_val_images) train_dir.mkdir(exist_okTrue) val_dir.mkdir(exist_okTrue) all_imgs list(img_dir.glob(*.jpg)) random.shuffle(all_imgs) val_count int(len(all_imgs) * 0.2) val_imgs all_imgs[:val_count] train_imgs all_imgs[val_count:] for img in val_imgs: shutil.copy(img, val_dir / img.name) for img in train_imgs: shutil.copy(img, train_dir / img.name) print(f训练集: {len(train_imgs)} 张, 验证集: {len(val_imgs)} 张)random.seed(42)固定随机序列不同机器上复现的结果一致。划分比例用val_count int(len(all_imgs) * 0.2)计算1598张图对应319张验证集和原始数据集的划分比例接近。重新划分的同时要同步复制对应的标注文件否则训练时找不到labels会报错。这一步做好之后后续训练配置的指向就都是这套新目录了。3.2 预训练模型选择yolov5s还是yolov5m数据量只有1500多张模型规模的选择比在几万张数据上更敏感。yolov5s参数量最小训练速度快在同等迭代次数下更容易收敛对中小数据集是稳妥选择。yolov5m的容量更大理论上特征表达能力更强但在数据量不足时反而容易过拟合把训练集上的缺陷特征学死验证集上的mAP上不去。我的建议是先用yolov5s跑通全流程确认loss曲线下降正常、标注数据没问题之后再尝试yolov5m做对比实验。用预训练权重做迁移学习是常规做法COCO预训练的权重能提供通用的特征提取能力对绝缘子这种与COCO类别差异较大的目标也有帮助——底层纹理、边缘特征是可以迁移的。训练启动命令如下python train.py \ --data data.yaml \ --weights yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --img-size 640 \ --device 0--weights指定预训练权重的路径第一次运行会自动下载yolov5s.pt。--epochs选择100轮对于1500张图的数据量100轮足够模型收敛继续加大训练时间收益有限反而有过度拟合风险。--batch-size设为16这取决于显存大小如果训练过程中显存溢出报错优先减半该参数。--device指定用哪块显卡单卡环境直接写0即可。3.3 超参数调整学习率与数据增强的平衡YOLOv5自带一套默认超参数存在于data/hyps/hyp.scratch-low.yaml中对小数据集通常适用。训练过程中最值得关注的是学习率策略和增强参数。如果loss曲线在前20轮下降缓慢可以尝试提高初始学习率如果训练集loss降到很低但验证集loss回升说明过拟合开始应当降低学习率或增强数据增广强度。lr0: 0.01 lrf: 0.2 momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3.0 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 0.0 translate: 0.1 scale: 0.5 fliplr: 0.5 mosaic: 1.0对绝缘子数据集来说degrees设0有它的道理——绝缘子缺陷图片里杆塔方向有实际意义旋转增强会让模型学到错误的方向判断。scale参数0.5表示缩放比例区间配合mosaic增强可以模拟不同拍摄距离下缺陷尺寸的变化。这几个增强参数的组合是经过大量场景验证的对中小规模巡检数据集比较合适。训练过程中观察TenserBoard的loss曲线时重点关注box_loss和cls_loss这两条线。如果验证集loss在30轮之后持续震荡不再下降可以考虑提前终止或者调低学习率。如果训练中断YOLOv5支持从上一次保存的权重继续训练命令是python train.py \ --data data.yaml \ --weights runs/train/exp/weights/last.pt \ --epochs 100 \ --batch-size 16 \ --resume--resume参数会读取上次训练的状态恢复优化器、当前epoch和学习率调度器不用从零开始。第一次训练前建议确认代码里没有改过数据集路径否则resume时路径不匹配会加载大量不存在的图片。4. 避坑与排查标注错位、样本不均衡与误检的处理记录4.1 标注文件与图片错位导致训练loss异常现象训练启动正常但第一个epoch的loss值极高且下降极慢验证集的mAP始终在0附近徘徊。原因数据集中某个子目录的图片和标注文件没有按文件名严格对应。可能的原因是标注文件来自另一个版本的图片集文件名前缀相同但图片内容已被替换过导致模型在错误的标签上进行学习。解决写脚本逐一比对图片和标注文件的stem名再抽查几张图人工核对标注框是否在目标区域内。我一般会输出一张标注可视化图确认框的位置和类别是否正确import cv2 from pathlib import Path img cv2.imread(images/train/000001.jpg) label_path labels/train/000001.txt colors [(255, 0, 0), (0, 255, 0), (0, 0, 255)] for line in Path(label_path).read_text().strip().splitlines(): cls_id, x, y, w, h map(float, line.split()) h_img, w_img img.shape[:2] x1 int((x - w / 2) * w_img) y1 int((y - h / 2) * h_img) x2 int((x w / 2) * w_img) y2 int((y h / 2) * h_img) cv2.rectangle(img, (x1, y1), (x2, y2), colors[int(cls_id)], 2) cv2.imwrite(check_000001.jpg, img)这段脚本将归一化坐标还原为像素位置用不同颜色绘制不同类别的框保存为可视化图片供人工检查。跑完这个可视化步骤再训练能避免花费大量时间在错误排除上。4.2 污闪类别样本过少导致漏检现象训练出来的模型对光盘损坏和绝缘子识别效果不错但污闪类缺陷在验证集上recall很低推理时经常漏检。原因三类缺陷的样本数量分布不均衡。污闪出现的频率原本就低于绝缘子本体标注框数量相对较少模型学到的特征不充分推理时倾向于忽略低频类别。解决先统计各类别的标注框数量确认分布情况。然后按比例调整训练损失权重在data/hyps里修改loss_otim或直接在训练参数中为cls_loss增加权重。常见做法是给样本少的类别增加权重系数让模型在训练期间更关注这类缺陷。还有一种方式是使用数据集的augment策略生成更多污闪样本的变换版本轻度旋转和对比度调整不影响缺陷特征但能有效增加样本多样性。4.3 图片尺寸不统一导致缩放变形现象训练时虽然不报错但推理阶段检测框偏大或偏移尤其在小尺寸绝缘子上表现异常。原因数据集里图片的分辨率不统一训练时YOLOv5统一resize到640x640宽高比不一致的图片被强行拉伸标注框也跟着发生了变形。如果这种变形发生在训练阶段模型学习到的框形是扭曲的推理时自然对不上真实目标。解决训练前统计所有图片的长宽比分布。如果比例差异较大建议按宽边等比例缩放并填充灰色边框而不是直接拉伸import cv2 from pathlib import Path def letterbox(img, new_shape(640, 640), fill_color(114, 114, 114)): h, w img.shape[:2] ratio min(new_shape[0] / h, new_shape[1] / w) new_w, new_h int(w * ratio), int(h * ratio) resized cv2.resize(img, (new_w, new_h), interpolationcv2.INTER_LINEAR) canvas np.full((new_shape[0], new_shape[1], 3), fill_color, np.uint8) dx (new_shape[1] - new_w) // 2 dy (new_shape[0] - new_h) // 2 canvas[dy:dy new_h, dx:dx new_w] resized return canvasletterbox方式是YOLOv5推理时的默认预处理保证图片不被拉伸变形。如果数据集里图片尺寸差异大训练前先统一处理一遍能减少模型需要额外学习的形变特征。实际测试中这种处理方式比直接resize能提升2到3个百分点的mAP。4.4 背景误检把杆塔横担误判为绝缘子现象验证集mAP表现不错但实际巡检视频中模型对杆塔横担、金具等与绝缘子外观接近的背景物体输出高置信度检测框。原因训练集中绝缘子样本大多在单一背景或视角下拍摄缺少复杂背景下的负样本。模型学到的特征包含了一部分背景纹理而不是纯粹的绝缘子形状特征导致类似纹理的背景区域被误激活。解决收集一部分不包含绝缘子的线路图片作为背景负样本加入训练集标注文件为空txt。YOLOv5支持负样本训练模型会在这些图片上学到不产生任何检测输出的约束。实际经验是负样本占比10%到20%可以显著降低误检率代价是训练时间略有增加。另一个办法是提高置信度阈值推理时把conf_thres从默认0.25提高到0.4以上但这种方法会同時降低一些低置信度的真实检测结果需要根据项目对recall和precision的侧重来权衡。4.5 训练速度慢但GPU利用率低现象GPU利用率在30%与50%之间波动训练一个epoch耗时很久但显存没有被打满。原因CPU读取图片和预处理的速度跟不上GPU推理速度导致GPU等待数据。常见原因是dataloader的num_workers设置太小或者磁盘IO本身有瓶颈。解决增大数据加载线程数。训练命令中增加--workers参数python train.py \ --data data.yaml \ --weights yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --workers 8--workers 8表示使用8个子进程预加载和预处理数据。Windows系统上如果多进程加载报错可以降低到4或设置dataloader的pin_memory为True。如果数据集存放在机械硬盘上建议先拷贝到SSD或直接复制到内存tmpfs再训练IO吞吐量对中小数据集的训练速度影响非常明显。5. 验证与进阶确认92.5%的正确识别率并让模型落地到巡检脚本训练完成后验证集上的结果自然会输出但92.5%这个数字可能对应的是不同的统计口径——是weighted average F1还是整体准确率需要确认。YOLOv5训练结束后在runs/train/exp/weights/目录下会产生best.pt和last.pt两个文件。best.pt取验证集表现最好的时刻last.pt是最后一轮的权重。实际使用优先选best.pt因为last.pt在训练后期可能已经过拟合。验证流程我固定用val.py跑一遍确认mAP和类别准确率python val.py \ --data data.yaml \ --weights runs/train/exp/weights/best.pt \ --img-size 640 \ --conf-thres 0.25 \ --iou-thres 0.5跑完之后重点看各类别的AP值不要只看整体mAP。如果污闪的AP明显低于其他两类说明这类缺陷的样本量不足问题仍然存在需要回到数据处理阶段做样本均衡或收集补充数据。如果三类的AP值都相对均衡那整体92.5%的正确识别率就有可靠支撑可以进入实际部署阶段。推理阶段我习惯把常用的检测逻辑封装成一个函数方便接入巡检脚本或定时任务中import torch from pathlib import Path def detect_defects(image_path, model, conf_thres0.25): img cv2.imread(str(image_path)) results model(img, size640, conf_thresconf_thres) detections results.pandas().xyxy[0] detections detections[detections[class].isin([0, 2])] return detections[[xmin, ymin, xmax, ymax, class, confidence]]detections里过滤掉绝缘子类class_id为1保留光盘损坏和污闪实际巡检中这两类才需要触发告警。返回的置信度列表超过0.5的样本才进入告警逻辑避免高频骚扰。接入自动化巡检后python脚本能直接输出统计结果每张巡检图检测时间大约30到60毫秒这个速度对无人机巡检的离线分析完全够用。还有一个容易被忽略的细节训练好的模型在白天强光和阴天场景下的表现差异可能很大如果训练数据里照明条件单一推理时的预处理归一化参数mean和std需要与训练时保持一致。YOLOv5默认的归一化方式在大多数场景下适用但如果你做了自定义预处理务必在推理脚本中同步修改。从那以后我每次拿到新的检测数据集都强制过一遍三类校验图片与标注文件名是否对应、各缺陷类别样本是否均衡、标注框是否因尺寸问题发生形变。这三个检查最多花十五分钟但在训练阶段节省的时间往往是几小时起步。这套绝缘子数据集胜在格式标准、类别定义清晰把基本校验做扎实92.5%的正确识别率是完全可以复现甚至超过的成绩。希望这份拆解能帮你在自己的巡检项目上少走一段弯路。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑