news 2026/9/20 14:50:16

海底鱼类检测数据集:VOC/COCO/YOLO三格式+YOLO11训练脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
海底鱼类检测数据集:VOC/COCO/YOLO三格式+YOLO11训练脚本

简介:面向目标检测与水下视觉方向的开发者,这份海底鱼类检测数据集可有效支撑水下机器人、海洋牧场等场景的鱼类识别与监测项目。数据涵盖浅海珊瑚礁、深海沉船周边、沙底海草区等多样环境,并特意加入遮挡与严重遮挡样本,统一标注为“Fish”单类别,且提供VOC、COCO、YOLO三种标准格式标签,无需再做格式转换即可用于YOLO等主流模型训练。资源包共1个PDF文件,约3.81MB,内含数据集基本情况介绍、缩略图与labelimg标注截图,同时附YOLO11一键训练脚本说明,覆盖GPU、CPU及Mac(M芯片)多平台执行方式,并给出博主训练结果日志,方便对比精度与损失变化。PDF中还清晰说明了百度网盘获取方式,读者可据此快速拿到完整图片与标签数据。对刚接触目标检测的初学者,可借助这些材料理解数据组织方式与训练流程;对有项目需求者,也可快速评估该数据集对海底监测场景的适配性。目前已有89人学习,适合作为算法入门和项目验证的实用参考资料。 做水下视觉方向的人应该都有个共同的痛点:跑通一个目标检测模型不难,难的是手里的数据根本撑不起你的想法。陆地场景的数据集随手就是几万张,车辆行人猫猫狗狗随便下,可一旦把场景换到海底,公开资源立刻变得稀薄。这次搭的这套“海底鱼类检测数据集 + VOC/COCO/YOLO三种标签格式 + YOLO11一键训练脚本”方案,就是冲着这个痛点去的。1000张水下图片,配好三种主流标签,再加一个改改路径就能跑的训练脚本——不管你是刚入门目标检测的学生,还是准备做水下渔业监测、海洋生态调查的工程开发者,这套东西都能帮你省掉两周以上的数据准备时间,直接进入模型训练和效果验证阶段。

1. 项目整体设计与思路拆解

1.1 项目的核心价值在哪里

先说说我为什么要按这个结构来设计。目标检测项目的完整链路包括:数据采集、数据清洗、标注、格式转换、模型训练、评估、部署。真正让人头疼的往往不是模型,而是前面那一大堆数据工程。尤其在水下场景,数据获取成本本来就高——要下潜、要布设设备、要在复杂光照里拍到清晰可用的鱼,一不小心拍回来一堆模糊重影,还得重新来。

所以这套方案的核心价值,就是把“从零准备训练数据”这个最劝退的环节直接压缩到零。数据集里每一张图片都清洗过、标注过、转换过,你拿到的不是一堆散装素材,而是一套开箱即用的训练资源。从工程角度看,这相当于把目标检测项目里最容易出错、最耗时、最难量化进展的部分,提前帮你做完了。

1.2 1000张图的规模到底够不够用

很多人看到1000张图,第一反应是“这么少,能训出个啥?”我的判断是:作为基线验证和第一版业务测试,这个规模非常合理。

海底鱼类检测和通用物体检测不太一样。如果类别结构控制得当,比如10类以下的常见鱼种,1000张图配合预训练权重做迁移学习,每类大约能分到80到150个目标实例,足以让模型学会基本的颜色、纹理、轮廓特征。YOLO11自带了在COCO上预训练好的权重,模型不是从零开始学,它已经知道“什么是边缘、什么是纹理、什么是物体”,你只需要让它学会“鱼长什么样”。这个场景下,几百张图的增量学习就够看到明显效果了。

另外要算一笔账:一张1920x1080的水下图像,如果鱼群密集,人工标注要花3到5分钟;配合质量校验,1000张图大概要三到五天完整工时。如果还要做三种格式的转换和抽检,又是一到两天。1000张的规模,恰好控制在一个人一周内能完成数据准备工作的范围内,不劝退、不烂尾,训练迭代一次也就几十分钟到几小时,非常适合快速验证想法。

1.3 为什么要同时给VOC、COCO、YOLO三种格式

这三个格式不是凑数,它们各自代表了一个主流工具生态。VOC格式是XML文件,一张图对应一个标注文件,结构里带object节点和bndbox像素坐标,数据标注工具(比如LabelImg、Roboflow导出)和传统检测框架对它的兼容性最好,用来做人工检查和可视化最直观。COCO格式是把所有标注汇总成一个JSON文件,用images、annotations、categories三个数组组织,mmdetection、Detectron2这类框架原生支持,而且COCO的annotation里可以带segmentation字段,以后想从检测升级到实例分割,标签还能复用。YOLO格式则是一个txt文件一行一个目标,格式是“类别ID 中心点x 中心点y 宽度w 高度h”,全部归一化到0到1,YOLO系列训练时零转换直接读。

做过训练的人都知道,格式转换是重灾区。坐标系的换算、类别ID的对齐、归一化是否做对,任何一个环节出错,轻则标签白做,重则模型训完mAP惨不忍睹还找不到原因。我见过太多人不是死在模型上,而是死在“VOC转YOLO之后标签全偏了”这种问题上。所以这次把三种格式一次性给齐,本质上是用一份标注成本覆盖三种使用路径,无论你习惯哪个生态,拿过来就能用。

1.4 为什么默认选YOLO11而不是YOLOv8

YOLO11是Ultralytics在2024年推出的版本,相比YOLOv8,它在网络结构上调整了C3K2模块、改进了SPPF结构,并且引入了C2PSA注意力机制。实测下来,在同等算力下YOLO11的精度和推理速度都有小幅提升,尤其对小目标的召回率改善比较明显。这个特性对海底鱼类检测非常关键——水下图片里很多鱼在画面中占比很小,经常躲在水草、珊瑚后面,目标只有几十个像素大小。小目标检测能力不行的模型,在这种场景下基本等于瞎猜。

还有一个很现实的原因:生态成熟度。Ultralytics已经把数据加载、增强、训练、验证、导出的流程全部封装好了,一个yaml配置文件加一行训练命令就能跑,对新手极其友好。同时它又没有锁死扩展空间,改Backbone、加检测头、换损失函数都还方便。所以选YOLO11是“低门槛 + 高天花板”的折中,既照顾了刚入门的同学,也留足了老手做改进的空间。

2. 数据集的核心细节与预处理实操

2.1 水下场景的数据特点

这套数据集围绕海底自然环境构建,图片来源覆盖不同光照条件和不同水体能见度。水下目标检测的典型难点,在数据集里都有体现。

第一个难点是色彩偏移。海水会吸收红光和黄光,水下图像普遍偏蓝偏绿,鱼体真实颜色被严重改变。模型如果在偏色严重的图上训练,学到的颜色特征可能是“被水染过之后的颜色”,而不是鱼本身的颜色。第二个难点是对比度差。水中的悬浮颗粒会造成散射,图像像蒙了一层雾,鱼和背景的边界模糊。第三个难点是密集遮挡。鱼群聚集时,大量目标互相遮挡,边界框重叠严重,这对模型的NMS后处理和小目标检测能力都是考验。

有意思的是,这些问题既是“麻烦”,也是“价值”。用一套包含这些困难场景的数据训练出来的模型,放到真实水下环境中反而不容易崩。如果数据本身太干净,训练时看着指标很好,一到实际部署就露馅。

2.2 三种标签格式的组织与目录结构

拿到手的数据集,目录结构是按照YOLO训练习惯排好的,大概长这样:

fish_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── annotations/ │ ├── voc_xmls/ │ ├── coco_train.json │ ├── coco_val.json │ └── coco_test.json └── fish.yaml

YOLO格式对应的就是images和labels两个目录,图片和txt标签一一对应;VOC格式的XML统一放在annotations/voc_xmls下;COCO格式的JSON也放在annotations里。这样设计的好处是,不管你要用哪种格式,都不用再重新组织目录,直接指向对应路径就能训练。

关于标签内容,YOLO格式的txt每行五个数,第二个和第三个是归一化后的中心点坐标,第四第五个是归一化后的宽高。这里要特别提醒一下:YOLO坐标的数值范围是0到1,而且是相对于整张图片的宽高,不是相对于目标所在裁剪区域。举个例子,一张1920宽、1080高的图,某个目标的中心点x坐标是960,那归一化后的值就是0.5。这个细节如果搞错,训练出来的模型预测框会全部偏到画面边缘。

