海底鱼类检测数据集:VOC/COCO/YOLO三格式+YOLO11训练脚本 简介面向目标检测与水下视觉方向的开发者这份海底鱼类检测数据集可有效支撑水下机器人、海洋牧场等场景的鱼类识别与监测项目。数据涵盖浅海珊瑚礁、深海沉船周边、沙底海草区等多样环境并特意加入遮挡与严重遮挡样本统一标注为“Fish”单类别且提供VOC、COCO、YOLO三种标准格式标签无需再做格式转换即可用于YOLO等主流模型训练。资源包共1个PDF文件约3.81MB内含数据集基本情况介绍、缩略图与labelimg标注截图同时附YOLO11一键训练脚本说明覆盖GPU、CPU及MacM芯片多平台执行方式并给出博主训练结果日志方便对比精度与损失变化。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到1YOLO系列训练时零转换直接读。做过训练的人都知道格式转换是重灾区。坐标系的换算、类别ID的对齐、归一化是否做对任何一个环节出错轻则标签白做重则模型训完mAP惨不忍睹还找不到原因。我见过太多人不是死在模型上而是死在“VOC转YOLO之后标签全偏了”这种问题上。所以这次把三种格式一次性给齐本质上是用一份标注成本覆盖三种使用路径无论你习惯哪个生态拿过来就能用。1.4 为什么默认选YOLO11而不是YOLOv8YOLO11是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.yamlYOLO格式对应的就是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, saveTrue)能正常出检测结果说明整个依赖链是通的再往后走训练流程就顺畅很多。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( datadata_yaml, epochs100, imgsz640, batch16, device0, # 指定GPUCPU则写devicecpu workers4, projectruns/train, namefish_yolo11n, patience20, # 早停验证集指标20轮不提升就停 save_period10, # 每10轮存一次权重 ) if __name__ __main__: main()train方法里这些参数绝大多数保持默认就能跑但有几个值得根据自己的实际情况调整。imgsz推荐先用640跑通流程如果发现小目标检测效果不好再升到1280。batch优先用显卡能承受的最大值8G显存跑yolo11n的话batch16一般没问题显存不够就往下减或者开启梯度累积。epochs先给100配合patience早停机制模型在验证集上长时间不提升就会自动停止不会白白浪费时间。3.4 目标检测训练过程中的评价标准目标检测训练过程中评价标准是最容易让人困惑的部分这里必须讲透。YOLO训练结束后会输出一组指标PPrecision查准率、RRecall召回率、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时的mAPmAP50-95则是IoU从0.5到0.95按0.05步长计算后取平均。后者的要求严苛得多也更贴近真实场景——在密集鱼群场景里框稍微偏一点IoU就可能跌破0.75。所以我判断模型好不好优先看mAP50-95mAP50高只能说明模型“大概能定位”mAP50-95高才说明框得准。4. 常见问题与排查技巧实录4.1 标签格式转换的经典错误虽然这次直接给了三种格式但你以后扩数据时一定会遇到格式转换问题提前把这些坑讲清楚。第一个坑是坐标系搞混。VOC的坐标是左上角和右下角的像素坐标xmin, ymin, xmax, ymaxCOCO是左上角加宽度高度x, y, w, hYOLO是归一化的中心点加宽高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提到1280mAP50-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只作为参考。最后再分享一个小技巧训练完成后别急着部署先用测试集单张图片跑一遍推理保存预测结果图人工检查每个类别的预测效果。水下场景的类别形态很相似比如两条花纹接近的鱼人工都可能分不清模型更可能把类别搞混。遇到这种情况不要盲目加大模型容量先看看是不是标注本身有歧义把易混淆类别的标注样本重新核对一遍往往比换更大模型更有效。本文还有配套的精品资源点击获取