ARTICLE DETAIL

资讯详情

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

海洋垃圾检测数据集与YOLO11一键训练:从1000张图到三平台跑通

海洋垃圾检测数据集与YOLO11一键训练:从1000张图到三平台跑通 简介这份资源面向从事海洋环境监测、水下目标检测的算法工程师与深度学习学习者提供一套真实拍摄的海洋海底垃圾检测数据集可用于海底监控场景下的垃圾识别项目也可作为通用水下检测任务的数据补充。数据集共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. 海洋垃圾检测数据集与 YOLO11 一键训练从 1000 张图到三平台跑通海面漂浮物检测这件事真正卡住大多数团队的往往不是模型结构而是数据。你拿到一批无人机或岸基摄像头拍的海洋垃圾照片想训一个能识别塑料瓶、泡沫箱、渔网碎片的检测器第一步就会撞上标注格式不统一、训练环境配不通、换台机器就跑不起来这三堵墙。这个标题讲的方案核心是把 1000 张海洋垃圾图像连同 VOC、COCO、YOLO 三种格式标签打包好再配一套能在 GPU、CPU、Mac 三平台一键启动的 YOLO11 训练脚本。它解决的是从数据到可训练模型之间的工程摩擦适合手里有图但不想在格式转换和环境配置上耗掉一周的算法工程师、研究生和做环保监测落地的开发者。下面按数据格式、环境准备、训练脚本、参数调优、踩坑排查的顺序把这条链路拆开讲清楚。2. 三种标签格式到底怎么选VOC、COCO、YOLO 的差异与转换逻辑拿到一个标注数据集第一件事不是急着训而是先搞清楚三种格式各自长什么样、什么时候用哪个。海洋垃圾检测这个场景里VOC 格式常见于早期标注工具导出COCO 格式适合做多任务扩展和与检测框架对接YOLO 格式则是直接喂给 YOLO11 训练脚本的最终形态。三者不是随便选的选错了要么训练脚本读不进去要么评估指标对不上。2.1 VOC、COCO、YOLO 三种格式的结构对比VOC 格式的核心是每张图对应一个 XML 文件里面用object标签记录每个目标的类别名和边界框的左上角、右下角坐标。它的坐标是绝对像素值原点在图像左上角。COCO 格式则把所有标注集中到一个 JSON 文件里用images、annotations、categories三个主键组织边界框用[x, y, width, height]表示同样是绝对像素值但原点也是左上角且类别用数字 id 映射。YOLO 格式最简洁每张图对应一个 txt 文件每行是class_id x_center y_center width height全部归一化到 0 到 1 之间原点在左上角。这三种格式的差异不只是文件结构还影响训练时的数据加载逻辑。YOLO11 官方训练脚本默认读 YOLO 格式如果你直接拿 VOC 的 XML 或 COCO 的 JSON 去训脚本会在数据加载阶段报错。所以数据集里同时提供三种格式本质是让你少写转换代码但你要知道什么时候该用哪个。格式单图标注文件坐标类型类别表示典型用途VOCXML绝对像素字符串名称早期标注工具、Pascal VOC 评估COCO单个 JSON绝对像素数字 id多任务、COCO 评估、框架对接YOLOTXT归一化 0-1数字 idYOLO 系列训练2.2 从 VOC 转 YOLO 的脚本与四个边界坑如果你手里的原始标注是 VOC 格式想转成 YOLO 格式喂给 YOLO11下面这段 Python 脚本可以直接用。它遍历 VOC 的 XML 文件读取图像宽高把绝对坐标转成归一化坐标再按类别名映射到数字 id 写入 txt。import os import xml.etree.ElementTree as ET # 类别名到 id 的映射必须和训练时的 data.yaml 一致 class_map { plastic_bottle: 0, foam_box: 1, fishing_net: 2, plastic_bag: 3, other_trash: 4 } def voc_to_yolo(xml_dir, img_dir, out_dir): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() # 图像宽高从 XML 的 size 节点读取 size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_map: continue bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 归一化并转为中心点加宽高 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{class_map[cls_name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) txt_name xml_file.replace(.xml, .txt) with open(os.path.join(out_dir, txt_name), w) as f: f.write(\n.join(lines)) voc_to_yolo(annotations_xml, images, labels_yolo)这段脚本的逻辑很直接读 XML、取宽高、算归一化中心点和宽高、写 txt。参数上唯一需要你改的是class_map它必须和后续训练用的data.yaml里的names列表顺序完全一致否则类别 id 会错位训练出来的模型会把塑料瓶认成泡沫箱。四个边界坑分别是第一XML 里size节点的宽高必须和实际图像一致有些标注工具会写错导致归一化后框偏移第二xmin可能大于xmax标注时拖拽方向不同会导致这个问题脚本里没做交换需要你提前检查第三类别名大小写和空格必须和class_map完全匹配plastic_bottle和Plastic_Bottle是两个东西第四空标注图会生成空 txtYOLO11 训练时默认会跳过但如果你开了某些增强策略空文件可能引发警告建议保留但确认脚本能处理。2.3 COCO 转 YOLO 时容易忽略的 id 重映射COCO 格式的类别 id 不一定是连续的也不一定从 0 开始。比如 COCO 官方数据集里person是 1bicycle是 2但你的海洋垃圾数据集可能只有 5 个类标注工具导出的 id 可能是 1 到 5。YOLO 格式要求类别 id 从 0 开始连续所以转换时必须做一次重映射。常见做法是读 COCO JSON 的categories列表按顺序建立旧 id 到新 id 的映射再遍历annotations写 txt。这一步如果偷懒直接用原 id训练时 YOLO11 会报类别数不匹配或者把背景当成某个类。转换完记得抽查几张图的 txt用cat看一眼坐标是否在 0 到 1 之间超出范围说明宽高读错了。3. GPU、CPU、Mac 三平台环境准备从驱动到 YOLO11 安装数据格式理顺之后下一步是让 YOLO11 能在你的机器上跑起来。这个数据集标题里强调支持 GPU、CPU、Mac 三平台意思是训练脚本要能自动检测硬件并选择对应的计算后端。但自动检测的前提是你把基础环境装对了否则脚本再智能也救不了缺驱动或版本冲突。3.1 GPU 平台CUDA 驱动与 PyTorch 版本匹配GPU 训练是首选1000 张图在单卡上通常几十分钟就能跑完几十个 epoch。但 GPU 环境最容易翻车的地方是 CUDA 驱动版本、CUDA Toolkit 版本和 PyTorch 版本三者不匹配。常见做法是先用nvidia-smi看驱动支持的 CUDA 最高版本再去 PyTorch 官网找对应版本的安装命令。比如驱动显示 CUDA 12.1你可以装 PyTorch 的 cu121 版本。不要直接pip install torch那样装的是 CPU 版训练时torch.cuda.is_available()会返回 False脚本会静默切到 CPU速度慢几十倍。# 查看驱动和 CUDA 版本 nvidia-smi # 安装对应 CUDA 版本的 PyTorch以 cu121 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 验证 GPU 是否可用 python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))这段命令的关键在第二行--index-url指定了 PyTorch 的 CUDA 12.1 轮子仓库装出来的 torch 才能调用 GPU。第三行验证时如果输出True和你的显卡型号说明环境通了。如果输出False先检查驱动版本是否太低再检查是不是装成了 CPU 版。另外如果你用的是 RTX 4060 Laptop 这类移动端显卡功耗墙和散热会影响持续训练速度建议把 batch size 调小一点避免显存溢出。3.2 CPU 与 Mac 平台线程数与 MPS 后端配置没有 GPU 或者用 Mac 的读者YOLO11 也能跑只是速度慢。CPU 训练时要设置torch.set_num_threads()来充分利用多核一般设成物理核心数。Mac 用户如果用的是 Apple Silicon 芯片可以启用 MPS 后端让训练跑在 GPU 上比纯 CPU 快不少。启用方式是在训练脚本里判断torch.backends.mps.is_available()然后指定 device 为mps。import torch # CPU 平台设置线程数一般等于物理核心数 torch.set_num_threads(8) # Mac MPS 平台检测并启用 if torch.backends.mps.is_available(): device mps elif torch.cuda.is_available(): device cuda else: device cpu print(f使用设备: {device})这段代码做了三平台自动检测优先级是 MPS 大于 CUDA 大于 CPU。参数上set_num_threads不要设成逻辑核心数超线程对训练帮助有限反而可能增加调度开销。Mac 用户注意MPS 后端对某些算子支持不完整如果训练中途报错可以回退到 CPU 跑通流程再排查。另外Mac 的 unified memory 和显存共享batch size 设太大可能触发内存交换建议从 4 或 8 开始试。3.3 YOLO11 安装与一键训练脚本的入口逻辑YOLO11 通过ultralytics包安装一条pip install ultralytics就能搞定。一键训练脚本的入口逻辑通常是解析命令行参数、加载data.yaml、根据设备选择device参数、调用model.train()。下面是一个最小可用的训练脚本骨架。from ultralytics import YOLO import argparse parser argparse.ArgumentParser() parser.add_argument(--data, defaultdata.yaml, help数据集配置文件) parser.add_argument(--epochs, typeint, default100) parser.add_argument(--imgsz, typeint, default640) parser.add_argument(--batch, typeint, default16) parser.add_argument(--device, default, help留空自动检测) args parser.parse_args() model YOLO(yolo11n.pt) # 加载预训练权重 model.train( dataargs.data, epochsargs.epochs, imgszargs.imgsz, batchargs.batch, deviceargs.device if args.device else None, projectruns_ocean_trash, nameexp1 )这个脚本的核心是model.train()的参数。data指向data.yaml里面写清楚训练集、验证集路径和类别名。imgsz是输入分辨率海洋垃圾目标通常较小640 是起点如果小目标漏检多可以提到 1280但显存占用会翻倍。batch根据显存调整GPU 上 16 或 32CPU 上 4 或 8。device留空时 ultralytics 会自动选但自动选有时会选错建议显式指定。project和name控制输出目录跑多次实验时改name避免覆盖。4. 用 1000 张图跑通 YOLO11 训练参数设置与训练过程监控环境通了数据格式也对了接下来是把 1000 张海洋垃圾图真正喂进 YOLO11 并观察训练是否正常。这个规模的数据集属于小样本容易过拟合也容易因为类别不平衡导致某些类学不出来。参数设置和监控指标要盯紧。4.1 data.yaml 的写法与类别名顺序data.yaml是 YOLO11 训练的数据入口格式很简单但容易写错。它包含path、train、val、names四个关键字段。path是数据集根目录train和val是相对路径names是类别名列表顺序必须和 YOLO 标签里的 class_id 对应。path: ./ocean_trash_dataset train: images/train val: images/val names: 0: plastic_bottle 1: foam_box 2: fishing_net 3: plastic_bag 4: other_trash这里最常见的错误是names写成列表而不是字典或者顺序和标签 id 不一致。YOLO11 读names时会按 key 排序如果你写成names: [plastic_bottle, foam_box]它也能读但 id 从 0 开始按列表顺序分配。两种写法都行但一旦定了就不要混用。另外train和val路径下要有images和labels两个子目录YOLO11 会自动去labels找同名 txt找不到会报 warning 并跳过该图。4.2 小样本下的 batch size、学习率与增强参数1000 张图分到 5 个类平均每类 200 张属于小样本。默认学习率 0.01 可能偏大容易在早期震荡。常见做法是把初始学习率降到 0.001 到 0.005配合余弦退火调度。batch size 在 GPU 上可以设 16CPU 上设 4 到 8。数据增强方面YOLO11 默认开了 mosaic、mixup、HSV 抖动等对小样本有帮助但海洋垃圾场景里有些增强会引入噪声比如 mixup 把两张图叠在一起可能让模型学到不存在的组合。如果发现验证集指标波动大可以关掉 mixup把mosaic概率从 1.0 降到 0.5。model.train( datadata.yaml, epochs150, imgsz640, batch16, lr00.003, # 初始学习率降低 lrf0.01, # 最终学习率因子 mosaic0.5, # mosaic 概率减半 mixup0.0, # 关闭 mixup patience30, # 30 轮无提升则早停 device0 )参数上lr0是初始学习率lrf是最终学习率相对于初始值的比例余弦退火会从lr0降到lr0 * lrf。patience是早停轮数小样本训练容易过拟合早停能省时间。mosaic和mixup是增强强度海洋垃圾目标通常比较独立mixup 的收益不大关掉更稳。4.3 训练日志里该盯哪几个指标mAP50、mAP50-95 与混淆矩阵训练启动后日志会每轮输出 box_loss、cls_loss、dfl_loss 和验证集的 mAP50、mAP50-95。box_loss 是边界框回归损失cls_loss 是分类损失dfl_loss 是分布焦点损失。这三个 loss 应该整体下降如果某个 loss 震荡不降说明对应部分有问题。mAP50 是 IoU 阈值 0.5 时的平均精度mAP50-95 是 0.5 到 0.95 多个阈值的平均后者更严格。海洋垃圾检测里如果 mAP50 高但 mAP50-95 低说明框的位置不够准可能需要调box损失权重或增加定位精度相关的增强。混淆矩阵在训练结束后会生成它能告诉你哪个类容易被认成哪个类。比如塑料瓶和塑料 bag 在颜色和形状上接近混淆矩阵里可能看到它们互相误判。这时候可以考虑增加这两类的区分性特征或者检查标注是否把两者标混了。另外YOLO 混淆矩阵的总合不唯一是常见现象因为多分类的混淆矩阵按行归一化和按列归一化结果不同看的时候要确认用的是哪种归一化方式。5. 海洋垃圾检测训练避坑5 个血泪踩坑记录这一章把实际跑这个数据集时最容易翻车的地方列出来每条按现象、原因、解决写。这些坑不挑平台GPU、CPU、Mac 都可能遇到。5.1 现象训练启动即报 “No labels found”原因通常是data.yaml里的train路径指向了images/train但labels/train不存在或者 txt 文件和图片文件名不对应。YOLO11 要求图片和标签同名只是扩展名不同。比如img_001.jpg对应img_001.txt如果标签叫img_001_label.txt就找不到。解决检查labels/train目录是否存在文件名是否和图片一一对应。可以用一条 shell 命令快速比对。# 列出图片文件名去扩展名和标签文件名去扩展名找差集 comm -3 (ls images/train | sed s/\.[^.]*$// | sort) (ls labels/train | sed s/\.[^.]*$// | sort)如果输出不为空说明有图片缺标签或有标签缺图片补上或删掉即可。5.2 现象GPU 显存溢出报 “CUDA out of memory”原因通常是 batch size 太大或 imgsz 太高。1000 张图里如果有些图分辨率很高YOLO11 会按 imgsz 缩放但缩放后的 batch 仍然可能撑爆显存。另外如果开了 mosaic 增强一个 batch 里会拼四张图等效 batch 翻四倍。解决先把 batch 降到 8 或 4再把 imgsz 从 640 降到 416 试。如果还不行检查是不是有其他进程占着显存用nvidia-smi看。Mac 用户如果报内存不足同理降 batch 和 imgsz。5.3 现象训练 loss 不降mAP 始终在 0.01 左右原因可能是学习率太大导致梯度爆炸也可能是标签格式错了但没报错。比如 YOLO 标签里的坐标没有归一化还是绝对像素值YOLO11 读进去后框全在图像外面模型学不到东西。解决先抽查几个 txt 文件确认坐标都在 0 到 1 之间。如果坐标没问题把lr0降到 0.001 再跑。另外检查data.yaml的names数量和标签里的最大 class_id 是否一致不一致会静默错位。5.4 现象验证集 mAP 比训练集低很多过拟合明显原因1000 张图对 5 个类来说偏少模型容易记住训练集。另外如果验证集和训练集分布差异大比如训练集是晴天拍的验证集有阴天也会导致指标差距。解决增加增强强度比如开 mosaic、HSV 抖动、随机翻转。加 weight decayYOLO11 默认有可以适当调大。如果还不行考虑用预训练权重冻结 backbone 先训几轮再解冻全量微调。早停 patience 设小一点比如 20。5.5 现象Mac 上训练到一半报 “MPS backend out of memory” 或算子不支持原因MPS 后端对某些算子支持不完整比如某些池化或插值操作。另外 unified memory 被其他应用占用也会导致训练中断。解决先关掉其他占内存的应用把 batch 降到 4。如果还报算子不支持设置环境变量PYTORCH_ENABLE_MPS_FALLBACK1让不支持的算子回退到 CPU 执行速度会慢但能跑通。实在不行就切回 CPU 训练1000 张图在 CPU 上跑 100 轮大概几小时能接受。6. 小目标漏检怎么救从 1000 张图里榨出更高精度的三个技巧海洋垃圾检测里最头疼的是小目标比如远处的塑料瓶、海面上的泡沫碎片在 640 分辨率下可能只有十几个像素。YOLO11 本身对小目标有一定能力但 1000 张图的规模下想再往上提几个点得在数据和推理两端做文章。第一个技巧是切图训练。把原图切成 640 乘 640 的块重叠 20%这样小目标在切块里相对变大模型更容易学到。切图后样本量会翻几倍1000 张可能变成 3000 到 5000 张但要注意切图后边缘目标会被截断标注也要跟着切。切图脚本可以用 PIL 或 OpenCV 写核心是遍历原图、按步长裁剪、同步裁剪标签框、过滤掉截断后面积太小的框。from PIL import Image import os def slice_image(img_path, label_path, out_img_dir, out_lbl_dir, size640, overlap128): img Image.open(img_path) w, h img.size step size - overlap idx 0 for y in range(0, h, step): for x in range(0, w, step): box (x, y, min(x size, w), min(y size, h)) crop img.crop(box) crop.save(os.path.join(out_img_dir, f{os.path.basename(img_path)}_{idx}.jpg)) # 标签同步裁剪逻辑略核心是坐标平移和过滤 idx 1这段代码只演示了切图部分标签同步裁剪需要读原 txt、把归一化坐标转回绝对坐标、减去切块偏移、再归一化到切块尺寸最后过滤掉宽或高小于 2 像素的框。参数上overlap控制重叠区域128 像素是个经验值太小会漏掉边缘目标太大则冗余样本多。第二个技巧是推理时用 TTA也就是测试时增强。对同一张图做水平翻转、多尺度缩放分别推理后再把结果融合。YOLO11 的model.predict()支持augmentTrue开启后会做简单的 TTA。这个技巧不增加训练成本只在推理时多花时间适合对精度要求高、对速度不敏感的离线检测场景。第三个技巧是调整 NMS 的 IoU 阈值和置信度阈值。海洋垃圾目标密集时默认 NMS 的 IoU 0.7 可能把相邻目标误删可以降到 0.5 到 0.6。置信度阈值默认 0.25如果漏检多可以降到 0.1但会引入更多误检需要根据业务权衡。我一般会在验证集上画一条 precision-recall 曲线找 F1 最高的那个阈值点而不是拍脑袋定。这三个技巧里切图训练收益最直接但工作量也最大需要重新生成数据集和标签。TTA 和阈值调整是推理端的后悔药训练完发现漏检多时可以立刻试。我自己的习惯是先把 1000 张图用默认参数跑一版 baseline看 mAP50 和漏检情况再决定要不要上切图。如果 baseline 已经够用就不折腾了。希望帮到你。本文还有配套的精品资源点击获取
返回列表