
简介这份资源面向从事海洋环境监测、水下目标检测的算法工程师与深度学习学习者提供一套真实拍摄的海洋海底垃圾检测数据集可用于海底监控场景下的垃圾识别项目也可作为通用水下垃圾检测数据的补充。数据集共1000张高质量图像覆盖海底塑料、铁罐、纸张等垃圾以及海洋生物、水下探测器与垃圾同框、打光拍摄等多种场景标注包含plastic、bio、rov、metal、paper、wood、rubber、timestamp、unknown九个类别采用labelimg标注质量较高。资源包为1个PDF文件约2.77MB内附数据集基本情况介绍与获取方式并说明提供VOC、COCO、YOLO三种标签格式可直接用于YOLO等算法训练。随附YOLO11一键训练脚本支持GPU、CPU及Mac多平台方案并给出训练结果日志供参考。目前已有540人学习适合需要快速开展水下垃圾检测实验的读者。1. 海底垃圾检测数据集1000 张真实图像与三格式标签能解决什么做水下目标检测的同行大多有过类似经历模型在公开数据集上跑得挺漂亮一换到真实海底监控画面就崩塑料瓶和塑料袋分不清ROV 机械臂被当成金属垃圾画面里那条时间戳水印还会被误检成目标。问题往往不在网络结构而在数据——公开的海洋垃圾数据要么是水面漂浮物要么是实验室水槽摆拍跟真实海底打光、悬浮颗粒、生物同框的场景差得太远。这份海洋垃圾检测数据集就是冲着这个缺口来的1000 张真实拍摄的海底场景图像覆盖塑料、金属罐、纸张、木头、橡胶手套等垃圾类别同时把生物、ROV 水下探测器、时间条、未知目标一并标注共九个标签并提供 VOC、COCO、YOLO 三种格式标签和一套 YOLO11 一键训练脚本GPU、CPU、Mac 三平台都能跑。它适合正在做海底监控垃圾检测、或者想给通用垃圾检测模型补充水下域数据的从业者也适合刚接触目标检测、想拿一份标注质量过关的真实数据练手的人。2. 九个标签怎么定从 labelimg 标注到类别体系设计2.1 为什么是这九个类而不是只留垃圾拿到数据集第一件事不是急着训练而是先看类别定义。这份数据的九个标签是 plastic、bio、rov、metal、paper、wood、rubber、timestamp、unknown。乍看有点杂——垃圾检测为什么要把生物、探测器、时间条也标进去这恰恰是真实海底监控场景的必然结果。海底画面里垃圾从来不是孤立出现的塑料袋旁边飘着鱼群金属罐躺在珊瑚碎石间ROV 的机械臂伸进画面右上角还压着摄像头的时间戳。如果只标垃圾、把其他目标当背景模型会把这些高频共现物体学成垃圾的上下文特征一旦 ROV 单独出现就容易误检。把 bio、rov、timestamp 单独成类本质是让模型学会这些不是垃圾用负样本类别去压制误检。unknown 这一类则是标注时的兜底画面里确实有目标但受悬浮物遮挡或打光影响无法确认具体材质与其硬塞进某个类污染标签不如单列。这种设计在实际项目里很常见代价是类别数变多、类间不平衡更明显后面训练时要专门处理。2.2 三种格式的字段对照与选用数据集同时给了 VOC 的 xml、COCO 的 json、YOLO 的 txt这不是凑数而是对应不同的训练框架和评估工具链。搞清三者字段差异能省掉大量格式转换的返工。格式单张标注文件坐标表示类别字段典型用途VOCxml左上右下绝对像素 xmin/ymin/xmax/ymaxname 文本labelimg 原生、部分老框架、可视化核对COCO单个 json 汇总左上角 x/y 宽高绝对像素category_id 数字pycocotools 评估、detectron 系、COCO 指标YOLOtxt归一化中心点 cx/cy 宽高 w/hclass_id 数字从 0 起YOLO 系训练、ultralytics 直接读选用的原则很简单用 ultralytics 的 YOLO11 训练就直接喂 YOLO 格式别绕 COCO要做 mAP 的 COCO 口径评估或者跟别的检测器对比就用 COCO json要人工复核标注框画得准不准打开 VOC 的 xml 配原图最直观。三种格式的类别顺序必须一致否则同一张图在三个格式里 class_id 对不上训练出来的模型类别全是错位的这种坑后面会专门讲。2.3 用脚本核对三种格式是否对齐在正式训练前我一般会写个小脚本抽查几张图确认三种格式的框和类别能对上。下面这段代码读一张图的 VOC xml 和对应 YOLO txt把 YOLO 的归一化坐标还原成像素跟 VOC 的绝对坐标比对。import xml.etree.ElementTree as ET from PIL import Image img_path images/000001.jpg xml_path annotations_voc/000001.xml txt_path labels_yolo/000001.txt # 读图像尺寸YOLO 归一化坐标要靠它还原 w, h Image.open(img_path).size # 解析 VOC tree ET.parse(xml_path) voc_boxes [] for obj in tree.getroot().findall(object): name obj.find(name).text b obj.find(bndbox) xmin float(b.find(xmin).text) ymin float(b.find(ymin).text) xmax float(b.find(xmax).text) ymax float(b.find(ymax).text) voc_boxes.append((name, xmin, ymin, xmax, ymax)) # 解析 YOLO还原成像素坐标 yolo_boxes [] with open(txt_path) as f: for line in f: cid, cx, cy, bw, bh line.split() cx, cy, bw, bh map(float, (cx, cy, bw, bh)) xmin (cx - bw / 2) * w ymin (cy - bh / 2) * h xmax (cx bw / 2) * w ymax (cy bh / 2) * h yolo_boxes.append((int(cid), xmin, ymin, xmax, ymax)) print(VOC 框数:, len(voc_boxes), YOLO 框数:, len(yolo_boxes)) for v, y in zip(voc_boxes, yolo_boxes): print(v[0], -, y[0], | VOC:, v[1:], | YOLO:, tuple(round(x, 1) for x in y[1:]))逻辑说明先取图像宽高因为 YOLO 存的是归一化值脱离图像尺寸没法还原。VOC 的 xmin/ymin/xmax/ymax 本身就是像素直接读。YOLO 的 cx/cy 是框中心归一化坐标bw/bh 是归一化宽高还原公式是(cx - bw/2) * w得到左上角 x其余同理。参数上要注意如果打印出来框数不一致说明有目标在某个格式里漏标如果坐标差得离谱多半是图像尺寸读错或者类别顺序错位。这一步花两分钟能挡掉后面几小时的无效训练。3. YOLO11 一键训练脚本三平台参数怎么设3.1 脚本结构与 data.yaml 的关键字段一键训练脚本的核心其实是一个 data.yaml 加一条 ultralytics 训练命令。data.yaml 决定了模型去哪找图、去哪找标签、有几个类、类名叫什么写错一个字段训练直接报错或者静默学错。这份数据集的 YOLO 格式目录结构常见做法是 images 和 labels 平行各自再分 train、valdata.yaml 大致长这样path: /your/path/ocean_trash # 数据集根目录绝对路径最稳 train: images/train # 相对 path 的训练图目录 val: images/val # 相对 path 的验证图目录 nc: 9 # 类别数九个标签就写 9 names: # 顺序必须和标注时的 class_id 完全一致 0: plastic 1: bio 2: rov 3: metal 4: paper 5: wood 6: rubber 7: timestamp 8: unknown参数说明path用绝对路径能避免相对路径在不同工作目录下解析不一致的问题这是新手最常翻车的地方。nc必须等于 names 的条目数多一个少一个都会在加载时抛异常。names 的键值顺序就是 class_id 的映射一旦和生成 YOLO txt 时的类别列表顺序不同模型学到的就是错位标签——比如把 plastic 学成 bio训练 loss 照样下降但推理结果全乱这种错误不看可视化很难发现。3.2 GPU、CPU、Mac 三平台的启动命令ultralytics 的接口在三平台上基本一致差别在设备参数和个别依赖。GPU 训练是最常规的# GPU 单卡训练device0 指定第一块卡 yolo detect train \ datadata.yaml \ modelyolo11n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/ocean \ nameexp_gpuCPU 训练把 device 换成 cpu同时把 batch 调小因为 CPU 没有显存但内存和算力都吃紧# CPU 训练batch 降到 4 或 8否则内存容易爆 yolo detect train \ datadata.yaml \ modelyolo11n.pt \ epochs100 \ imgsz640 \ batch4 \ devicecpu \ projectruns/ocean \ nameexp_cpuMac 的 M 系列芯片走 MPS 后端device 写 mps# Mac M 芯片devicemps 启用 Metal 加速 yolo detect train \ datadata.yaml \ modelyolo11n.pt \ epochs100 \ imgsz640 \ batch8 \ devicemps \ projectruns/ocean \ nameexp_mac参数说明modelyolo11n.pt是 nano 版本参数量小、适合先跑通流程数据量只有 1000 张n 或 s 版本通常够用直接上 l/x 容易过拟合。imgsz640是通用起点海底小目标多的话可以试 960但显存和耗时都会涨。epochs100配合早停一般够收敛batch在 GPU 上按显存调CPU 和 Mac 上宁小勿大。project和name决定结果落盘位置建议按平台分开命名方便对比三者的日志。3.3 训练日志里该盯哪几个数脚本跑起来后控制台会滚动输出每个 epoch 的指标。别只盯着最后一行重点看三个box_loss 和 cls_loss 是否稳定下降、mAP50 是否在涨、以及有没有出现 loss 突然变 NaN。1000 张图的数据量正常情况前 20 个 epoch 指标涨得最快之后趋于平缓。如果 box_loss 一直不降先怀疑标签格式或 data.yaml 路径如果 cls_loss 高但 box_loss 正常多半是类别不平衡bio 和 timestamp 这类样本可能远多于 rubber、wood。博主提供的训练结果日志可以作为对照基线但要注意硬件和超参不同绝对值没法直接比看趋势更有意义。4. 避坑与排查从标签错位到 MPS 报错4.1 训练不报错但 mAP 接近零现象脚本正常跑完loss 也在降但验证集 mAP50 始终在 0.01 上下推理出来框的位置对但类别全错。 原因YOLO txt 里的 class_id 和 data.yaml 的 names 顺序不一致。标注工具导出时类别顺序可能按字母排而 data.yaml 按自定义顺序写两边对不上。 解决用 2.3 的核对脚本抽查把 txt 里出现的 class_id 集合和 names 的键集合比对确认映射一致不一致就重新生成标签或改 names 顺序改完必须重训不能接着旧权重续。4.2 路径写成相对路径导致找不到图现象报错No labels found或images not found但目录明明存在。 原因data.yaml 里 path 用了相对路径而训练命令的工作目录和数据集目录不在同一层ultralytics 解析出的绝对路径是错的。 解决path 一律写绝对路径train/val 相对 path 写。改完先用yolo detect train ... epochs1跑一个 epoch 验证能读到数据再放开训。4.3 Mac 上 devicemps 报后端不支持现象Mac 上设 devicemps 后报错提示算子不支持或直接回退到 CPU。 原因部分 PyTorch 版本对 MPS 的算子覆盖不全或者 ultralytics 版本与 torch 版本不匹配。 解决先确认 torch 是支持 MPS 的版本python -c import torch; print(torch.backends.mps.is_available())返回 True 再用仍报错就退回 devicecpu 先跑通别在环境上死磕M 芯片 CPU 训练小数据量也能接受。4.4 时间条 timestamp 被大量误检现象推理时画面右上角的时间戳区域频繁出框类别是 timestamp 或 unknown。 原因timestamp 在几乎每张图都出现且位置固定模型把它学成了高置信先验一旦测试图时间条样式变化就误检或漏检。 解决如果实际部署场景不需要检测时间条训练时把 timestamp 类过滤掉或者裁掉图像顶部固定区域如果保留就要在数据增强里加入随机裁剪打破位置固定性。4.5 小目标塑料垃圾漏检严重现象大块金属罐、木头检出率高远处小片塑料、纸张漏检多。 原因1000 张图里小目标占比不低但 640 输入下小目标像素太少特征在深层被稀释。 解决把 imgsz 提到 960 或 1280 重训开启 mosaic、copy-paste 这类增强提升小目标样本密度必要时换更浅的特征层输出。注意提分辨率会显著增加显存和训练时间先小 epoch 验证收益再全量跑。5. 把 1000 张用出 3000 张的效果增强与验证的实操技巧数据量只有 1000 张直接训容易过拟合尤其是 rubber、wood 这种长尾类。我的习惯是在 ultralytics 的训练配置里把增强开足同时用一套固定的验证流程确认增强没把标签搞坏。下面这段是常用的增强参数配置写进训练命令或 hyp 文件都行yolo detect train \ datadata.yaml \ modelyolo11s.pt \ epochs150 \ imgsz960 \ batch8 \ device0 \ mosaic1.0 \ mixup0.15 \ copy_paste0.3 \ degrees10 \ translate0.1 \ scale0.5 \ fliplr0.5 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ projectruns/ocean \ nameexp_aug参数说明mosaic1.0四图拼接对小目标提升明显但会让单图目标变小配合imgsz960用mixup0.15做图像混合比例别太高否则标签语义被稀释copy_paste0.3把目标复制粘贴到其他图对长尾类补样本很有效但粘贴位置要合理否则出现目标悬空这种不真实样本degrees、translate、scale做几何变换海底画面本身视角多变适度旋转平移合理fliplr0.5水平翻转注意如果画面里有文字类目标比如时间条翻转后文字镜像可能引入噪声介意就关掉hsv_*调色调饱和亮度模拟不同打光和浑浊度海底图像色偏大这组参数值得开。增强开完必须验证标签没被破坏。我一般训完先跑一次验证集推理把预测框和真值框叠在同一张图上肉眼过一遍重点看三类小目标框有没有因为 mosaic 缩放后错位、copy_paste 的目标有没有贴到不合理位置、翻转后文字类目标是否变成干扰。这一步用 ultralytics 自带的yolo detect predict加saveTrue就能出图花十分钟能挡掉一批指标虚高但实际不能用的模型。还有一个容易被忽略的点1000 张图划分 train/val 时如果按随机划分同一段视频的相邻帧可能同时进训练和验证导致验证指标虚高。海底监控数据往往是连续帧正确做法是按视频段或时间划分让验证集来自训练时没见过的场景。这个细节不处理模型在验证集上 mAP 很漂亮一上真实新场景就掉属于典型的数据泄漏翻车。从那以后我每次拿到连续帧来源的数据集都强制按来源分组划分再跑一遍基线确认指标没有异常跳变才敢往下调参。希望这份数据和这套流程能帮你少走几个弯路。本文还有配套的精品资源点击获取