ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLO海底垃圾检测实战:185张图像数据集训练与调优指南

YOLO海底垃圾检测实战:185张图像数据集训练与调优指南 简介这份资源面向从事海洋环境监测、水下目标识别与计算机视觉方向的研究者及YOLO算法学习者提供一套可直接用于训练与验证的海底垃圾目标检测数据集覆盖生物罐、布料、玻璃等常见海底废弃物类别。压缩包共371个文件以185张jpg图像与185个同名txt标注文件一一对应另含1个yaml配置文件用于定义数据集路径与类别信息整体约9.93MB规模轻量、便于快速上手。标注采用YOLO标准格式每行依次为类别索引、归一化后的中心点坐标与宽高可直接适配yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等系列算法也可按需转换为VOC格式。数据集已完成训练集与验证集划分省去自行清洗与切分的步骤适合用于算法对比实验、课程设计或小样本检测调优。目前已有75人学习下载可作为海底垃圾检测任务的入门与验证基线。1. 海底垃圾检测为什么值得单独搞一份数据集做水下目标检测的同行多半有过这种体验拿 COCO 或 VOC 的预训练权重直接往海底图像上迁模型能把鱼认成塑料袋把玻璃瓶认成石头mAP 掉得让人怀疑人生。问题不在网络结构而在数据分布——水下成像的色偏、悬浮颗粒、光照衰减和自然场景完全是两套统计规律。这份yolo算法-海底垃圾数据集-185张图像带标签-生物罐布玻璃yolo-odgki.zip就是冲着这个缺口来的185 张真实海底图像全部带 YOLO 格式标注类别聚焦在生物、罐、布、玻璃这几类典型海底垃圾上。它体量不大但胜在标注完整、类别贴近真实清理场景适合拿来做迁移学习的起点、验证自建标注流程或者给水下机器人视觉模块做小样本微调。如果你正在做海洋环保、水下巡检、ROV 视觉相关的项目这份数据集能帮你省掉最耗时的第一轮标注。2. 数据集拆开看185 张图里到底装了什么2.1 类别设计与标注格式这份数据集的核心价值不在数量而在类别定义。生物、罐、布、玻璃这四类覆盖了海底垃圾里最难区分的几个形态罐和玻璃都是硬质反光物体布和生物在形态上容易混淆生物本身又可能是活体附着在垃圾上。标注采用 YOLO 标准的 txt 格式每张图对应一个同名 txt 文件每行是class_id x_center y_center width height坐标全部归一化到 0~1。这种格式的好处是直接喂给 YOLOv5/v8/v10 都不用转换省掉格式清洗这一步。常见做法是先把压缩包解压后检查目录结构确认 images 和 labels 是否一一对应。我一般会先跑一遍配对检查避免训练时才发现有图无标签import os img_dir dataset/images lbl_dir dataset/labels imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} only_img imgs - lbls only_lbl lbls - imgs print(f有图无标签: {len(only_img)}) print(f有标签无图: {len(only_lbl)})这段逻辑很直白用集合差集找出不配对的样本。参数上注意os.path.splitext去掉扩展名后再比对因为图片是 .jpg 而标签是 .txt直接比文件名会全部不匹配。如果输出不是 0说明压缩包里可能有损坏文件或命名不一致需要手动处理。2.2 标注质量与类别分布检查185 张图在目标检测里属于小样本所以每一张的标注质量都很关键。我习惯先统计每个类别的框数量判断是否存在严重的长尾分布。如果某一类只有个位数框训练时几乎学不到特征得考虑数据增强或者合并类别。from collections import Counter counter Counter() for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for line in fp: cls int(line.split()[0]) counter[cls] 1 for cls_id, cnt in sorted(counter.items()): print(f类别 {cls_id}: {cnt} 个框)运行后如果发现某类框数低于 20我的建议是要么用 mosaic、mixup 增强补足要么在训练配置里给这一类调高损失权重。参数上cls就是类别索引需要和你的data.yaml里 names 的顺序对上否则训练出来的类别名会张冠李戴。2.3 划分训练集与验证集小数据集最忌讳随机划分后验证集里没有某类样本。我一般用分层抽样保证每个类别在训练集和验证集里都有代表。下面这段脚本按 8:2 划分并尽量让类别分布一致import random import shutil random.seed(42) all_imgs sorted(os.listdir(img_dir)) random.shuffle(all_imgs) split int(len(all_imgs) * 0.8) train_imgs all_imgs[:split] val_imgs all_imgs[split:] for phase, files in [(train, train_imgs), (val, val_imgs)]: os.makedirs(fdataset/{phase}/images, exist_okTrue) os.makedirs(fdataset/{phase}/labels, exist_okTrue) for f in files: shutil.copy(os.path.join(img_dir, f), fdataset/{phase}/images/{f}) lbl os.path.splitext(f)[0] .txt shutil.copy(os.path.join(lbl_dir, lbl), fdataset/{phase}/labels/{lbl})random.seed(42)是为了结果可复现团队协作时尤其重要。split取 80% 作为训练集185 张里大约 148 张训练、37 张验证。这个比例在小数据集上比较稳验证集再小就失去统计意义了。复制而不是移动是为了保留原始数据后面做交叉验证时还能重新划分。3. 用 YOLOv8 跑通第一轮训练配置与参数怎么定3.1 环境准备与依赖版本YOLOv8 目前是 ultralytics 包在维护安装比早期 YOLOv5 省心但版本兼容仍然是翻车高发区。我一般锁定一个稳定组合避免 torch 和 ultralytics 互相打架pip install ultralytics8.2.0 pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu118这里ultralytics8.2.0是写这篇文章时的稳定版cu118对应 CUDA 11.8。如果你的显卡驱动只支持到 CUDA 11.7就把 index-url 换成 cu117。装完用yolo checks验证环境重点看 CUDA 是否可用、显存是否识别正确。这一步别偷懒我见过太多训练到一半报 OOM 的根因都是环境没对齐。3.2 data.yaml 的写法与类别映射YOLOv8 训练靠一个 yaml 文件告诉它数据在哪、有几类。这份数据集四类写法如下path: ./dataset train: train/images val: val/images names: 0: biological 1: can 2: cloth 3: glasspath是根目录train和val是相对路径。names的顺序必须和标注文件里的 class_id 严格对应否则模型学出来的类别会错位。如果你不确定原始标注的类别顺序先跑一遍 2.2 里的统计脚本看看 class_id 最大到几再决定 names 写几行。常见错误是 names 写了 4 类但标注里出现了 class_id4训练直接报索引越界。3.3 训练命令与关键超参第一轮训练不建议一上来就调复杂超参先用默认配置跑通确认 loss 能正常下降yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/train \ nameseabed_trashmodelyolov8n.pt用 nano 版是因为数据集小大模型容易过拟合。imgsz640是 YOLO 系列的标准输入尺寸如果你的原图分辨率远高于此可以试 960但显存占用会翻倍。batch16在 8G 显存上比较稳显存不够就降到 8。lr00.01是初始学习率小数据集上可以降到 0.005 减少震荡。patience20表示 20 轮没提升就早停防止无效训练浪费时间。训练过程中重点盯三个指标box_loss、cls_loss、mAP50。box_loss 负责定位cls_loss 负责分类两个都该稳步下降。如果 cls_loss 一直不降多半是类别不平衡或者标注有问题回头查 2.2 的统计结果。3.4 推理验证与结果解读训练完在验证集上跑一遍看混淆矩阵和 PR 曲线yolo detect val \ modelruns/train/seabed_trash/weights/best.pt \ datadata.yaml \ imgsz640输出里重点看每类的 mAP50-95 和混淆矩阵。海底垃圾检测里罐和玻璃最容易互相误判因为都是反光硬物。如果混淆矩阵显示这两类大量互错说明特征区分度不够可以考虑加更多玻璃和罐的样本或者在数据增强里加颜色抖动模拟不同水深的光照。布和生物的混淆则通常是因为形态相似可以尝试在标注时更严格地界定边界。4. 避坑与排查小数据集训练最容易翻车的五个点4.1 现象训练 loss 正常但 mAP 始终为 0原因通常是类别映射错位。标注里的 class_id 从 0 开始但 data.yaml 的 names 写成了从 1 开始或者顺序对不上。模型学到的类别和验证时的类别完全错开mAP 自然为 0。解决用 2.2 的脚本打印所有出现的 class_id确保 names 的键和它完全一致。改完重新训练不要指望从 checkpoint 恢复能修正这个问题。4.2 现象验证集 loss 远高于训练集 loss这是典型过拟合。185 张图对 YOLOv8n 来说仍然偏少模型记住了训练样本的噪声。表现是训练 mAP 很高但验证 mAP 停滞甚至下降。解决先加数据增强在训练命令里显式打开 mosaic 和 mixupmosaic1.0 mixup0.1。再把dropout调到 0.1 以上。如果还不行换更小的模型或者冻结 backbone 前几层。我一般会同时开早停patience 设 15 到 20 之间。4.3 现象训练中途报 CUDA out of memory原因不一定是 batch 太大也可能是 imgsz 设高了或者 dataloader 的 workers 太多导致内存泄漏。解决先把 batch 减半试不行再降 imgsz 到 512。workers在 Windows 上设 0 或 2Linux 上可以设 8。另外检查是不是有其他进程占着显存nvidia-smi看一眼就清楚。4.4 现象某些类别完全检测不到如果某一类在统计里框数就很少模型学不到足够特征。185 张图里如果玻璃只有十几框检测不到很正常。解决要么补标注要么在训练时给这一类加权。YOLOv8 没有直接的类别权重参数但可以通过复制含该类别的样本做过采样。另一个办法是先用这类样本做一次单类微调再合并训练。4.5 现象推理时框大量重叠或漏检NMS 的 iou 阈值和 conf 阈值没调好。默认 conf0.25、iou0.7在密集垃圾场景下可能过杀或漏杀。解决推理时显式指定conf0.3 iou0.5试一组观察框的变化。海底垃圾经常堆叠iou 可以适当调低到 0.4 到 0.5 之间减少重叠框。conf 则根据你对漏检和误检的容忍度来定清理场景通常宁可误检不可漏检conf 可以降到 0.2。5. 从 185 张到可用模型小样本迁移的进阶技巧小数据集训练最怕的就是模型没学到通用特征就过拟合了。我的习惯是分两阶段走先冻结 backbone 只训 head让分类头先适应新类别再解冻全部做微调。YOLOv8 里通过freeze参数控制yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs50 \ freeze10 \ lr00.001 \ projectruns/train \ namestage1_freezefreeze10表示冻结前 10 层这些层通常是 backbone 的浅层特征提取器。lr00.001比默认低一个量级因为只训 head 不需要大学习率。跑完 50 轮后用 stage1 的 best.pt 作为第二阶段起点解冻全部层学习率再降一半yolo detect train \ datadata.yaml \ modelruns/train/stage1_freeze/weights/best.pt \ epochs100 \ lr00.0005 \ projectruns/train \ namestage2_finetune这套流程在 185 张图上通常能把 mAP50 从 0.3 左右拉到 0.5 以上具体取决于类别难度。另一个技巧是善用预训练权重yolov8n.pt本身是在 COCO 上训的虽然 COCO 没有海底垃圾类别但底层边缘和纹理特征可迁移。如果你有更多水下数据哪怕没标注也可以先做自监督预训练再拿这份数据集微调。验证阶段我习惯用 TTA测试时增强再刷一遍指标yolo detect val \ modelruns/train/stage2_finetune/weights/best.pt \ datadata.yaml \ augmentTrueaugmentTrue会做多尺度翻转推理再融合结果通常能涨 1 到 3 个点代价是推理时间翻几倍。上线部署时是否开 TTA取决于你的实时性要求。最后说个血泪经验小数据集上任何一次随机划分都可能带来指标波动我后来养成的习惯是跑三次不同 seed 的训练取平均再决定模型是否可用。单次结果好看不代表稳定这点在 185 张这种量级上尤其明显。从那以后我每次拿到小数据集都强制走一遍分层划分加多次训练再也不敢只看一次结果就下结论。希望这份数据集和上面的流程能帮你少走点弯路。本文还有配套的精品资源点击获取
返回列表