尧图精选

无人机海面垃圾检测数据集实战:VOC/YOLO双格式与YOLO训练调优指南

🕒 发布时间:2026/10/2 10:55:13 📁 来源:尧图网络
1. 项目缘起与数据集整体设计思路1.1 为什么盯上了“无人机海面垃圾”这个方向做视觉检测这行的朋友应该都有体会通用数据集刷到90%以上的mAP已经很难带来什么兴奋感了真正让人头疼的是那些场景特殊、样本稀缺、标注成本极高的垂直领域。海面漂浮垃圾检测就是典型中的一个——它不像COCO、VOC那样有几十万张标注图等着你去调参也不像工业质检那样有稳定的光照和背景。你要面对的是动态水面反光、波浪纹理干扰、目标尺度剧烈变化、无人机视角下的透视畸变以及最要命的——正负样本极度不平衡。我拿到这个数据集的时候第一反应是“9627张、单类别、VOCYOLO双格式”这个体量在垂直领域里算是相当能打的了。要知道很多海面垃圾相关的公开数据集要么只有几百张要么是多类别混标导致单类样本被稀释。单类别“垃圾”虽然粗粒度但对于海漂垃圾巡检、水面清洁船路径规划、近岸环境监测这类应用来说先解决“有没有”的问题远比“是什么垃圾”更紧迫。你不可能让一架无人机在海上先分辨塑料瓶和泡沫箱再决定要不要上报实际工程中都是先框出来、传回岸基、人工复核分类。这个数据集的核心价值在于它把无人机低空拍摄这个特定视角下的海面垃圾检测问题做成了一个可以直接拿来训练、验证、对比的标准化基准。不管你是做学术研究要跑baseline还是做工程落地要快速验证模型可行性这9627张图能帮你省掉至少两三个月的数据采集和标注周期。1.2 VOC与YOLO双格式并存的工程意义很多刚入门的同学会问为什么同一个数据集要提供VOC和YOLO两种格式直接用YOLO格式不就行了吗这个问题我在带新人的时候被问过不下十次。答案其实很简单VOC格式是“母版”YOLO格式是“派生版”。VOC格式用XML文件存储标注信息每个目标用bndbox标签记录xmin, ymin, xmax, ymax四个绝对坐标值。这种格式的好处是信息完整、可读性强、方便做数据增强和格式转换。你拿到VOC格式的标注想转成COCO、转成YOLO、转成CSV、甚至自己写个脚本做统计分析都非常直接。而且VOC格式保留了图像的原始尺寸信息对于后续要做多尺度训练或者切片推理的场景来说这个信息至关重要。YOLO格式则是把标注归一化成了class_id x_center y_center width height五个值全部是0到1之间的相对坐标。这种格式的好处是直接喂给YOLO系列模型就能训练不需要在数据加载阶段做额外的坐标变换训练效率更高。但缺点是丢失了绝对尺寸信息如果你要做一些依赖原始像素尺寸的操作比如按目标实际像素面积过滤小目标就得反归一化回去。这个数据集同时提供两种格式说明制作者是懂工程实际的。我的建议是永远保留VOC格式作为原始存档每次训练前用脚本动态生成YOLO格式。这样当你需要调整类别映射、过滤某些样本、或者做格式转换实验时不会因为反复转换导致精度损失或信息丢失。1.3 单类别设计的利与弊单类别“垃圾”这个设计乍一看好像太粗糙了但仔细想想其实很合理。海面漂浮垃圾的形态差异极大——塑料瓶、泡沫板、渔网碎片、木板、海藻团有时候会被误标——如果强行分成多个细类每个类的样本量可能只有几百张训练出来的模型大概率过拟合。而且在实际巡检场景中发现垃圾的位置比识别垃圾的种类更重要后续的清理决策可以由人工或更高层级的分类模型来完成。但单类别也有它的坑。最大的问题是类内差异过大一个透明塑料瓶和一个黑色轮胎在视觉特征上几乎没有共性。模型要学会把它们都归为“垃圾”需要非常大的样本多样性和足够强的特征提取能力。这也是为什么这个数据集9627张的体量显得尤为重要——样本量不够单类别反而比多类别更难训因为模型没有类别间的对比信号只能靠海量样本来覆盖类内变化。我在实际训练中发现对于这种类内差异大的单类别检测数据增强策略比模型结构选择更关键。后面我会专门讲这块的实操细节。2. 数据集核心细节解析与实操要点2.1 标注质量评估与清洗策略拿到任何数据集第一件事不是急着跑训练而是做标注质量抽检。我见过太多人直接拿数据集开训结果mAP卡在0.5上不去排查半天才发现是标注框大量漏标、错标、重叠框导致的。对于这个海面垃圾数据集我建议按以下流程做质量评估第一步随机抽样目视检查。从9627张里随机抽200张用LabelImg或者自己写个可视化脚本把标注框画出来逐张看。重点看三类问题漏标图里有明显垃圾但没框、过框框的范围远大于实际目标、误标把浪花反光、海鸟、船体阴影标成了垃圾。海面场景特别容易出现浪花被误标的情况因为白色浪花和白色泡沫垃圾在低分辨率下确实很像。第二步统计标注框尺寸分布。用Python脚本读一遍所有XML文件统计每个框的宽高像素值画出直方图。这个数据集的无人机拍摄高度决定了目标像素尺寸的分布范围。如果发现大量框的宽高小于10像素说明存在大量极小目标训练时需要特别注意输入分辨率和特征金字塔的设计。如果发现有些框的宽高比极端异常比如宽高比大于10或小于0.1大概率是标注错误需要人工复核。第三步检查类别标签一致性。虽然只有一个类别但要确认所有XML里的name字段是否完全一致。我遇到过有的数据集里同时存在“garbage”、“trash”、“waste”三种写法导致训练时被当成三个类别处理。这个数据集标称单类别但拿到手后还是用脚本扫一遍确认最稳妥。注意标注清洗不要过度。有些框看起来“不太准”但只要IoU在0.5以上对训练的影响其实有限。把大量时间花在微调标注框上不如多跑几组对比实验。我的经验是标注质量从60分提到80分带来的收益远大于从80分提到95分。2.2 无人机视角下的图像特性分析无人机低空拍摄和地面手持拍摄、卫星遥感拍摄有本质区别这些区别直接决定了模型设计和训练策略的选择。第一透视畸变与尺度变化。无人机通常以一定倾角拍摄海面导致图像中的目标存在透视变形。靠近图像边缘的目标被拉伸靠近中心的目标相对正常。更麻烦的是同一类垃圾在不同飞行高度下像素尺寸可能相差几十倍——低空5米拍的塑料瓶可能有200像素宽高空30米拍的同样塑料瓶可能只有20像素。这种极端尺度变化要求模型必须有很强的多尺度检测能力。第二水面反光与纹理干扰。海面不是均匀背景波浪、泡沫、阳光反射都会产生大量高频纹理。这些纹理在浅层特征上和垃圾的边缘特征非常相似容易导致误检。我在可视化模型特征图时发现水面反光区域的激活值往往和真实垃圾区域相当这说明模型确实被干扰了。第三运动模糊。无人机在飞行中拍摄如果快门速度不够快海面波浪和移动中的垃圾会产生运动模糊。这个数据集里应该有一部分图像存在不同程度的模糊训练时如果全部当清晰样本处理模型对模糊目标的检测能力会偏弱。第四光照条件多变。海面场景的光照从正午强光到阴天散射光动态范围极大。强光下水面反光可能过曝阴影区垃圾可能欠曝。这要求训练时必须有充分的光照增强。针对这些特性我在训练这个数据集时采用的策略是输入分辨率不低于640优先用1280做高分辨率微调数据增强中必须包含随机亮度对比度调整、运动模糊模拟、以及随机透视变换。这些后面会展开讲。2.3 VOC与YOLO格式转换的实操细节虽然数据集已经提供了两种格式但实际训练中你很可能需要自己再做一次转换比如调整类别映射、过滤特定样本、或者做训练集/验证集重新划分。这里把转换脚本的核心逻辑和踩过的坑说清楚。VOC转YOLO的核心公式x_center (xmin xmax) / 2.0 / image_width y_center (ymin ymax) / 2.0 / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_height看起来很简单但有几个坑坑一坐标越界。有些标注框的xmax可能等于image_width转换后x_center width/2 1.0刚好在边界上。YOLO训练时如果做了随机裁剪增强这个框可能被裁掉一部分导致宽高变成负数。建议转换后做一次clamp把所有值限制在[0, 1]范围内并且过滤掉宽或高小于0.001的框。坑二图像尺寸不一致。VOC格式的XML里虽然有size标签记录宽高但有些标注工具写进去的尺寸和实际图像尺寸不一致。必须以实际读取到的图像尺寸为准不要信XML里的size标签。我吃过这个亏用XML里的尺寸做归一化结果训练时发现框全部偏移。坑三类别映射表。单类别看似简单但YOLO要求类别从0开始编号。如果VOC里的类别名是“garbage”你需要建一个{garbage: 0}的映射表。如果后续要扩展多类别这个映射表要提前规划好不然后面改起来很麻烦。坑四训练集验证集划分。不要随机划分海面垃圾数据集如果随机划分可能出现同一段视频的连续帧被分到训练集和验证集两边导致验证集精度虚高。正确做法是按拍摄架次或时间段划分确保验证集的图像来自训练集未覆盖的场景。如果数据集没有提供架次信息至少按图像文件名前缀做分组划分。3. 从零到一YOLO训练完整实操流程3.1 环境搭建与数据准备我用的训练环境是Ubuntu 20.04 CUDA 11.3 PyTorch 1.10 Ultralytics YOLOv5/v8。这个组合在V100和3090上都跑过稳定性没问题。如果你用Windows建议直接上WSL2原生Windows下的DataLoader多进程效率会打折扣。数据目录结构建议这样组织dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml的内容path: /path/to/dataset train: images/train val: images/val test: images/test nc: 1 names: [garbage]这里有个细节images和labels的目录结构必须严格对应YOLO加载数据时是根据图像路径替换images为labels、替换扩展名为.txt来找标注文件的。如果目录名不一致训练时会报“找不到标签”的错误。数据准备阶段还要做一件事统计训练集和验证集的样本量、目标数量分布。我一般会跑一个脚本输出每个子集有多少张图、多少个标注框、平均每张图几个目标。这个统计信息对后续判断模型表现是否合理非常重要。比如验证集mAP突然比训练集低很多如果验证集的目标密度和训练集差异大那可能是数据划分问题而不是过拟合。3.2 模型选型与参数配置YOLOv5和YOLOv8我都试过最终在这个数据集上我倾向于YOLOv8m作为baseline。原因有三第一YOLOv8的C2f结构和解耦头在小目标检测上比v5的C3结构有优势第二v8的Anchor-Free设计省去了调Anchor的麻烦对于海面垃圾这种形状极不规则的类别更友好第三v8的训练脚本更简洁超参数默认值在垂直领域数据集上表现更稳。模型配置的关键参数参数推荐值说明imgsz640基线/ 1280高精度1280能显著提升小目标召回但显存占用翻倍batch16640/ 81280根据显存调整V100 32G可以跑batch32640epochs200-300垂直领域数据集需要更多轮次收敛lr00.01初始学习率配合cosine调度lrf0.01最终学习率系数warmup_epochs3预热轮次防止初期梯度爆炸box7.5框回归损失权重cls0.5分类损失权重单类别可以适当降低dfl1.5分布焦点损失权重v8特有这里重点说imgsz的选择。640是YOLO系列的默认值速度快、显存友好但对于无人机高空拍摄的小目标640分辨率下可能只有几个像素模型根本学不到有效特征。我的做法是先用640跑一轮baseline看验证集的小目标召回率。如果小目标面积小于32x32像素的召回低于0.4就切到1280重新训。1280下小目标的像素面积是640下的4倍特征信息丰富得多。代价是训练时间大约增加2.5倍显存占用增加3倍左右。还有一个容易被忽略的参数是anchor。虽然YOLOv8是Anchor-Free但如果你用YOLOv5一定要用kmeans重新聚类这个数据集的标注框。海面垃圾的宽高比分布和COCO差异很大用默认anchor会导致正样本匹配率低。我实测过重新聚类anchor后YOLOv5s的mAP0.5能提升3-5个百分点。3.3 数据增强策略的针对性设计数据增强是这个小项目里最值得花时间打磨的环节。通用增强策略翻转、缩放、色彩抖动当然要用但针对海面垃圾场景我额外加了几个“特效”。第一随机透视变换。无人机拍摄角度不固定透视变换能模拟不同倾角下的目标形变。在Albumentations里用Perspectivescale参数设0.05-0.1概率0.3。注意透视变换后要检查标注框是否还在图像范围内超出边界的框要裁剪或丢弃。第二运动模糊模拟。用MotionBlurblur_limit设3-7概率0.2。这个增强能显著提升模型对模糊目标的鲁棒性。但概率不要太高否则清晰样本的检测精度会下降。第三水面反光模拟。这个没有现成的库我的做法是用RandomBrightnessContrast配合RandomGamma再加上局部的高光增强。具体来说随机选图像中10%-20%的区域把这些区域的亮度提升30%-50%模拟阳光反射。这个增强对降低水面反光误检非常有效。第四Mosaic与MixUp。YOLOv8默认开启Mosaic概率1.0最后10个epoch关闭。Mosaic对海面垃圾检测的帮助很大因为它能合成出目标密度更高的训练样本缓解正负样本不平衡。MixUp我建议概率设0.1-0.15太高会导致训练不稳定。第五随机裁剪与缩放。这个要小心。海面垃圾数据集中很多图像的目标集中在图像中央区域随机裁剪可能把目标裁掉。我的做法是用RandomSizedBBoxSafeCrop确保裁剪后至少保留一个完整标注框。实操心得数据增强不是越多越好。我试过同时开15种增强结果模型收敛极慢验证集精度还不如只开5种核心增强。增强策略要围绕数据集的真实变化维度来设计海面场景的核心变化是光照、视角、模糊那就重点增强这三个维度。3.4 训练过程监控与调参训练启动后不要只盯着loss看。我一般同时监控这几个指标train/box_loss、train/cls_loss、train/dfl_loss三个损失要同步下降。如果box_loss降但cls_loss不降说明模型在学定位但学不会分类可能是类别标签有问题。metrics/mAP0.5和mAP0.5:0.95mAP0.5到0.8以上算及格0.85以上算不错。mAP0.5:0.95如果只有mAP0.5的一半左右说明定位精度不够需要检查标注框质量。val/box_loss和val/cls_loss如果train loss持续降但val loss开始升就是过拟合了。这时候要么加数据增强要么加正则化weight_decay调大要么早停。学习率曲线cosine调度下学习率应该平滑下降。如果学习率震荡检查warmup设置和batch size是否匹配。我在这个数据集上遇到过一个典型问题前50个epoch mAP涨得很快到0.75左右就卡住了再训100个epoch也只涨到0.78。排查后发现两个原因一是学习率衰减太慢后期学习率还是太大模型在最优解附近震荡二是数据增强中的Mosaic一直开着导致后期模型看到的都是合成图对真实分布的拟合不够。解决方案是把cosine调度的周期缩短到150个epoch并且在最后20个epoch关闭Mosaic和MixUp。调整后mAP0.5最终到了0.84。4. 常见问题排查与避坑指南4.1 训练不收敛或mAP异常低这是最常见的问题原因可能有很多按以下顺序排查第一步检查数据加载是否正确。写个脚本随机抽几张训练图把标注框画出来确认框的位置和类别都对。我遇到过有人把images和labels的路径配反了训练时加载的全是空标签模型当然学不到东西。第二步检查类别数和类别名。data.yaml里的nc必须和实际类别数一致names的顺序必须和标注文件里的class_id对应。单类别的话nc: 1names: [garbage]class_id必须是0。第三步检查输入归一化。YOLO默认会把图像像素值从0-255归一化到0-1。如果你自己改了数据加载逻辑确认归一化没做错。我见过有人把图像归一化到-1到1结果模型完全不收敛。第四步检查学习率。学习率太大会导致loss震荡不下降太小会导致收敛极慢。YOLOv8的默认lr00.01在大多数数据集上没问题但如果你的batch size特别小比如小于8学习率要相应调小。第五步检查预训练权重。用COCO预训练权重初始化能显著加速收敛。如果从零开始训前几十个epoch mAP为0是正常的不要慌。4.2 小目标漏检严重海面垃圾数据集中小目标占比很高漏检是主要误差来源。提升小目标召回的手段按性价比排序提高输入分辨率640提到1280小目标召回通常能提升10-20个百分点。这是最直接有效的方法。增加P2特征层YOLOv8默认用P3-P5做检测加一个P2层 stride4专门检测小目标。代价是计算量增加推理速度下降。调整Anchor尺寸如果用YOLOv5把最小的Anchor缩小匹配更多小目标。切片推理训练时用640推理时把大图切成640x640的小块分别检测再合并。这个方法对小目标效果极好但推理耗时成倍增加。Copy-Paste增强把小目标复制粘贴到其他图像上增加小目标样本密度。这个增强对小目标检测提升明显但要注意粘贴位置不要遮挡其他目标。4.3 水面反光导致的误检水面反光误检是海面场景的特有难题。模型会把阳光反射的高亮区域当成垃圾因为两者在浅层特征上都是高对比度的边缘纹理。解决方案方案一在训练数据中增加负样本。收集一批没有垃圾但有强烈水面反光的图像作为背景负样本加入训练集。YOLO训练时这些图像没有对应的标注文件或者标注文件为空模型会学会抑制这些区域的激活。方案二在数据增强中模拟反光。前面提到的局部亮度增强就是干这个的。让模型在训练阶段就见过各种反光模式推理时就不容易上当。方案三后处理过滤。如果误检框集中在图像的上半部分天空/远海区域可以在后处理阶段根据框的位置做过滤。但这个方案比较粗暴可能误杀真实目标。方案四换用更强的 backbone。反光和垃圾的区别在高层语义特征上更明显用更大的模型YOLOv8l或x能提升区分能力。但推理速度会下降需要权衡。4.4 常见问题速查表问题现象可能原因排查方法解决方案loss不下降学习率过大/过小打印学习率曲线调整lr0加warmupmAP0.5高但mAP0.5:0.95低定位精度不够可视化预测框检查标注质量加box loss权重验证集mAP远低于训练集过拟合对比train/val loss加数据增强加正则化早停小目标漏检多输入分辨率不够统计小目标占比提高imgsz加P2层水面反光误检多负样本不足可视化误检区域加负样本加反光增强训练速度慢batch太小/图像太大看GPU利用率减小imgsz用混合精度推理结果框重叠NMS阈值不当调整NMS IoU阈值降低NMS IoU阈值到0.5-0.65. 模型评估与部署落地要点5.1 评估指标的正确解读mAP不是唯一指标。在实际部署中我更关注召回率Recall和误检率False Positive Rate。海面垃圾巡检场景下漏检一个垃圾的代价远大于误检一个反光区域——漏检意味着垃圾继续漂浮污染环境误检只是多派一次人工复核。所以我的评估策略是在保证召回率不低于0.85的前提下尽量压低误检率。具体做法是调整推理时的置信度阈值。默认conf0.25我会降到0.15甚至0.1先把召回拉满然后看误检情况。如果误检太多再逐步提高阈值找到平衡点。另外按目标尺寸分层评估也很重要。把验证集的目标按面积分成小32x32、中32x32到96x96、大96x96三档分别算AP。如果小目标AP明显低于中大目标说明模型对小目标检测能力不足需要针对性优化。5.2 模型导出与推理优化训练完的PyTorch模型要部署到实际系统中通常需要导出成ONNX或TensorRT。YOLOv8的导出命令yolo export modelbest.pt formatonnx opset12 simplifyTrue yolo export modelbest.pt formatengine halfTrue device0导出ONNX时注意opset版本12兼容性最好。simplifyTrue会做图优化去掉冗余算子。导出TensorRT引擎时halfTrue开启FP16推理速度能提升30%-50%精度损失通常在1个百分点以内。推理优化方面如果部署在边缘设备如Jetson系列建议用TensorRT DLA加速。如果部署在服务器端ONNX Runtime CUDA Execution Provider就够用了。不要直接用PyTorch模型做推理速度慢且显存占用高。5.3 实际部署中的经验技巧技巧一多尺度推理融合。推理时把图像缩放到多个尺度如640、960、1280分别检测然后用NMS融合结果。这个方法能提升小目标召回但推理耗时成倍增加。适合对实时性要求不高的巡检场景。技巧二时序滤波。无人机视频是连续的相邻帧的检测结果可以做时序平滑。如果某一帧检测到垃圾但前后帧都没有大概率是误检可以过滤掉。这个后处理能显著降低误检率。技巧三地理围栏过滤。如果无人机有GPS信息可以把检测框映射到地理坐标然后根据已知的陆地/海域边界过滤掉陆地上的误检。海面垃圾检测中岸边建筑、船只、浮标都可能被误检地理围栏能有效过滤这些。技巧四模型量化。如果部署设备算力有限可以对模型做INT8量化。YOLOv8支持PTQ训练后量化用几百张校准图就能完成。量化后模型体积缩小4倍推理速度提升2-3倍精度损失通常在2-3个百分点。对于海面垃圾检测这种对精度要求不是极端苛刻的场景INT8量化完全可用。最后分享一个小技巧在实际部署前一定要用真实场景的视频流做一次端到端测试而不是只看验证集的mAP。验证集是静态图像视频流有帧间相关性、有运动模糊、有编码压缩伪影这些都会影响实际检测效果。我见过太多模型在验证集上mAP 0.9一到视频流上就各种漏检误检。用视频流测试能提前暴露这些问题给你留出优化时间。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →