海底垃圾检测数据集:1000张真实图像与YOLO11训练全攻略
2026/9/23 16:43:22 网站建设 项目流程

简介:这份资源面向从事水下视觉与目标检测的开发者、科研人员及学生,提供一套真实拍摄的海洋海底垃圾检测数据集,可用于海底监控场景下的垃圾识别项目,也可作为通用水下垃圾检测数据的补充。数据集共1000张高质量图像,覆盖海底塑料、铁罐、纸张等垃圾,以及海洋生物、水下探测器与垃圾同框、打光拍摄等多种场景,标注包含plastic、bio、rov、metal、paper、wood、rubber、timestamp、unknown九个类别,采用labelimg标注,质量较高。资源以PDF形式交付,文件总数1个,大小约2.77MB,内附数据集基本情况介绍与获取方式,并同步提供VOC、COCO、YOLO三种标签格式,可直接用于YOLO等算法训练。此外还附赠YOLO11一键训练脚本,支持GPU、CPU及Mac芯片多平台方案,并给出博主训练结果日志供参考。目前已有540人学习,适合希望快速开展水下垃圾检测实验的读者。

1. 海底垃圾检测数据集:1000 张真实图像与三格式标签的落地价值

做水下目标检测的同行大多有过这种体验:公开数据集里找海底塑料、金属罐、ROV 同框的样本,翻遍 COCO、VOC 也凑不齐几百张,最后只能自己扛着相机下水或者去视频里抽帧。这份海洋垃圾检测数据集就是冲着这个缺口来的——1000 张真实拍摄的海底场景图像,覆盖塑料、生物、水下探测器、金属制品、纸张、木头、手套、时间条、未知共九个类别,并且一次性给出 VOC(xml)、COCO(json)、YOLO(txt) 三种标签格式。它解决的不是"有没有数据"的问题,而是"拿到就能直接喂给 YOLO 训练"的问题。适合做海底监控垃圾识别、水下机器人视觉、以及需要小目标检测补充样本的团队。下面按数据本身、格式转换、训练脚本、踩坑、进阶验证的顺序拆开讲。

2. 数据构成与标签体系:九个类别怎么用才不浪费

2.1 场景分布与类别定义

这批数据的采集场景比想象中杂。除了常规的海底塑料垃圾,还有铁制品罐状垃圾、纸张、木头、橡胶手套,以及容易被忽略的两类"非垃圾"目标:bio(海洋生物)和 rov(水下探测器)。另外 timestamp(时间条)和 unknown(未知)这两个标签,是很多人在训练时直接删掉、结果模型在真实视频里频繁误检的根源。

先把九个类别的实际含义对齐一下:

类别名含义训练建议
plastic塑料垃圾主目标,保留
bio海洋生物保留,避免误检为垃圾
rov水下探测器保留,同框干扰项
metal金属制品主目标,保留
paper纸张主目标,保留
wood木头主目标,保留
rubber手套主目标,保留
timestamp时间条建议保留或单独成类
unknown未知视项目决定是否合并

为什么建议保留 bio 和 rov?因为海底监控的真实画面里,鱼群和探测器出现的频率极高。如果训练集里没有这些负样本,模型会把游动的鱼当成塑料垃圾,把 ROV 的机械臂当成金属罐。这是水下检测最常见的翻车点,不是模型不行,是类别体系没设计好。

timestamp 这个类别比较特殊。它是视频抽帧时叠在画面上的时间戳文字,标注出来是为了让模型学会"忽略"它。如果你的推理场景是单张图片而非视频帧,可以把它合并进 unknown 或者直接删除;但如果是视频流检测,保留它反而能降低误报。

2.2 三种格式的目录结构与选用逻辑

数据集同时提供 VOC、COCO、YOLO 三种格式,不是让你三个都用,而是对应不同的训练框架和验证需求。常见做法是:YOLO 系列训练直接用 txt 格式,做 benchmark 对比或者跑 MMDetection、Detectron2 时用 COCO json,需要和旧项目对接或者用 labelImg 复查标注时用 VOC xml。

三种格式的典型目录长这样:

# YOLO 格式 dataset_yolo/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yaml # VOC 格式 dataset_voc/ ├── JPEGImages/ ├── Annotations/ └── ImageSets/Main/ # COCO 格式 dataset_coco/ ├── images/ └── annotations/ ├── instances_train.json └── instances_val.json

YOLO 的 txt 每行是class_id x_center y_center width height,坐标全部归一化到 0~1。VOC 的 xml 存的是绝对像素坐标的 xmin/ymin/xmax/ymax。COCO 的 json 里 bbox 是[x, y, width, height]绝对像素,同时还有 segmentation 和 area 字段。这三种格式之间转换时,最容易出错的就是归一化和绝对坐标的混用,以及类别 id 从 0 还是 1 开始。

提示:YOLO 的类别 id 从 0 开始,VOC 和 COCO 的类别 id 通常从 1 开始。转换脚本里如果没做偏移,训练时会出现类别整体错位,loss 降不下去但也不报错,属于典型的玄学问题。

2.3 标注质量与 labelImg 复查方法

数据用 labelImg 标注,质量整体在线,但 1000 张里难免有个别框偏移或者漏标。拿到数据后建议先做一轮可视化抽查,不用全看,随机抽 50 张就够。用下面这段脚本把 YOLO 格式的标签画回图上:

import cv2 import os import random img_dir = "dataset_yolo/images/train" lbl_dir = "dataset_yolo/labels/train" names = ["plastic", "bio", "rov", "metal", "paper", "wood", "rubber", "timestamp", "unknown"] samples = random.sample(os.listdir(img_dir), 50) for img_name in samples: img = cv2.imread(os.path.join(img_dir, img_name)) h, w = img.shape[:2] lbl_path = os.path.join(lbl_dir, img_name.rsplit(".", 1)[0] + ".txt") if not os.path.exists(lbl_path): continue with open(lbl_path) as f: for line in f: cid, xc, yc, bw, bh = map(float, line.split()) # 归一化坐标还原为像素坐标 x1 = int((xc - bw / 2) * w) y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w) y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, names[int(cid)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imwrite(f"check_{img_name}", img)

这段脚本的逻辑很直接:读图、读对应 txt、把归一化坐标乘回宽高得到像素框、画框写类别名。参数上唯一要注意的是names列表的顺序必须和data.yaml里的names完全一致,否则画出来的类别名会张冠李戴。跑完看check_开头的图,如果发现框明显偏了或者类别标错,就回到 labelImg 里改对应的 xml 或 txt。

3. YOLO11 一键训练脚本:三平台参数怎么设

3.1 脚本结构与平台判断逻辑

附赠的训练脚本核心目标是"一套代码跑通 GPU、CPU、Mac 三种环境"。它的思路不是写三份脚本,而是在入口处做设备探测,然后动态调整 batch size、workers 和 AMP 开关。常见做法是用torch.cuda.is_available()判断 GPU,用platform.processor()torch.backends.mps.is_available()判断 Mac 的 M 芯片。

一个典型的入口逻辑如下:

import torch import platform from ultralytics import YOLO def pick_device(): if torch.cuda.is_available(): return "cuda", 16, 8, True # GPU: batch=16, workers=8, AMP开 elif torch.backends.mps.is_available(): return "mps", 8, 4, False # Mac M芯片: batch=8, workers=4 else: return "cpu", 4, 2, False # CPU: batch=4, workers=2 device, batch, workers, amp = pick_device() print(f"device={device}, batch={batch}, workers={workers}, amp={amp}") model = YOLO("yolo11n.pt") model.train( data="dataset_yolo/data.yaml", epochs=100, imgsz=640, batch=batch, workers=workers, device=device, amp=amp, patience=20, project="runs_ocean", name="exp1" )

逻辑说明:pick_device()返回四个值,设备字符串直接传给 ultralytics 的device参数;batch 和 workers 按平台降级,GPU 给最大,Mac 次之,CPU 最小;AMP 自动混合精度只在 CUDA 上开,因为 MPS 和 CPU 对 AMP 的支持不稳定,开了反而可能报错或者掉精度。patience=20是早停,100 轮里如果 20 轮 mAP 没提升就停,省时间。

参数怎么改:如果你的 GPU 显存小于 8G,把 batch 降到 8 或 4;如果数据集小、过拟合快,把 epochs 降到 50~80;imgsz=640是默认,海底小目标多的话可以试 800 或 1024,但显存占用会翻倍。

3.2 data.yaml 的写法与路径坑

YOLO11 训练最容易被路径坑到。data.yaml里写的是相对路径还是绝对路径,直接决定脚本能不能找到图。推荐用绝对路径,省得因为工作目录不同而翻车:

path: /home/user/dataset_yolo train: images/train val: images/val nc: 9 names: 0: plastic 1: bio 2: rov 3: metal 4: paper 5: wood 6: rubber 7: timestamp 8: unknown

path是数据集根目录,trainval是相对于path的子路径。nc必须等于names的长度,多一个少一个都会在训练启动时报错。names的顺序必须和 txt 里的 class_id 严格对应,这个顺序错了,模型学到的就是错位的类别,mAP 会低得莫名其妙。

注意:Windows 下路径用反斜杠时,yaml 里要写成D:/data/dataset_yolo或者用双反斜杠,单反斜杠会被当成转义字符。

3.3 三平台实测差异与日志解读

GPU 平台是最顺的,CUDA + AMP 开着,1000 张图 100 轮大概几十分钟到一两小时,取决于卡。CPU 平台要有心理准备,同样配置可能要跑十几个小时甚至更久,建议先把 epochs 设成 10 跑通流程,确认没问题再放大。Mac M 芯片用 MPS 后端,速度介于两者之间,但 MPS 对某些算子支持不全,如果报NotImplementedError,就退回 CPU 跑那部分。

博主提供的训练日志主要看三个指标:box_losscls_lossmAP50。正常情况 box_loss 和 cls_loss 应该在前 10 轮快速下降,然后趋于平缓。如果 loss 一直不降,先查 data.yaml 路径和类别数;如果 mAP50 卡在很低的值不动,大概率是标签格式或者类别 id 错位。日志里还会打印每个类别的 AP,如果某个类别 AP 一直是 0,说明这个类别的样本太少或者标注有问题,需要回去补数据。

4. 避坑与排查:五个真实踩过的坑

4.1 现象:训练启动就报 "No labels found"

原因:YOLO 找标签的路径逻辑是images替换成labels,如果你的目录结构不是标准的images/trainlabels/train对应,它就找不到。或者 txt 文件和图片没有同名。

解决:确认图片和标签文件名除了扩展名外完全一致,比如001.jpg对应001.txt。目录结构严格按images/trainlabels/train来,不要自己改成train/images

4.2 现象:mAP 一直是 0 或者极低

原因:最常见的是类别 id 从 1 开始而不是从 0 开始。VOC 转 YOLO 时如果没做 id 偏移,所有标签的 class_id 都大了一位,而 data.yaml 里 nc=9,第 9 类直接越界被忽略。

解决:写个脚本扫一遍所有 txt,看 class_id 的最大值是不是等于 nc-1。如果最大值是 9 而 nc=9,说明 id 从 1 开始了,全部减 1。

4.3 现象:Mac 上训练报 MPS 相关错误

原因:MPS 后端对某些算子(比如某些池化或插值)支持不完整,ultralytics 在 MPS 上跑时会遇到未实现的算子。

解决:在训练参数里加device="cpu"强制走 CPU,或者升级 PyTorch 到较新版本,MPS 支持会好一些。速度慢总比跑不起来强。

4.4 现象:显存溢出 OOM

原因:batch 设太大,或者 imgsz 设太大。1000 张图里如果有高分辨率原图,YOLO 会按 imgsz 缩放,但 batch 大了一样爆。

解决:先把 batch 降到 4 或 2,跑通再往上加。imgsz 从 640 起步,不要一上来就 1280。另外workers设太大也会占内存,CPU 平台设 2 就够。

4.5 现象:验证集 mAP 高但实际推理效果差

原因:训练集和验证集如果来自同一段视频的相邻帧,两边的画面几乎一样,验证集 mAP 会虚高。这是数据划分的坑,不是模型的锅。

解决:按视频来源或者场景划分 train/val,不要随机按帧划分。如果数据集没提供视频来源信息,至少按图像亮度、拍摄角度做分层抽样,让验证集覆盖不同场景。

5. 进阶验证:用置信度门限和混淆矩阵定位真实短板

训练跑完不是终点,拿到best.pt之后要做两件事:调置信度门限、看混淆矩阵。这两步能告诉你模型在真实海底监控里到底能不能用。

先看混淆矩阵。YOLO11 训练完会在runs_ocean/exp1/下生成confusion_matrix.png。重点看 bio 和 plastic 之间有没有互相误判,以及 rov 有没有被当成 metal。如果 bio 被大量判成 plastic,说明负样本不够,需要补海洋生物的图像。如果 timestamp 被误判成其他类,考虑把它单独拎出来或者直接删掉这个类重新训。

再调置信度门限。默认推理是conf=0.25,但海底场景里小目标多,0.25 可能漏检,也可能误检。用下面这段脚本在验证集上扫一遍不同门限下的 precision 和 recall:

from ultralytics import YOLO model = YOLO("runs_ocean/exp1/weights/best.pt") for conf in [0.1, 0.2, 0.25, 0.3, 0.4, 0.5]: metrics = model.val(data="dataset_yolo/data.yaml", conf=conf, iou=0.5) print(f"conf={conf}, mAP50={metrics.box.map50:.4f}, " f"precision={metrics.box.mp:.4f}, recall={metrics.box.mr:.4f}")

逻辑是固定 iou=0.5,只变 conf,看 mAP50、precision、recall 怎么变。参数上conf越低 recall 越高但 precision 越低,实际部署时按业务需求选:宁可误报不可漏报就选 0.1~0.2,要求准确率高就选 0.3~0.4。iou=0.5是 COCO 的标准门限,想更严格可以试 0.75。

我自己的习惯是,每次训完新模型,先把混淆矩阵和门限扫描跑一遍,再决定要不要补数据或者调参。有次偷懒跳过这步,直接拿默认门限去跑海底视频,结果塑料垃圾漏检了一大半,回头一看 recall 在 0.25 门限下只有 0.4,调到 0.15 才拉到 0.7。从那以后我每次拿到新权重,都强制走一遍混淆矩阵加门限扫描,不省这一步。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询