ARTICLE DETAIL

资讯详情

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

YOLO海洋目标检测数据集实战:10000张图、三格式标签与训练避坑指南

YOLO海洋目标检测数据集实战:10000张图、三格式标签与训练避坑指南 简介本资源为YOLO海洋目标检测数据集面向从事目标检测算法学习与实战的开发者、学生及科研人员解决海洋场景下真实图片数据获取难、标注格式不统一的问题。数据集包含10000张真实场景高质量图片场景丰富经labelimg精细标注同时提供voc、coco和yolo三种格式标签可直接用于YOLO系列模型训练。压缩包共2000个文件以1986个xml标注文件为主另含少量html教程、txt说明与py脚本整体约140.33MB。资源附赠YOLO环境搭建、训练案例教程及数据集划分脚本支持按需划分训练集、验证集与测试集并覆盖Windows与Linux双平台环境配置与训练流程。已有303人学习下载适合希望快速上手海洋目标检测、复用标注数据与划分工具、减少环境配置与数据整理成本的读者参考使用。1. 拆开这个 YOLO 海洋目标检测数据集10000 张图、三套标签、划分脚本和训练教程做海洋场景目标检测的同行大概都有过这种体验模型在 COCO 上跑得挺欢一换到海面、码头、养殖区就集体翻车水面反光、目标密集、尺度跨度大通用数据集根本喂不饱。这个资源包就是冲着这个痛点来的——10000 张真实海洋场景图片用 labelImg 标注同时给了 VOCxml、COCOjson、YOLOtxt三种格式标签还附了数据集划分脚本和 Linux/Windows 两套环境搭建与训练教程。它解决的不是从零学 YOLO的问题而是我手上有明确海洋检测需求但缺一份能直接开训的高质量数据的问题。适合做海上目标监测、船舶识别、海洋生物检测的从业者也适合想拿真实场景练手 YOLO 全流程的人。下面我按数据长什么样 → 怎么划分 → 怎么配环境开训 → 坑在哪的顺序拆一遍。2. 三种标签格式怎么选VOC、COCO、YOLO 的目录结构与转换逻辑拿到一个多格式数据集第一件事不是急着训练而是搞清楚每种格式对应什么框架、目录怎么组织、字段什么含义。选错了格式后面脚本全得返工。2.1 三种格式的字段差异与适用框架VOC 格式是 PASCAL VOC 那套老规矩每张图配一个同名 xml里面object节点记录类别名和bndbox的 xmin/ymin/xmax/ymax左上右下两个角点绝对像素坐标。它的好处是可读性强、labelImg 原生输出缺点是解析要写 XML 逻辑训练时一般还得转一道。COCO 格式把所有标注塞进一个 jsonimages、annotations、categories三个主键bbox 是[x, y, width, height]且是绝对坐标category_id从 1 开始。它适合直接喂给 pycocotools 做评估也方便做实例分割扩展但单文件体积大改一个框要动整个 json。YOLO 格式最省事每张图一个同名 txt每行class_id x_center y_center width height后四个全是归一化到 0~1 的相对值。YOLOv5/v8/v11 系列直接读这个训练脚本不用改。三者的核心换算关系就一句话YOLO 的归一化坐标 VOC 绝对坐标除以图片宽高中心点 (xminxmax)/2。格式单文件形式坐标类型类别字段典型框架VOC每图一个 xml绝对像素name 字符串老版检测框架、labelImgCOCO全局一个 json绝对像素category_id 整数pycocotools、MMDetectionYOLO每图一个 txt归一化 0~1class_id 整数YOLOv5/v8/v11提示三种格式的类别顺序不一定一致。VOC 里是字符串名YOLO 里是数字 id转换前务必确认classes.txt或names列表的顺序否则会出现船被标成鸟这种玄学。2.2 目录组织与格式互转的实操这个包把三种格式分别放在不同文件夹下我一般会先建一个统一的工作目录把图片和标签对齐。假设解压后结构是images/、voc_labels/、coco/、yolo_labels/先做一次完整性校验图片数量和标签数量是否一致有没有孤儿标签。import os from pathlib import Path img_dir Path(images) yolo_dir Path(yolo_labels) imgs {p.stem for p in img_dir.glob(*.jpg)} labels {p.stem for p in yolo_dir.glob(*.txt)} # 图片有但标签没有或反过来都要警惕 missing_label imgs - labels missing_img labels - imgs print(f缺标签的图片: {len(missing_label)}) print(f缺图片的标签: {len(missing_img)})这段逻辑很直白用文件名主干stem做集合运算。missing_label非空说明有图没标训练时这些图会被当负样本或直接报错missing_img非空说明标签是脏数据。参数上没什么可调的关键是路径要对Windows 下注意反斜杠和编码。如果只有 VOC 想转 YOLO常见做法是遍历 xml读宽高做归一化import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_path, img_path, class_map, out_path): tree ET.parse(xml_path) root tree.getroot() w, h Image.open(img_path).size lines [] for obj in root.findall(object): cls obj.find(name).text bnd obj.find(bndbox) xmin float(bnd.find(xmin).text) ymin float(bnd.find(ymin).text) xmax float(bnd.find(xmax).text) ymax float(bnd.find(ymax).text) # 归一化并转中心点格式 xc (xmin xmax) / 2 / w yc (ymin ymax) / 2 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{class_map[cls]} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) with open(out_path, w) as f: f.write(\n.join(lines))class_map是类别名到 id 的字典必须和训练时的data.yaml对齐。坐标保留 6 位小数足够YOLO 官方也是这个精度。注意Image.open读的是原始图片尺寸别用缩略图否则归一化全错。3. 划分脚本怎么用train/val/test 与 ImageSets 两条路线数据集划分看着简单其实是翻车重灾区。随机划分导致同类目标分布不均、验证集里一个类别都没有这些坑我全踩过。包里给了三个脚本对应两种划分思路得按你的训练框架选。3.1 三个划分脚本的分工从文件名看训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.py是物理复制路线按比例把图片和标签复制到 train/val/test 三个新文件夹适合 YOLO 这种按目录读数据的框架。训练集、验证集划分脚本图片标签划分写入新文件夹.py是它的两分版只分 train/val。split_train_val生成ImageSets下txt文件划分脚本.py是索引路线不复制文件只在ImageSets/Main/下生成 train.txt、val.txt 记录文件名这是 VOC 风格框架的读法。选哪条用 YOLOv5/v8 就用物理复制版配置里直接写 train/val 路径用老版 VOC 评估流程或想省磁盘空间就用 ImageSets 版。train_list.txt应该是脚本跑完后生成的清单记录参与训练的文件名方便核对数量。3.2 按比例划分并落盘物理复制版的核心逻辑是打乱后切片。我一般会固定随机种子保证每次划分一致方便复现import random import shutil from pathlib import Path random.seed(42) # 固定种子划分可复现 img_dir Path(images) lbl_dir Path(yolo_labels) out_root Path(dataset) ratio {train: 0.7, val: 0.2, test: 0.1} stems sorted([p.stem for p in img_dir.glob(*.jpg)]) random.shuffle(stems) n len(stems) n_train int(n * ratio[train]) n_val int(n * ratio[val]) splits { train: stems[:n_train], val: stems[n_train:n_train n_val], test: stems[n_train n_val:], } for split, names in splits.items(): (out_root / split / images).mkdir(parentsTrue, exist_okTrue) (out_root / split / labels).mkdir(parentsTrue, exist_okTrue) for s in names: shutil.copy(img_dir / f{s}.jpg, out_root / split / images / f{s}.jpg) shutil.copy(lbl_dir / f{s}.txt, out_root / split / labels / f{s}.txt) print(f{split}: {len(names)} 张)random.seed(42)是后悔药换数据集时改个种子就行。比例 7:2:1 是检测任务的常见起点数据量小可以调成 8:1:1。shutil.copy是物理复制占磁盘但最稳想省空间就改成写 txt 清单。跑完打印三个数量加起来必须等于总数对不上说明有文件被漏掉。3.3 ImageSets 索引路线与 train_list.txt如果走索引路线脚本会在ImageSets/Main/下生成 train.txt、val.txt每行一个文件名不带扩展名。这种划分不占额外空间但要求你的数据加载器支持按清单读。生成后建议立刻核对# 统计各清单行数确认比例 wc -l ImageSets/Main/train.txt ImageSets/Main/val.txt # 检查是否有重复文件名 sort ImageSets/Main/train.txt | uniq -dwc -l看数量uniq -d查重复。如果 train 和 val 出现同名文件说明划分逻辑有 bug训练时会造成数据泄漏验证指标虚高这种坑最隐蔽。train_list.txt如果是全量清单可以用来做最终的数据审计。注意划分前一定要确认图片和标签文件名严格一一对应。有的数据集图片是.jpg标签是.txt有的混了.png脚本里 glob 模式写错就会漏文件最后训练时才发现少了几百张。4. 环境搭建与开训Linux/Windows 双版本教程怎么落地包里给了 Linux 和 Windows 两套环境搭建、训练教程还有 Ubuntu 安装教程。教程是 HTML照着点开看就行但真正开训前有几个参数必须自己确认不能无脑照抄。4.1 环境搭建的关键依赖YOLO 系列跑起来无非几样Python 3.8、PyTorch带 CUDA、以及框架本体。Linux 下常见做法是 conda 建虚拟环境Windows 下注意 CUDA 版本和显卡驱动匹配。教程里给的是案例环境你换机器时最容易翻车的就是 CUDA 和 PyTorch 版本对不上。# Linux 下建环境版本按自己显卡驱动选 conda create -n yolo python3.10 -y conda activate yolo # 装 PyTorchcu118 是示例按 nvidia-smi 显示的 CUDA 版本调整 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 装 YOLO 框架 pip install ultralyticsnvidia-smi右上角显示的 CUDA Version 是驱动支持的上限PyTorch 的 cu 版本不能超过它。装完用torch.cuda.is_available()验证返回 False 就是没配上别急着开训。Windows 下同理只是命令在 Anaconda Prompt 里跑。4.2 按案例改自己的数据集教程的核心是根据案例修改训练自己的数据集落到操作就是改data.yaml。这个文件告诉框架去哪找图、有几类、类名是什么# data.yaml path: ./dataset # 数据集根目录 train: train/images # 相对 path 的训练图路径 val: val/images test: test/images nc: 5 # 类别数必须和标签里的 class_id 最大值1 一致 names: # 顺序必须和标注时的 classes 一致 0: ship 1: boat 2: buoy 3: fish 4: platformnc和names是最容易错的地方。如果标签里出现了 id5 但nc写的 5合法 id 是 0~4训练直接报 index 越界。names的顺序错了模型学出来的类别就是乱的评估时混淆矩阵会告诉你真相。4.3 启动训练与关键参数配置对了就能开训。以 ultralytics 为例yolo detect train \ datadata.yaml \ modelyolov8n.pt \ # 预训练权重小数据建议从预训练起步 epochs100 \ imgsz640 \ batch16 \ device0 # 0 表示第一块 GPUmodel用预训练权重能明显加快收敛海洋场景和通用数据有差异但底层特征可迁移。imgsz640是默认值海洋目标如果普遍偏小可以提到 1280但显存翻倍。batch按显存调爆显存就减半。训练日志里重点看 box_loss、cls_loss 是否稳定下降以及每轮的 mAP。如果 loss 震荡剧烈先查学习率再查标签有没有越界坐标归一化值超过 1。提示训练前用几十张图跑 1 个 epoch 做冒烟测试能提前暴露路径、类别、显存问题比训到一半崩了强得多。5. 避坑与排查海洋数据集训练里最常见的五个翻车点这一章是我自己踩过的坑按现象 → 原因 → 解决写遇到对应症状直接对号入座。现象一训练一开始就报坐标越界或 loss 为 nan。原因多半是 YOLO 标签里有归一化值大于 1 或小于 0 的脏数据标注时框拖出了图片边界。解决写脚本扫一遍所有 txt把越界行打印出来手动修或直接丢弃该框。from pathlib import Path for txt in Path(yolo_labels).glob(*.txt): for i, line in enumerate(txt.read_text().splitlines()): parts line.split() if len(parts) ! 5: print(f{txt} 第{i}行字段数不对: {line}) continue vals list(map(float, parts[1:])) if any(v 0 or v 1 for v in vals): print(f{txt} 第{i}行坐标越界: {line})现象二验证集 mAP 高得离谱测试集一塌糊涂。原因是划分时数据泄漏同一张图或高度相似的图同时进了 train 和 val。海洋场景里连续帧截图尤其容易这样。解决划分前按拍摄批次或时间分组同组只进一个 split别纯随机。现象三某个类别死活学不出来。原因通常是类别样本极度不均衡或者names顺序和标注不一致。解决先统计各类别框数量少的做重采样或加数据增强再核对data.yaml的 names 和标注 classes 是否逐一对齐。现象四训练中途 BN 层崩溃或 loss 突然爆炸。常见于 batch 太小或学习率太大。解决把 batch 调大至少 8或换用更小的初始学习率也可以开梯度裁剪。这个在热词里叫yolo训练中bn崩溃本质是统计量估计不稳。现象五Windows 下路径报错或中文乱码。原因是路径里有中文或反斜杠转义。解决数据集放纯英文路径脚本里用pathlib或原始字符串r...读文件统一指定encodingutf-8。6. 进阶技巧用混淆矩阵和类别分布反查数据质量训完一轮别急着调参先看混淆矩阵和类别分布这两个东西能直接告诉你数据本身有没有问题比盲目加 epoch 有用得多。混淆矩阵的对角线是正确分类非对角线是误判。如果船大量被判成平台要么是这两类视觉上确实像要么是标注时标准不统一。我一般会把混淆矩阵导出来对着误判最多的类别对回原图抽查几十张八成能发现标注问题。类别分布统计更简单遍历所有 YOLO 标签数每个 class_id 出现次数from collections import Counter from pathlib import Path counter Counter() for txt in Path(dataset/train/labels).glob(*.txt): for line in txt.read_text().splitlines(): if line.strip(): counter[int(line.split()[0])] 1 total sum(counter.values()) for cid, cnt in sorted(counter.items()): print(f类别 {cid}: {cnt} 框, 占比 {cnt/total:.1%})如果某一类占比不到 1%模型基本学不动得靠过采样、复制粘贴增强或专门补数据。反过来如果某类占了 60% 以上其他类会被压制考虑用类别权重或 focal loss 缓解。这个统计我每次拿到新数据集都强制跑一遍比看总图片数有用得多——10000 张图里可能 9000 张只有船那这个数据集的真实难度和宣传的完全不是一回事。还有个验证习惯训完后拿测试集跑推理把预测框画回原图肉眼扫一遍。指标再好看框飘到天上或漏掉密集小目标说明数据或后处理还有问题。海洋场景水面反光强模型容易把浪花当目标这种误检在指标里不一定显眼但实际部署时很致命。从那以后我每次拿到新数据集都强制走一遍完整性校验 → 类别分布 → 冒烟训练 → 混淆矩阵复查这套流程宁可前期多花两小时也不愿训到半夜发现标签是错的。希望帮到你。本文还有配套的精品资源点击获取
返回列表