ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

无人机航拍行人检测数据集:1000张图三套标签与YOLO训练全链路

无人机航拍行人检测数据集:1000张图三套标签与YOLO训练全链路 简介这份资源面向无人机航拍场景下的行人检测任务适合正在做目标检测课程设计、毕业设计或算法验证的学生与开发者。数据集采集自真实航拍视角场景丰富图片均经labelimg精细标注并同步提供voc、coco、yolo三种格式标签可直接接入YOLO系列模型训练省去格式转换的繁琐环节。压缩包共2000个文件约376MB以1000个xml标注文件和990个txt标签文件为主另含少量html教程、py划分脚本与yaml配置文件覆盖数据标注、格式转换到训练配置的完整链路。资源附赠环境搭建与训练案例教程以及训练集、验证集、测试集划分脚本可按需自行切分数据。目前已有1120人学习下载适合希望快速跑通航拍行人检测流程、验证模型效果的读者参考使用。1. 无人机航拍行人检测数据集1000 张图、三套标签和一条能跑通的训练链路拿到一个无人机航拍行人检测数据集最怕的不是图片少而是标签格式对不上、划分脚本跑不通、训练脚本报维度错误。这个标题里的东西拆开看很实在1000 张航拍视角图片配 VOC、COCO、YOLO 三种格式标签外加划分脚本和训练教程。它解决的是从「有一堆图」到「模型能收敛」之间那段最磨人的工程链路。适合两类人一类是想快速验证 YOLO 在俯视小目标场景下表现的算法工程师另一类是手里有航拍素材、想自己标数据做行人检测的落地开发者。航拍行人检测和地面监控最大的区别是目标尺度小、遮挡密、视角倾斜1000 张图不算多但足够把数据管线和训练流程跑通后面换自己的数据只是替换路径的事。2. 三种标签格式到底怎么选VOC、COCO、YOLO 的差异与转换逻辑2.1 为什么同一个数据集要同时给三种格式VOC、COCO、YOLO 三种格式不是重复劳动它们对应不同的训练框架和评估工具。VOC 格式用 XML 存每张图的标注结构直观很多老牌检测框架和标注工具默认吃这套COCO 格式用单个 JSON 管全部图片和标注字段多但生态最广pycocotools 评估、COCO 预训练权重加载都靠它YOLO 格式最轻每张图一个 txt每行类别 x_center y_center width height坐标全部归一化到 0 到 1训练时直接读不用再解析 XML 或 JSON。我一般会这样分工标注阶段用 VOC 或 COCO 存原始标注训练 YOLO 系列时转成 YOLO txt需要跑 COCO mAP 评估或者加载 COCO 预训练模型时再转回 COCO JSON。三种格式同时给省掉的是你自己写转换脚本的时间但前提是你得知道它们之间哪些信息会丢。2.2 三种格式的字段对照与转换时的坐标陷阱先看一张表把三种格式的核心字段对齐维度VOC XMLCOCO JSONYOLO TXT图片信息每图一个 XML含 filename、sizeimages 数组统一存不存靠文件名对应标注位置object 下 bndboxxmin/ymin/xmax/ymaxannotations 下 bbox[x,y,w,h] 左上角加宽高每行 class xc yc w h归一化类别object 下 name 字符串categories 数组id 从 1 开始行首 class_id从 0 开始坐标单位像素绝对值像素绝对值0 到 1 归一化一图多标多个 object 节点多条 annotation靠 image_id 关联多行转换时最容易翻车的是坐标归一化和类别 id 偏移。VOC 的 xmin/ymin/xmax/ymax 转 YOLO 要算中心点和宽高再除以图宽图高COCO 的 bbox 是左上角加宽高转 YOLO 要先加一半宽高得到中心点。类别 id 上COCO 从 1 开始YOLO 从 0 开始直接照搬会整体错一位训练时类别全乱。下面是一段 VOC 转 YOLO 的核心逻辑实际脚本里会遍历目录批量处理import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, img_w, img_h, class_list): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in class_list: continue cls_id class_list.index(cls_name) # YOLO 类别从 0 开始 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) # 转中心点加宽高再归一化 xc (xmin xmax) / 2.0 / img_w yc (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {xc:.6f} {yc:.6f} {w:.6f} {h:.6f}) return lines这段代码里class_list的顺序决定了类别 id必须和训练时的 data.yaml 里 names 顺序完全一致否则模型学到的类别和评估时对不上。img_w和img_h要从对应图片读不能硬编码航拍图分辨率不统一时硬编码会让所有框偏移。归一化保留 6 位小数是 YOLO 官方脚本的习惯精度足够再多了训练时也会被截断。2.3 划分脚本怎么用训练验证测试的比例与随机种子数据集划分脚本通常做一件事把图片和标签按比例分到 train、val、test 三个目录同时保证图片和标签同名对应。常见比例是 7:2:1 或 8:1:1航拍数据量只有 1000 张时我倾向 8:1:1验证集 100 张够看趋势测试集 100 张留作最终评估不参与调参。划分脚本里必须固定随机种子否则每次跑出来的划分不一样实验没法复现。下面是一个最小划分逻辑import os, random, shutil random.seed(42) # 固定种子保证可复现 img_dir images label_dir labels out_dir dataset ratio {train: 0.8, val: 0.1, test: 0.1} files [f for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(files) n len(files) n_train int(n * ratio[train]) n_val int(n * ratio[val]) splits { train: files[:n_train], val: files[n_train:n_train n_val], test: files[n_train n_val:] } for split, flist in splits.items(): for f in flist: name os.path.splitext(f)[0] shutil.copy(os.path.join(img_dir, f), os.path.join(out_dir, images, split, f)) shutil.copy(os.path.join(label_dir, name .txt), os.path.join(out_dir, labels, split, name .txt))random.seed(42)这行是后悔药没有它后面复现实验会多花很多时间。shutil.copy保留原文件划分错了还能重来比 move 安全。如果标签是 VOC 或 COCO 格式划分脚本要先转成 YOLO txt 再按同名规则复制否则训练时找不到标签。3. 用这 1000 张图跑通 YOLO 训练环境、配置和第一轮收敛3.1 环境配置与预训练权重选择训练 YOLO 的环境不复杂但版本对不上会出各种玄学错误。我一般用 Python 3.8 到 3.10PyTorch 1.12 以上ultralytics 包直接 pip 装。GPU 方面1000 张图用单卡 8G 显存足够batch size 设 16 或 32 都行显存不够就降到 8。预训练权重建议用 COCO 上训好的 YOLO 权重航拍行人检测虽然视角不同但底层边缘和纹理特征可迁移从零训 1000 张图很难收敛。权重文件放在项目根目录训练脚本里用--weights指过去。注意权重版本要和代码版本匹配YOLOv5 的权重不能直接喂给 YOLOv8 的代码反之亦然。3.2 data.yaml 的写法与三个必调参数YOLO 训练靠一个 data.yaml 描述数据路径和类别写法如下path: ./dataset train: images/train val: images/val test: images/test nc: 1 names: [person]nc是类别数行人检测只有一类就写 1。names的顺序必须和转换脚本里class_list一致这是最容易埋雷的地方。路径用相对路径时训练脚本的工作目录要对否则会报找不到图片。训练命令里三个参数最影响结果--img输入尺寸航拍小目标建议设 640 或 1280设太小行人变成几个像素模型学不到--epochs轮数1000 张图我一般跑 100 到 300 轮看验证集 mAP 不再涨就停--batch批大小显存允许就设大batch 太小梯度噪声大收敛慢。学习率用默认的 0.01 起步如果 loss 震荡厉害再降到 0.001。yolo detect train datadata.yaml modelyolov8n.pt epochs200 imgsz640 batch16这条命令里yolov8n.pt是预训练权重imgsz640是输入尺寸epochs200是训练轮数。跑起来后看控制台输出的 box_loss 和 mAP前 10 轮 loss 快速下降说明配置没问题如果 loss 不动或者变 NaN先查学习率和数据标签。3.3 训练过程监控与早停判断训练时重点看三个指标box_loss、cls_loss 和 mAP0.5。box_loss 管框的位置cls_loss 管类别两个都降才正常。mAP0.5 在验证集上算涨到平缓就可以停。航拍行人检测因为目标小mAP 通常比地面数据集低0.5 到 0.7 算正常低于 0.3 要查标签质量。如果训练中 loss 突然变 NaN常见原因是学习率太大或者某张图标签坐标越界。YOLO 对越界坐标会警告但不报错训练时表现为 loss 异常。排查方法是把标签里 xc、yc、w、h 不在 0 到 1 之间的行找出来通常是转换时图宽高读错或者框超出边界。4. 航拍行人检测的避坑记录从标签错位到 BN 崩溃4.1 标签类别 id 错位导致 mAP 恒为零现象训练 loss 正常下降但验证集 mAP 一直是 0预测框画出来位置对但类别全错。 原因转换脚本里类别 id 从 1 开始或者 data.yaml 的 names 顺序和转换时不一致。 解决统一用 0 起始的类别 id转换脚本和 data.yaml 的 names 列表逐字对齐改完重新生成标签再训。4.2 图片和标签文件名不匹配现象训练报No labels found或者大量图片被跳过实际标签文件存在。 原因划分脚本复制时改了文件名或者图片是.jpg标签是.JPG.txt这种大小写不一致。 解决划分脚本里用os.path.splitext取主名再拼.txt复制后抽查几个文件名是否一一对应。4.3 输入尺寸设太小导致小目标漏检现象训练 mAP 看着还行但推理时远处行人全漏近处大目标正常。 原因--img设了 320 或 416航拍图里行人原本就几十像素缩放后只剩几个像素特征提取不到。 解决输入尺寸提到 640 以上或者把大图切块训练推理时再合并。1000 张图直接 640 起步显存不够就减 batch。4.4 BN 层崩溃与 batch size 的关系现象训练几个 epoch 后 loss 突然飙到 NaN报 BN 相关错误。 原因batch size 太小比如设成 2 或 4BatchNorm 统计量不稳定航拍图分布差异大时更容易崩。 解决batch 至少设 8显存不够就换小模型或者用梯度累积。已经崩了的把学习率降一个量级重跑。4.5 验证集和测试集混用导致指标虚高现象调参时 mAP 一直涨换测试集一跑掉一大截。 原因划分脚本没固定种子每次重新划分验证集图片漏进了训练集。 解决划分一次固定下来训练只碰 train 和 valtest 目录在最终评估前不打开。5. 把 1000 张图用出 10000 张的效果增强、切片与迁移技巧1000 张航拍图训行人检测数据量是瓶颈但有几个技巧能把效果往上提一档。第一是离线增强训练前用 albumentations 或 YOLO 自带增强把训练集扩到 3 到 5 倍重点加随机缩放、平移和 mosaic航拍视角变化大这些增强比颜色抖动更有效。第二是切片推理航拍图分辨率高整图缩放会丢小目标训练时把大图切成 640 的块推理时也切块再合并行人召回能明显提升。第三是冻结 backbone 先训 head前 20 轮只训检测头让分类和框回归先稳定再解冻全网络微调小数据集上这样比一上来全量训收敛更稳。验证方法上别只看 mAP把预测结果可视化出来挑漏检和误检的图单独看。航拍行人漏检多半是遮挡和尺度问题误检多半是树冠、车辆顶部这些纹理相似区域。针对误检可以在训练集里补这类负样本针对漏检可以调低置信度阈值看召回上限。我自己的习惯是每换一次数据或改一次增强先跑 20 轮看 loss 和 mAP 趋势趋势不对就停别等 200 轮跑完才发现配置错了。1000 张图不大一轮几分钟快速迭代比一次跑满更省时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表