2.3 水下图像预处理该做哪些事

拿到数据别急着直接丢给模型,先花半天时间做基础预处理,效果会差很多。

第一步是色彩校正。最简单的做法是灰度世界算法:计算全图RGB三个通道的平均值,然后调整增益让三个通道的平均值趋于一致,这样能把海水造成的蓝色偏色拉回来一些。也可以用更专业的白平衡工具,但这些工具得注意不要过度饱和。第二步是增强对比度,推荐CLAHE(对比度受限自适应直方图均衡化),它能把局部细节的对比度拉起来,同时不会像全局直方图均衡化那样把噪声也一起放大。

但这里有一个原则性问题:预处理是辅助,不是主角。训练时要使用和部署环境一致的数据分布,如果部署时你不可能在每帧画面上做复杂增强,那么训练时也别做得太狠。我的习惯是,训练前只做轻度的色彩校正和CLAHE,把决定“能不能检测到”这件事交给模型自己去学,而不是靠预处理硬撑。

3. YOLO11环境配置与一键训练脚本实操

3.1 环境准备与依赖安装

YOLO11基于PyTorch,环境配置的几大件是Python、CUDA、PyTorch和Ultralytics包。安装命令非常简单:

pip install ultralytics

装完之后可以用一行命令验证:

python -c "from ultralytics import YOLO; print(YOLO.__version__)"

如果机器上有NVIDIA显卡,一定要确认PyTorch装的是CUDA版本。判断方法很简单,跑下面这行:

import torch print(torch.cuda.is_available())

如果输出False,大概率是装了CPU版PyTorch,训练会慢到怀疑人生。新手最常犯的错就是这一步没检查,跑了十几个小时后才发现一直在用CPU。

建议装完环境后先跑一个官方预训练模型的推理测试,随便拿数据集的某张图:

from ultralytics import YOLO # 用n版本,最轻量 model = YOLO("yolo11n.pt") results = model.predict("fish_dataset/images/val/0001.jpg", save=True)

能正常出检测结果,说明整个依赖链是通的,再往后走训练流程就顺畅很多。

3.2 数据集yaml配置文件怎么写

YOLO训练必须要有一个yaml文件来描述数据集信息。这份数据集的yaml内容大致是:

path: fish_dataset train: images/train val: images/val nc: 5 names: 0: clownfish 1: butterflyfish 2: angelfish 3: grouper 4: snapper

几个关键点要留意。path字段指向数据集根目录,train和val是相对于path的路径,YOLO会自动去path/train找图片、去path/labels/train找对应标签。nc是类别总数,names是类别名列表,顺序必须和标签txt里的类别ID严格对应。如果你只改了nc没改names,或者names顺序和标注时的顺序不一致,训练过程不会报错,但最终模型的预测输出类别会全部错位,这是个非常隐蔽的坑。

还有一种常见错误是图片路径和标签路径不匹配。YOLO默认把images目录下的图片对应到labels目录下同名txt,比如images/train/0001.jpg对应labels/train/0001.txt。如果目录结构不符合这个约定,训练时会疯狂警告“label not found”,一张图都喂不进去,最后精度直接为0。所以在自定义数据时,目录结构一定不要随意改。

3.3 一键训练脚本的核心逻辑

这份方案里的“一键训练脚本”本质上是一个把训练参数集中管理的Python脚本,核心逻辑是读取yaml配置、实例化模型、启动训练。简化后的骨架大致长这样:

from ultralytics import YOLO def main(): data_yaml = "fish_dataset/fish.yaml" model = YOLO("yolo11n.pt") # 加载预训练权重 model.train( data=data_yaml, epochs=100, imgsz=640, batch=16, device=0, # 指定GPU,CPU则写device="cpu" workers=4, project="runs/train", name="fish_yolo11n", patience=20, # 早停,验证集指标20轮不提升就停 save_period=10, # 每10轮存一次权重 ) if __name__ == "__main__": main()

