简介:目标检测作为计算机视觉的核心任务,在电力巡检领域正发挥着越来越重要的作用。然而,与通用场景不同,电力设备检测面临目标尺度跨度大、背景复杂、样本不均衡等现实挑战,而数据质量更是直接决定模型性能的天花板。面对一份110kV电力设备目标检测数据集,从解压到训练再到部署,每一步都暗藏陷阱。本文将围绕数据集验证、标注格式转换、YOLOv8参数调优、小目标漏检与类别不均衡处理等关键环节,系统梳理一套可落地的工程实践方案。通过合理的预处理与增强策略,结合迁移学习与切片推理,可有效提升模型在真实巡检场景中的检测精度与泛化能力。无论你是刚接触电力视觉的初学者,还是正在优化检测流程的工程师,这套方法论都能帮助你少走弯路,快速构建可靠的目标检测系统。 最近手头一个巡检项目要用到 110kV电力设备目标检测数据集,从解压 zip 的那一刻开始就没有一刻省心。文件损坏、标注格式不统一、小目标漏检、类别不均衡……一路踩下来,我才算把这条链路完整跑通。这篇文章就把整个过程拆开讲透:数据集拿到手该怎么验货、训练前要做什么准备、YOLOv8 怎么调参、部署推理有哪些现实问题,希望能帮你少走几天弯路。
1. 110kV场景为什么难:先搞清楚模型要面对什么
1.1 背景:从人工巡检到智能巡检的痛点
电网系统的变电设备巡检,过去主要靠人。运维人员带着望远镜、红外测温仪,对着绝缘子、避雷器、导线接头一台一台看,一天能巡检的杆塔和设备数量非常有限。尤其是 110kV 电压等级,设备数量庞大、分布范围广,很多站点在山区或者偏远区域,人工巡检效率低,而且高空设备用肉眼判断缺陷的准确率很依赖个人经验。
近几年无人机巡检和在线监测装置大面积铺开,一次飞行能拍几千张高清照片。图像数量上来了,新的问题也来了:几千张照片靠人一张张看,比到现场巡检还累。目标检测模型的价值就在这——自动把图像里的设备找出来、框出来,再结合后续的分类模型判断有没有破损、污闪、异物悬挂等异常。这就是 110kV 电力设备目标检测数据集存在的核心意义:给检测模型提供足量、有效、有标注的训练素材。
1.2 110kV场景的视觉特征与检测难点
很多人觉得目标检测不就是把物体框出来嘛,通用模型 COCO 上能跑 80 类,电力设备应该也不难。实际做下来,110kV 场景有几个通用数据集覆盖不到的难点。
第一,目标尺度跨度极大。一张无人机拍摄的 4000×3000 图像里,可能同时存在占据画面 1/3 的变压器本体,以及只有几十个像素宽的绝缘子串。检测模型对尺度变化非常敏感,训练时如果输入尺寸设置太小,小目标直接丢失;设置太大,显存和训练时间又扛不住。
第二,背景极其复杂。变电站里设备密集,导线、构架、杆塔互相交错遮挡。模型很容易把背景中的横担、金具误检成目标。再加上逆光、阴影、雨天反光,对模型的泛化能力要求很高。
第三,同类目标外观差异显著。同样是绝缘子,悬式绝缘子、针式绝缘子、支柱绝缘子形态完全不同;同样是避雷器,氧化锌避雷器、阀式避雷器外观也差很多。如果数据集的类别定义不够清晰,模型就会学得非常痛苦。
第四,样本天然不均衡。绝缘子数量多、拍摄角度多,样本丰富;而某些型号的断路器、互感器可能只在个别站点出现过,样本极少。极端类别不均衡下,少数类别的召回率会非常难看。
2. 数据集解剖:拿到 zip 之后先别急着训练
2.1 解压前先验货:文件完整性检查
我拿到的是110kV电力设备目标检测数据集.zip,很多人第一步就是双击解压,结果弹出file is not a zip file或者could not find EOCD,然后就慌了。其实 zip 文件解压报错,不一定是文件坏了,先按照下面的顺序排查。
# 用 file 命令看文件真实类型 file 110kV电力设备目标检测数据集.zip # 用 unzip 测试完整性,不实际解压 unzip -t 110kV电力设备目标检测数据集.zip # 查看压缩包内文件列表 unzip -l 110kV电力设备目标检测数据集.zip如果输出显示Zip archive data,说明文件头正常;unzip -t跑完没有报错,说明压缩包结构完整。最常见的问题是下载过程被中断,浏览器或者下载工具没有把文件写完整,导致 zip 尾部缺少 End of Central Directory(EOCD)记录,unzip就会报could not find EOCD。解决办法很朴素:重新下载,换一个网络环境,或者用支持断点续传的下载工具。
如果重新下载后还是报错,而且你用迅雷、IDM 这类多线程工具下载,大概率是服务器不支持 Range 请求,多线程下载的文件是拼接损坏的。这个时候把下载工具的线程数改成单线程,或者直接用curl -L -C -断点续传:
curl -L -C - -o 110kV电力设备目标检测数据集.zip "实际下载地址"注意:如果你的压缩包设置了密码且来源正规,密码应该由提供方通过正规渠道告知。不要花时间去研究任何破解压缩包密码的方法,既浪费时间也踩红线。
2.2 目录结构与标注格式:一次看明白
解压完成后,先整体看一遍目录结构:
110kV电力设备目标检测数据集/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── classes.txt ├── data.yaml └── README.md这是 YOLO 系列最常见的组织方式。images下放原图,labels下放同名 txt 标注文件,每行一个目标,格式为:
class_id x_center y_center width height所有坐标值都是归一化到[0, 1]的浮点数,即像素坐标除以图像宽高。举个例子,一张 1920×1080 的图上,某个绝缘子框左上角坐标是 (480, 270),右下角是 (960, 810),换算过程是:
x_center = (480 + 960) / 2 / 1920 = 0.375 y_center = (270 + 810) / 2 / 1080 = 0.5 width = (960 - 480) / 1920 = 0.25 height = (810 - 270) / 1080 = 0.5这一行就写成:0 0.375 0.5 0.25 0.5。
打开classes.txt和data.yaml:
# classes.txt insulator arrester transformer circuit_breaker disconnector# data.yaml train: images/train val: images/val nc: 5 names: ['insulator', 'arrester', 'transformer', 'circuit_breaker', 'disconnector']注意:
data.yaml里的train和val路径要写成相对路径。很多新手喜欢写绝对路径,比如C:/Users/xxx/dataset/images/train,换台机器就报错。我习惯把data.yaml放在数据集根目录下,路径就写相对数据集根目录的路径,项目迁移到哪里都能跑。
2.3 数据分布与标注质量:肉眼扫一遍很关键
拿到数据集,不要急着开训。先用脚本统计一下各类别的样本量,心里有个底:
from collections import Counter import os label_dir = "110kV电力设备目标检测数据集/labels/train" class_counter = Counter() total_boxes = 0 for file in os.listdir(label_dir): if not file.endswith(".txt"): continue with open(os.path.join(label_dir, file), "r") as f: for line in f: class_id = int(line.strip().split()[0]) class_counter[class_id] += 1 total_boxes += 1 print("总标注框数:", total_boxes) for cid, cnt in class_counter.items(): print(f"类别 {cid}: {cnt}")我这次看到的情况是:绝缘子占了 70% 以上的标注框,避雷器约 15%,变压器、断路器、隔离开关加起来 15% 左右。这种情况在电力设备数据集里太典型了。
然后还要随机抽 100 张图,打开原图叠加上标注框可视化,这一步不能省。
import cv2 img_path = "110kV电力设备目标检测数据集/images/train/000001.jpg" label_path = "110kV电力设备目标检测数据集/labels/train/000001.txt" img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path, "r") as f: for line in f: cid, cx, cy, bw, bh = map(float, line.strip().split()) x1 = int((cx - bw / 2) * w) y1 = int((cy - bh / 2) * h) x2 = int((cx + bw / 2) * w) y2 = int((cy + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite("check_000001.jpg", img)可视化检查主要看三件事:框是否贴合目标边缘、是否漏标、是否错标。我这次发现了两个问题:有十几张图的标注框整体偏移,大概偏了 20 个像素左右,可能是标注工具导出时坐标系设置错误;另外有部分绝缘子串被标成了一个整框,而另一些是按单串分隔标注的,标签标准不统一。这种不统一会让模型学得左右摇摆,好在数量不多,占比不到 5%,不影响整体训练,但你要知道有这个坑。
3. 训练前准备:环境搭建与数据格式转换
3.1 环境选型:为什么推荐 YOLOv8
电力设备检测领域,YOLO 系列是目前实践中最主流的方案。我推荐 YOLOv8,理由很实际:
- 生态成熟:ultralytics 库把训练、验证、导出打包得很好,新手友好度极高。
- 精度与速度平衡好:电力巡检场景对推理速度有硬性要求,无人机巡检图像量大,单张推理时间不能太高。YOLOv8 的 m/s 曲线比同代 Anchor-based 模型更好。
- 内置增强策略:Mosaic、MixUp、Copy-paste 等增强开箱即用,省了自己写增强的功夫。
- 部署链路完整:可以导出 ONNX、TensorRT、CoreML 等多种格式,后面接边缘盒子或在线服务都方便。
如果你之前用的是 YOLOv5 的代码库,迁移到 YOLOv8 的成本也非常低,数据格式几乎一致,yaml 配置方式相似。
训练环境我用的是:
Python 3.10 PyTorch 2.1.0 CUDA 11.8 ultralytics 8.1.0pip install ultralytics pip install torch==2.1.0 torchvision==0.16.0 --index-url https://download.pytorch.org/whl/cu1183.2 标注格式转换:VOC XML 转 YOLO txt
有些电力数据集给的是 VOC 格式的 XML 标注,而不是 YOLO 的 txt。这种情况下需要先转换。写一个小脚本:
import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_dir, class_names): tree = ET.parse(xml_path) root = tree.getroot() size = root.find("size") width = int(size.find("width").text) height = int(size.find("height").text) lines = [] for obj in root.iter("object"): name = obj.find("name").text if name not in class_names: continue class_id = class_names.index(name) bndbox = obj.find("bndbox") xmin = float(bndbox.find("xmin").text) ymin = float(bndbox.find("ymin").text) xmax = float(bndbox.find("xmax").text) ymax = float(bndbox.find("ymax").text) x_center = (xmin + xmax) / 2 / width y_center = (ymin + ymax) / 2 / height bbox_width = (xmax - xmin) / width bbox_height = (ymax - ymin) / height lines.append(f"{class_id} {x_center:.6f} {y_center:.6f} {bbox_width:.6f} {bbox_height:.6f}") img_name = os.path.splitext(os.path.basename(xml_path))[0] with open(os.path.join(out_dir, f"{img_name}.txt"), "w") as f: f.write("\n".join(lines)) class_names = ["insulator", "arrester", "transformer", "circuit_breaker", "disconnector"] xml_dir = "annotation_xml" out_dir = "labels/train" os.makedirs(out_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if xml_file.endswith(".xml"): voc_to_yolo(os.path.join(xml_dir, xml_file), out_dir, class_names)注意:转换前务必确认 XML 里
size的宽高和实际图片一致。有些标注软件在缩放图片后同步改了显示尺寸,但 XML 里的 size 没有更新,导致坐标全部错位。
3.3 数据划分与 data.yaml 配置
数据集如果已经分好了 train/val,直接用;如果没有,需要手动划分。我一般按 8:2 划分,采用分层抽样,保证验证集里每个类别的比例和训练集接近。用 scikit-learn 很简单:
import os import shutil from sklearn.model_selection import train_test_split image_files = [f for f in os.listdir("images/all") if f.endswith(".jpg")] train_files, val_files = train_test_split(image_files, test_size=0.2, random_state=42, stratify=None) # 如有类别信息可做分层 for f in train_files: shutil.copy(f"images/all/{f}", f"images/train/{f}") shutil.copy(f"labels/all/{f.replace('.jpg', '.txt')}", f"labels/train/{f.replace('.jpg', '.txt')}") # val 同理然后是data.yaml。我建议先写好一份相对路径配置:
path: /absolute/or/relative/path/to/dataset # 可选,如果设置,下面的路径基于此 train: images/train val: images/val nc: 5 names: ['insulator', 'arrester', 'transformer', 'circuit_breaker', 'disconnector']3.4 数据增强策略:针对电力场景的设置
YOLOv8 默认的增强已经不错,但针对 110kV 电力设备场景,我做了两处调整:
- Mosaic 打开:默认开启,推荐保留。Mosaic 可以显著提升小目标的检测能力,但如果你发现验证集上大目标指标降低了,可能是 Mosaic 混出的图片中目标尺寸严重失真,可以尝试降到
mosaic=0.8或者关闭。 - 增加 HSV 增强的饱和度变化:电力设备图像受光线影响大,阴天和晴天的色温差异明显。适当增加
hsv_s=0.7可以让模型对颜色变化更鲁棒,但注意不要调得过大导致图像失真。
训练时不需要自己写增强代码,通过参数控制即可:
hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 0.0 # 电力设备通常竖直安装,不建议旋转太多 translate: 0.1 scale: 0.5我个人不建议把
degrees设得很高。电气设备大多有固定安装方向,旋转 90 度产生的样本在现实中几乎不存在,反而会误导模型。把增强用在颜色、尺度、平移上更有效。
4. 开启一轮训练:关键参数与完整流程
4.1 预训练权重选择:迁移学习是数据集的救星
电力设备数据集通常只有几千张图,几万个标注框,从零训练一个检测器难度很大。迁移学习在这里价值巨大。YOLOv8 官方提供了 COCO 预训练权重,虽然 COCO 里没有绝缘子、避雷器,但模型已经学会了通用的边缘、纹理、形状特征,迁移到电力设备场景时,只需在顶部分类/回归层做调整。
yolo detect train data=data.yaml model=yolov8m.pt epochs=200 imgsz=1280 batch=16这里我选了yolov8m而不是yolov8s或yolov8n,原因在于电力设备的检测难度主要在细节和小目标上,过小的模型容量不够,过大的模型训练和推理成本高。m是平衡点。
选预训练权重时注意一点:下载源要可靠。可以在 ultralytics 的 GitHub Releases 页面下载,或者用命令自动下载。如果你网络环境受限,无法连接外部下载地址,那就只能从能访问的渠道把yolov8m.pt文件拷到项目目录,再用本地路径指定。实际部署时也有用yolov8x跑高精度推理、配合TensorRT加速的,但训练阶段m足够。
4.2 完整训练命令与参数详解
yolo detect train \ data=110kV电力设备目标检测数据集/data.yaml \ model=yolov8m.pt \ epochs=200 \ imgsz=1280 \ batch=16 \ patience=30 \ optimizer=AdamW \ lr0=0.001 \ lrf=0.01 \ save_period=10 \ device=0 \ workers=8 \ seed=42逐个参数说明一下,方便你根据实际调整:
epochs=200:训练轮数。数据集小的时候模型收敛快,如果 200 轮后过拟合了可以提前停止,配合patience使用。imgsz=1280:输入分辨率为 1280×1280。这是提高小目标检测效果最直接的手段。如果显存不够 20GB 以上,建议降到 960 或 1024。我用的是 16GB 显存的卡,batch=16,1280 分辨率刚好能跑。batch=16:批量大小。batch 越大模型训练越稳定,但显存有限。如果 OOM,可以降到 8,同时适当降低学习率。patience=30:如果验证集指标连续 30 个 epoch 没有提升,训练提前结束。防止浪费算力。optimizer=AdamW:YOLOv8 默认 SGD,但 AdamW 在小数据集上收敛更快,调参压力小。lr0=0.001:初始学习率。用 COCO 预训练权重做迁移学习时,学习率不宜太大,否则会破坏预训练特征。save_period=10:每 10 个 epoch 保存一次权重,防止训练中断后从头再来。
如果你只有单张显卡,显存 8GB,建议这样调整:
yolo detect train data=data.yaml model=yolov8m.pt epochs=200 imgsz=960 batch=84.3 评估指标:不要只看 mAP
训练结束后,ultralytics 会在runs/detect/train/目录下生成结果。重点关注几个文件:
results.png:loss 曲线和 mAP 曲线confusion_matrix.png:混淆矩阵val_batch0_pred.jpg:验证集预测可视化weights/best.pt:验证集指标最好的权重
评估时,我经常提醒自己不要只盯着 mAP50。电力设备检测场景中,小目标多、背景复杂,mAP50-95 更能反映模型的真实能力。另外,对每一类单独看 Precision 和 Recall 很有必要:
yolo detect val model=runs/detect/train/weights/best.pt data=data.yaml输出结果里会有per-class的 P、R、mAP50、mAP50-95。如果绝缘子的 mAP 很高但避雷器的 mAP 只有一半,说明类别不均衡的问题没有解决,需要在推理时单独调试置信度阈值,或者回到数据层面补样本。
5. 踩坑记录:从 zip 解压到模型推理的真实教训
5.1 zip 解压报错完整排查链路
这次最折腾我的就是压缩包解压。前两次解压都报了could not find EOCD,当时差点以为是数据集本身有问题,后来一步步排查发现是下载工具开了 32 线程导致的文件损坏。
完整排查链路:
file命令看文件类型,输出data说明文件头损坏,输出Zip archive data说明文件头正常。unzip -l看文件列表,能列出部分文件但数量明显不对,说明文件被截断。- 对比压缩包的文件大小和服务器上显示的 Content-Length,不一致就直接重新下载。
- 重新下载后用
unzip -t全量测试,通过后再解压。
另外一个相关的问题是failed to copy spatial iop zip,这不是压缩包本身的问题,而是解压出来的某个文件正在被其他程序占用,或者目录没有写入权限。检查一下你是不是在解压到系统保护目录,比如C:\Program Files,换个目录解压就好。
5.2 标注坐标归一化:肉眼不可见的误差
有一次我训练之后发现 mAP 一直在 0.6 徘徊,上不去。可视化检查训练数据看不出问题,最后是跑了一遍反向映射检查坐标是否越界才定位到问题:一部分标注文件的 width 或 height 被算成了 0。
原因是标注转换脚本里有个 bug,目标框的xmax和xmin在 XML 里是字符串,直接用除法会报错,但 Python 的float()转换在某些情况下会静默失败,变成一个负数。这种 bug 模型训练时不会报错,只会让 loss 居高不下。
建议你在训练前加一步数据校验:
import os label_dir = "110kV电力设备目标检测数据集/labels/train" invalid = [] for file in os.listdir(label_dir): path = os.path.join(label_dir, file) with open(path, "r") as f: lines = f.readlines() for line in lines: parts = line.strip().split() if len(parts) != 5: invalid.append((file, "字段数不对")) continue cid, cx, cy, bw, bh = map(float, parts) if not (0 <= cx <= 1 and 0 <= cy <= 1 and 0 < bw <= 1 and 0 < bh <= 1): invalid.append((file, "坐标越界")) break print(invalid[:20])5.3 小目标漏检:绝缘子串被整串跳过
第一版模型在验证集上 mAP50 有 0.87,看着不错。但实际把模型接到无人机拍摄的大图上推理时,发现imgsz=1280输入尺度下,远处几十甚至上百像素宽的绝缘子串经常漏检。
排查后发现两个原因:一是训练集中大部分绝缘子标注框的尺寸占比都在 2%~8% 之间,模型对大图中小目标的敏感度不够;二是推理时直接resize到 1280,图像下采样后小目标细节丢失。
解决方案是推理时改用SAHI(Slicing-Aided Hyper Inference),就是把大图切成多个小图块,每个图块单独推理再合并结果。实测下来,漏检率降低了不少。
pip install sahifrom sahi import AutoDetectionModel from sahi.predict import get_prediction, get_sliced_prediction detection_model = AutoDetectionModel.from_pretrained( model_type="yolov8", model_path="runs/detect/train/weights/best.pt", confidence_threshold=0.25, image_size=1280, device="cuda:0", ) result = get_sliced_prediction( "test_large_image.jpg", detection_model, slice_height=640, slice_width=640, overlap_height_ratio=0.2, overlap_width_ratio=0.2, ) result.export_visuals(export_dir="sahi_output/")slice_height和slice_width我建议从 640 起步,overlap至少 0.2,否则切图边缘的目标容易被切掉。
5.4 类别不均衡:少数类召回率拉到 0.5
前面统计过类别分布,避雷器只占 10% 左右。训练后的验证结果里,避雷器的召回率只有 0.5 出头,处于不可用状态。这个问题的解法有两种,我建议都做:
一是数据层过采样。把避雷器样本重复复制进训练集,或者用copy-paste增强,把避雷器目标粘贴到没有该类目标的背景图上。YOLOv8 的copy_paste参数直接设成0.3试试。
二是损失函数层面调整。YOLOv8 没有直接提供类别权重参数,但可以通过修改损失权重或者使用class_weight方式间接实现。更简单的做法是:训练时用全部数据让模型先收敛,然后单独对少数类再做几轮微调,只给少数类样本,降低学习率。
实测下来,过采样 + copy-paste 就能把避雷器的召回率从 0.5 提到 0.7 以上,不必一开始就动损失函数。
5.5 推理部署时的细节:置信度阈值和 NMS
最后再提醒一个很容易被忽略的问题:训练时的置信度阈值和推理时的不一样。
训练阶段,模型会输出大量低置信度候选框,这些框在 loss 计算中都有贡献。而推理阶段,你会设定conf=0.25或者更高,过滤掉低置信度框。这个阈值怎么定,取决于你的业务场景。
- 如果是巡检初筛,宁可误报不可漏报,阈值可以设低一些,比如 0.15~0.2。
- 如果是给后续人工复核提供精准目标,阈值可以设到 0.4 以上,减少误报。
我在实际部署时把两个阈值都测了一遍,最终采用conf=0.25 + 二次过滤:先在低阈值下把候选框全部找出来,再用类别专属阈值过滤。这样兼顾了召回和精度。
6. 从能跑到好用:模型导出与效果优化
6.1 ONNX 导出与推理速度评估
训练结束后,用 best.pt 导出 ONNX:
yolo export model=runs/detect/train/weights/best.pt format=onnx opset=12 imgsz=1280导出后可以用 ONNX Runtime 做一次推理,确认导出结果和 PyTorch 推理一致:
import onnxruntime as ort import cv2 import numpy as np sess = ort.InferenceSession("best.onnx") input_name = sess.get_inputs()[0].name img = cv2.imread("test.jpg") img = cv2.resize(img, (1280, 1280)) img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, HWC to CHW img = np.ascontiguousarray(img, dtype=np.float32) img /= 255.0 img = np.expand_dims(img, axis=0) outputs = sess.run(None, {input_name: img}) print(outputs[0].shape)电力巡检的推理设备通常是边缘盒子(Jetson Orin、瑞芯微 RK3588 等)或服务器 GPU。如果跑 TensorRT,INT8 量化通常可以在精度损失很小的情况下把速度提升 2~3 倍,建议尝试。
6.2 效果优化的三个方向
模型跑通之后,如果想要在复杂场景下更可靠,可以从下面三个方向继续迭代:
数据补采与主动学习。把模型漏检和误检的样本收集起来,定期加入训练集重新训练。这是成本最低、效果最明显的迭代方式。我一般用
conf=0.1的模型去跑新拍的大图,把所有低置信度框的局部图截图保存,人工快速过一遍,把有价值的样本挑出来。多模型融合或者级联。用一个高召回模型负责初筛,再用一个高精度模型对初筛结果二次确认。在算力允许的情况下,这种方式比单模型调参更有效。
引入分割模型辅助检测。绝缘子串经常发生多个目标紧密排列、框互相重叠的情况,交并比阈值一高就被 NMS 删掉了。如果对定位精度有更高要求,可以考虑实例分割模型(YOLOv8-seg),用掩膜替代边界框,重叠目标也能区分。
6.3 针对这份数据集的个性化建议
如果你拿到的也是类似的 110kV 电力设备目标检测数据集,我的建议是:不要指望拿到手就能直接训练出完美模型。先花半天时间做数据检查,统计分布、可视化标注、修正格式问题,这部分投入会在训练阶段成倍回报。
训练时注意控制输入分辨率,优先保证小目标不被压碎;推理时用切片推理解决大图小目标问题;类别不均衡就靠过采样和增强。这几个步骤做下来,模型的基本可用性是可以保证的。后面再根据实际测试集反馈,逐步补充难例,迭代优化到一个稳定的状态。
这些年做目标检测项目,我越来越认同一个朴素的道理:模型架构决定的是精度上限,数据质量决定的是能达到的上限有多高。一份看似普通的 110kV 电力设备数据集,如果能把数据层面的事情做扎实,训练出来的模型在真实巡检场景中完全可以扛起大梁。
本文还有配套的精品资源,点击获取