train方法里这些参数,绝大多数保持默认就能跑,但有几个值得根据自己的实际情况调整。imgsz推荐先用640跑通流程,如果发现小目标检测效果不好,再升到1280。batch优先用显卡能承受的最大值,8G显存跑yolo11n的话batch=16一般没问题,显存不够就往下减,或者开启梯度累积。epochs先给100,配合patience早停机制,模型在验证集上长时间不提升就会自动停止,不会白白浪费时间。

3.4 目标检测训练过程中的评价标准

目标检测训练过程中评价标准是最容易让人困惑的部分,这里必须讲透。YOLO训练结束后会输出一组指标:P(Precision,查准率)、R(Recall,召回率)、mAP50、mAP50-95。逐一说清楚。

Precision衡量的是“模型检测出的所有框中,有多少是真正正确的”,也就是FP(误检)越少,Precision越高。Recall衡量的是“所有真实目标中,有多少被成功检测出来”,FN(漏检)越少,Recall越高。二者是此消彼长的关系:阈值调高,模型只输出高置信度的框,Precision高但Recall低;阈值调低,框出更多目标,Recall高但误检也变多。所以单独看P或R都没有意义,要看它们的综合表现。

mAP是核心中的核心。对每个类别,在不同置信度阈值下画出以Recall为横轴、Precision为纵轴的PR曲线,曲线下的面积就是AP。mAP是所有类别AP的平均值。mAP50表示IoU阈值为0.5时的mAP,mAP50-95则是IoU从0.5到0.95按0.05步长计算后取平均。后者的要求严苛得多,也更贴近真实场景——在密集鱼群场景里,框稍微偏一点IoU就可能跌破0.75。所以我判断模型好不好,优先看mAP50-95,mAP50高只能说明模型“大概能定位”,mAP50-95高才说明框得准。

4. 常见问题与排查技巧实录

4.1 标签格式转换的经典错误

虽然这次直接给了三种格式,但你以后扩数据时一定会遇到格式转换问题,提前把这些坑讲清楚。

第一个坑是坐标系搞混。VOC的坐标是左上角和右下角的像素坐标(xmin, ymin, xmax, ymax),COCO是左上角加宽度高度(x, y, w, h),YOLO是归一化的中心点加宽高(cx, cy, w, h)。VOC转YOLO的公式是:

YOLO_x_center = (xmin + xmax) / 2 / img_width YOLO_y_center = (ymin + ymax) / 2 / img_height YOLO_width = (xmax - xmin) / img_width YOLO_height = (ymax - ymin) / img_height

注意img_width和img_height必须是原图尺寸,很多转换脚本出错,就是因为读取的是缩放后的尺寸,而不是原始尺寸。

第二个坑是类别ID对齐。VOC和COCO用类别名或全局ID来标识目标类别,YOLO则用从0开始的整数索引。同一个类别在不同格式之间转换时,如果类别列表顺序定义不一致,所有框的类别就会集体错位。比如VOC里“clownfish”是第3类,转到YOLO时如果names列表里第0个是“grouper”,那所有clownfish的框都会被标成grouper。建议转换前把类别列表固定下来,每次转换后随机抽几张图可视化验证一下。

第三个坑是难例样本被丢弃。VOC的XML里如果有truncated(目标被截断)或difficult(目标难以辨认)字段,部分转换脚本会直接把这类目标删掉。删掉之后训练样本变少,而且被删的往往是困难样本,模型学不到对抗遮挡和截断的能力。转换时一定要检查脚本对这些字段的处理策略,最好是保留而不是删除。

4.2 训练不收敛或loss曲线异常

我自己的经验是,训练过程中如果loss一直不降,先别急着调参,优先怀疑标签有问题。用Ultralytics提供的可视化工具把图片和标注框画出来,如果框的位置明显偏离目标、大小异常、或者类别名对不上,先修复标签再重新训练,不然调参调半天也是瞎忙。

还有一种常见情况是类别严重不平衡。比如数据集中某种鱼占了百分之七十以上的样本,另一种鱼只有几十张,模型会倾向于把所有预测都推向多数类。解决办法可以从三个方向入手:一是给少数类类别在loss计算中增加权重;二是对少数类样本做额外的数据增强,比如随机裁剪、旋转、色彩抖动,让它的有效样本量变大;三是从数据源头补充样本。海底鱼类的场景里,类别不均衡几乎必然存在,所以训练完一定要按类别分别查看AP,不要只看整体mAP。

还有一点容易被忽略:learning rate。YOLO11默认会自动设置学习率,一般不用改,但如果你用了自定义的数据集且标签噪声大,可以尝试把初始学习率调低一点,比如从0.01降到0.001,防止模型在噪声标签上快速过拟合。调完之后观察前20轮的loss下降趋势,如果loss震荡剧烈,通常就是学习率偏高了。

4.3 显存不足与训练速度优化

如果你用的是8G显存的显卡,跑yolo11s或yolo11m时大概率会遇到CUDA out of memory。优先降低batch,其次是降低imgsz,还可以开启梯度累积模拟更大的batch。Ultralytics里直接设置batch参数不方便做梯度累积时,就手动把batch调小到不爆显存为止,配合patience早停,效果通常可以接受。显存够但训练太慢时,优先把workers调高,让数据加载不再卡在CPU上,其次确认训练过程中GPU利用率是否跑满了,用nvidia-smi观察利用率如果长期低于50%,瓶颈大概率在数据读取,而不是模型计算。

水下小目标比较多的话,我建议有条件就上1280分辨率训练。实测下来,从640提到1280,mAP50-95通常能提升三到五个点,代价是显存和时间翻倍。如果显存不够,可以把原图裁剪成带重叠的小图训练,推理时再做拼贴,这也是KITTI、DOTA这类数据集常用的训练方式。

4.4 快速上手的一些建议

如果你第一次用这套方案,我的建议是先完整跑通一遍,再考虑优化。第一次训练就用默认参数,epochs给100,权重文件用yolo11n.pt,先看整体的P、R、mAP三个指标,并保存检测结果图检查预测框的分布。只有在“检测框位置基本正确、但边界不够紧”的情况下,才值得去改输入分辨率、调数据增强、换更大的模型。如果跑了50轮mAP还低于0.1,大概率不是参数问题,而是数据路径或标签没配对。

另外,YOLO11训练过程中会生成runs/train目录,里面有每次epoch的loss曲线和验证集指标图,一定要养成看这些曲线的习惯。loss下降但mAP不动,说明模型在拟合训练集但泛化不够,这时候优先考虑数据增强;loss没下降但mAP却在缓慢上升,也不用慌,有时候模型置信度校准和检测框精度的提升并不会直观反映在loss曲线上。以mAP为准,loss只作为参考。

最后再分享一个小技巧:训练完成后,别急着部署,先用测试集单张图片跑一遍推理,保存预测结果图,人工检查每个类别的预测效果。水下场景的类别形态很相似,比如两条花纹接近的鱼,人工都可能分不清,模型更可能把类别搞混。遇到这种情况,不要盲目加大模型容量,先看看是不是标注本身有歧义,把易混淆类别的标注样本重新核对一遍,往往比换更大模型更有效。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 14:48:51

PyAutoGUI桌面自动化完全指南:鼠标键盘操作与图像识别避坑

简介:这是一份Python桌面自动化入门教程,聚焦pyautogui模块在鼠标与键盘模拟方面的应用,适合需要开展UI自动化测试、批量重复操作或桌面应用脚本开发的开发者,也可作为自动化测试初学者的上手参考。PDF文档以实例为主线&#xff0…

作者头像 李华
网站建设 2026/9/20 14:48:48

SpringBoot+Vue新闻推荐系统实战:从开发到Docker部署

简介:本资源是一套完整的新闻推荐系统毕业设计项目,面向计算机专业本科生及全栈开发初学者,解决前后端分离架构下推荐功能落地的实战难题。压缩包共742个文件,14.82MB,涵盖90个Java后端核心类(含SpringBoot…

作者头像 李华
网站建设 2026/9/20 14:46:55

ESP32 + MAX30102 实战:从传感器原理到心率血氧监测全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 14:45:39

销售团队CRM选型与落地实战:数据清洗、权限设计与自动化流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 14:44:06

Agent 工具 30+ 上下文混淆?TaoToken 这样改模型 Base URL

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 14:43:16

2026年Flash还能用吗?4399老游戏运行与安装全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华