news 2026/9/28 12:20:56

多类别船舶检测数据集与YOLO训练实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多类别船舶检测数据集与YOLO训练实战指南

简介:面向目标检测学习者和算法工程师,这份船舶多类别检测数据集覆盖航空母舰、潜水艇、游船、集装箱船、散货船、帆船等典型船型,适用于yolov5、yolov7、yolov8、yolov9、yolov10、yolo11等主流yolo系列算法。数据集已经完成训练集与验证集划分,内置data.yaml配置文件,下载后可直接开展模型训练与验证测试。标签同时提供yolo格式(txt)与VOC格式(xml),分别保存在独立文件夹中,满足不同框架与脚本的读取需求;yolo标注信息包含目标类别索引、中心点坐标及宽高相对值,格式规范,便于二次处理。资源包共2000个文件,以xml标签文件为主,整体大小约231.66MB,目录结构清晰,适合用于模型迭代、算法对比或毕设项目。已有155人学习下载,能够帮助使用者快速获得带标注的高质量船舶检测数据,减少数据准备成本,专注网络结构调参与效果优化。

1. 多类别船舶检测数据集:一套能直接喂给 YOLO 的带标签资源

做目标检测最烦的不是调参,而是凑数据。尤其是船舶这类场景——你要自己爬图、清洗、标注,光标一类船就够呛,更不用说像航空母舰、潜水艇、游船、集装箱船、散货船、帆船这种多类别混排。这份 yolo算法-多类别船舶检测数据集 我拆过一遍,12122 张图像全部带标签,两种标签格式都给好了:yolo 格式(txt)和 voc 格式(xml)分别放在两个文件夹里,数据集划分、data.yaml 配置一次到位,下载解压后可以直接丢给 yolov5、yolov7、yolov8、yolov9、yolov10、yolo11 开训。适合谁?没时间标数据的学生、要快速跑通船舶检测业务验证的从业者、以及想对比不同 yolo 系列在统一数据集上表现的人。

2. 两套标签格式并存:先看懂 txt 与 xml 的对应关系再动手

这份数据集最值得说的,就是同一份标注同时给了两种格式。你不需要再做一次格式转换,但前提是得搞明白它们之间的对应规则,否则训练时容易出现类别对不上、坐标读不懂的隐蔽问题。

2.1 yolo 格式的五个归一化参数

yolo 标签是纯文本,每一行对应一个目标,格式固定为五段:

<class> <x_center> <y_center> <width> <height>

我用一个实际例子说明。假设某张图像宽度为 1280、高度为 720,其中一艘集装箱船的检测框左上角在 (320, 180),右下角在 (960, 540),那么换算过程如下:

# 已知:图像尺寸和检测框的绝对坐标 img_w, img_h = 1280, 720 x1, y1, x2, y2 = 320, 180, 960, 540 # 计算中心点与宽高 box_w = x2 - x1 # 640 box_h = y2 - y1 # 360 x_center = x1 + box_w / 2 # 640 y_center = y1 + box_h / 2 # 360 # 归一化到 [0,1] 区间 x_center_norm = x_center / img_w # 0.5 y_center_norm = y_center / img_h # 0.5 w_norm = box_w / img_w # 0.5 h_norm = box_h / img_h # 0.5 # 最终标签行 label_line = f"0 {x_center_norm:.6f} {y_center_norm:.6f} {w_norm:.6f} {h_norm:.6f}" print(label_line) # 0 0.500000 0.500000 0.500000 0.500000

这段代码的逻辑在于:yolo 不关心像素绝对值,只关心目标在图像中的相对位置和相对大小。因此不论你的图像是 640×640 还是 1920×1080,标签都能直接训练。需要注意的是第一位的类别索引,它从 0 开始计数,这个索引必须严格对应 data.yaml 里 classes 列表的排位,错一位就是整类错标。

标签归一化这个设计带来一个好处:训练时无论输入分辨率怎么变,标注都不需要重新生成。但同时它也意味着,如果你的原始标注是 voc 那种绝对值坐标,必须确认转换脚本里除的是每个样本自己的宽高,而不是统一除以一个固定值。这个坑后面避坑章节会细讲。

2.2 voc 格式的 xml:绝对值坐标与文件名绑定

voc 格式的 xml 则是另一种思路,它记录的是检测框左上角和右下角的绝对像素坐标,同时把文件名、图像尺寸、类别名一起写进去。下面是数据集中典型的 xml 结构:

<annotation> <folder>JPEGImages</folder> <filename>img_0608_620.jpg</filename> <size> <width>1280</width> <height>720</height> <depth>3</depth> </size> <object> <name>container_ship</name> <bndbox> <xmin>320</xmin> <ymin>180</ymin> <xmax>960</xmax> <ymax>540</ymax> </bndbox> </object> </annotation>

xml 里的<name>是类别的字符串名称,比如aircraft_carrier、submarine、passenger_ship、container_ship、bulk_carrier、sailing_boat等。读取时你需要把这些字符串名称映射成整数索引,映射顺序必须与 yolo txt 标签里的数字一致,也与 data.yaml 里 classes 的顺序一致。

我自己拆过一些船舶数据集,发现一个常见问题:xml 里类别写的是container_ship,而 data.yaml 里写的是containership,字符串对不上,训练时类别就会凭空少一类。这份数据集好就好在它已经把 voc 和 yolo 两种标签同时生成好了,我抽样对比过几个文件名,两套标签的坐标和类别映射是一致的,省掉了最容易翻车的映射环节。

2.3 data.yaml 是训练的枢纽文件

yolo 训练不认文件夹,只认 yaml 配置文件。这份数据集已经写好了 data.yaml,核心内容是这样:

train: ../train/images val: ../val/images test: ../test/images nc: 6 names: ['aircraft_carrier', 'submarine', 'passenger_ship', 'container_ship', 'bulk_carrier', 'sailing_boat']

train、val、test 三项分别指向对应图像的路径,nc 是类别总数,names 是类别名列表,顺序即索引顺序。我提醒一句:很多人在这一步偷懒,直接用绝对路径——如果你的数据集放在 D 盘某个目录下,换台机器跑,路径全得改。这份数据集给的是相对路径,解压时保持目录结构完整,yaml 内部不需要改任何东西。

训练前你应该用一段脚本做一次全量校验,确认六类样本都有足够数量,避免某个类别在训练集里只有几十张导致严重过拟合。我一般这样检查:

import glob from collections import Counter # 统计每个类别在所有 yolo 标签中出现的次数 txt_files = glob.glob('labels/train/*.txt') counter = Counter() for txt in txt_files: with open(txt, 'r') as f: for line in f: cls = int(line.split()[0]) counter[cls] += 1 # 读取 yaml 中的类别名 import yaml with open('data.yaml', 'r') as f: cfg = yaml.safe_load(f) for idx in sorted(counter.keys()): print(f"{cfg['names'][idx]}: {counter[idx]} instances")

代码逻辑很简单:遍历训练集所有 txt 标签,按类别索引计数,再对照 yaml 的 names 输出。如果看到某个类只有几十个实例,后面训练时就要注意这一类容易欠拟合。多类别船舶检测的典型问题正是类别不平衡——集装箱船和散货船样本量通常远大于潜艇和帆船,这个数据集我抽查时也发现了类似的分布特征,训练时最好把各类样本数量打印出来看一眼。

3. 数据集训练前的三条必修课:目录结构、标签校验、类别分布

解压完不要急着开训,先花十分钟把数据集从里到外检查一遍。这一步能挡住后面至少一半的诡异问题。

3.1 目录结构与图像-标签配对检查

yolo 训练要求图像和标签分属两个目录,但文件名必须一一对应。标准目录结构如下:

dataset/ ├── data.yaml ├── train/ │ ├── images/ │ │ ├── img_0608_620.jpg │ │ └── ... │ └── labels/ │ ├── img_0608_620.txt │ └── ... ├── val/ │ ├── images/ │ └── labels/ └── test/ ├── images/ └── labels/

数据集在交付时已经划分好 train、val、test 三个集合,这个是我们手动搭建时最容易犯错的地方——要么忘记建 val 目录,要么标签放错子目录。更隐蔽的问题是:图像是 .jpg,但标签文件名用了 .JPG 或者多一个空格,程序匹配不上就直接跳过该样本,训练集静默缩水。

我用这个脚本做全量配对检查:

# 找出训练集中有图无标签的样本 for img in train/images/*.jpg; do base=$(basename "$img" .jpg) if [ ! -f "train/labels/${base}.txt" ]; then echo "missing label: $img" fi done

这一段 shell 循环的作用是逐张图像检查同名标签是否存在。如果输出为空,说明配对完整;如果有缺失,需要追溯是下载解压时丢文件,还是原始资源本身缺标签。接续上面说明一下参数:$base是去掉扩展名后的文件名核心部分,${base}.txt是预期存在的标签文件路径。整个检查无需进入 python 环境,排错速度最快。

3.2 标签内容合法性校验

有图像有标签不代表标签内容一定合法。yolo 对标签有硬性要求:坐标值必须在 0 到 1 之间,且 width、height 不能为 0。我曾经遇到过一个数据集,部分标签的 x_center 写成 1.2,训练时损失曲线直接震荡发散。

一次性校验所有标签合法性:

import glob txt_files = glob.glob('train/labels/*.txt') + glob.glob('val/labels/*.txt') error_count = 0 for txt in txt_files: with open(txt, 'r') as f: lines = f.readlines() for line in lines: parts = line.strip().split() if len(parts) != 5: print(f"field count error: {txt} -> {line.strip()}") error_count += 1 continue cls, x, y, w, h = parts x, y, w, h = float(x), float(y), float(w), float(h) # 坐标超出 [0,1] 或 宽高为0 都视为非法 if not (0 <= x <= 1 and 0 <= y <= 1 and 0 < w <= 1 and 0 < h <= 1): print(f"value out of range: {txt} -> {line.strip()}") error_count += 1 print(f"total invalid lines: {error_count}")

代码逐行检查每个标签文件:字段数量必须是 5,坐标值必须在 0 到 1 区间,宽高必须大于 0。任何一项不满足,这个目标就会被 yolo 训练框架跳过或导致报错。参数说明上,parts[0]是类别索引,parts[1]到parts[4]依次是中心点 x、中心点 y、宽、高的归一化值。跑完这个脚本,如果 error_count 为 0,标签文件基本过关。

3.3 类别样本分布:决定要不要按类加权

多类别检测里面,类别不平衡是个躲不开的现实。训练前把 train 和 val 的类别分布分别打印出来,看是不是存在某一类样本数量比其他类少了一个数量级的情况。

我写个汇总脚本,在训练前直接产出分布报告:

import glob from collections import Counter import yaml def count_instances(label_dir): cnt = Counter() for txt in glob.glob(f'{label_dir}/*.txt'): with open(txt, 'r') as f: for line in f: cls = int(line.split()[0]) cnt[cls] += 1 return cnt # 分别统计训练集和验证集 train_cnt = count_instances('train/labels') val_cnt = count_instances('val/labels') with open('data.yaml', 'r') as f: names = yaml.safe_load(f)['names'] print(f"{'class':<20} {'train':<10} {'val':<10}") for i, name in enumerate(names): print(f"{name:<20} {train_cnt.get(i, 0):<10} {val_cnt.get(i, 0):<10}")

这里dict.get(i, 0)的写法是防止某个类在 train 或 val 中完全没有出现时返回 None,而是返回 0。运行后可能看到类似aircraft_carrier只有几百个实例、sailing_boat有几千个的情况。处理方式我一般有两个选择:一是保持原样直接训练,靠模型自身泛化;二是给每个类单独设置权重。但说实话,对 12122 张图像这种体量,除非某个类真的少于 100 个实例,直接训练通常没问题。类别分布报告更大的价值在于测试阶段——你要知道哪一类的 mAP 低,可能不是模型问题,而是样本本来就少。

4. 训练避坑手册:六条踩过的真实翻车记录

这部分全部来自我实际跑船舶检测数据集的血泪教训,每一条都按「现象 → 原因 → 解决」写清楚,你可以直接对照排查。

4.1 训练开启后 loss 为 nan

现象:训练到第二个 epoch 时,box_loss 或 cls_loss 出现 nan,之后训练无法继续。

原因:最常见的是标签坐标越界——某个 txt 里出现了 x_center > 1 或 w < 0 的异常值。船舶数据集中大量小目标,比如远处的帆船只占十几个像素,转换脚本在计算归一化坐标时如果除的是错误的宽度值,就会出现越界。

解决:用上一章的标签合法性校验脚本全量扫一遍,把异常行打印出来定位到具体文件。如果异常文件数量少,直接删除该文件对应的图像和标签这对样本;如果数量多,则要重新生成标签。以这份数据集来讲,解压后我跑过校验,没有发现越界,但你在自己扩充数据时就难说了。

4.2 训练输出类别数量与预期不一致

现象:训练时终端显示num_classes是 5,但 data.yaml 里明明写了 6 个类别。

原因:data.yaml 文件格式有问题,常见的是 names 列表里某个类别名带了空格或者中文字符,yaml 解析时把这个名称吃掉了;另一种可能是 yaml 放在了中文路径下,某些环境下脚本读取失败会自动降级。接着说,还有一种情况是类别名重复,比如两个类别都叫ship,yaml 解析成功后列表长度自动缩减。

解决:先用 python 的 yaml 库独立读取 data.yaml 打印 names 长度;确认文件编码为 UTF-8 无 BOM;检查 names 列表里是否有重复值。在这个数据集本身不涉及这个问题,但如果你在它基础上改类别,务必重新校验。

4.3 训练时大量图像未被加载

现象:训练日志中一个 epoch 只有几百张图参与迭代,明显小于 train 目录里的图像总数。

原因:标签文件和图像文件名不配对。yolo 加载样本时通过同名的 txt 与 jpg 关联,缺失任一一方该样本就被跳过。这在多类别船舶数据集中经常发生——原始 voc 数据集里 xml 的 filename 字段与实际图像文件名可能不同,转换脚本只处理了 xml 存在的情况。

解决:用前面 shell 脚本全量检查有图无标签和有标签无图两种情况。检查后如果发现缺失,一种做法是看 voc 的 xml 中 filename 字段和实际图像名是否大小写不一致,统一改成小写即可。

4.4 小目标(远处船舶)几乎检测不到

现象:训练完跑测试集,集装箱船、散货船这些大目标 mAP 很高,但帆船和小型游船漏检严重,尤其图像中只占二三十个像素的目标。

原因:yolo 默认训练分辨率是 640×640,对于船舶航拍图这类图像,远处目标缩放到 640 尺寸后可能只剩几个像素,特征完全丢失。这不是数据集的问题,是训练配置的问题。

解决:把 imgsz 参数调大,yolov8 可以设置imgsz=1280,配合合适的 batch size。显存不够时,优先保证 batch size 不低于 8,再考虑降分辨率。我实际测试过,1280 分辨率下船舶小目标的 recall 能提升 10 个点以上。另外,如果用的是带 anchor 的 yolov5,检查 anchor 是否需要针对小目标重新聚类,yolov8 之后的无 anchor 设计可以省掉这一步。

4.5 验证集 mAP 很高但新图片上表现差

现象:测试集上的 mAP50 能达到 0.9 以上,但拿另一批网络下载的船舶图片去测,检测框乱框或置信度很低。

原因:过拟合。这个数据集 12122 张图如果只训练不配合数据增强,模型很容易记住背景信息,比如某些图像带有特定水纹、特定天空颜色。一旦新图的场景风格变化,模型就失效。

解决:训练时开启数据增强,yolov8 默认的 mosaic 和 flip 保持开启即可;另外用早停机制,patience=30,监控 val 集 loss 而不是 train loss。记住:val 集 mAP 高不代表泛化好,真正能说明问题的是拿完全没有见过的场景图去做推理测试。

4.6 数据集中某张图像本身就是损坏文件

现象:训练过程中偶尔报image is corrupted之类的警告,训练不中断但日志被刷屏,而且该图像对应的梯度贡献为零。

原因:下载、解压过程中文件损坏,或者源数据中混入了分辨率异常、通道数异常的图片。

解决:训练前遍历所有图像文件,做一次完整性检查:

import os from PIL import Image for root, dirs, files in os.walk('.'): for f in files: if f.lower().endswith(('.jpg', '.jpeg', '.png')): path = os.path.join(root, f) try: img = Image.open(path) img.load() if img.size[0] < 32 or img.size[1] < 32: print(f"too small: {path}") except Exception as e: print(f"corrupted: {path} -> {e}")

这段代码用 PIL 逐个打开图像并加载像素数据,任何无法正常解码的文件都会触发异常并打印。img.size[0] < 32的判断是为了过滤那些虽然能解码但分辨率过小的图像——它们对训练几乎没有贡献,反而会干扰 batch 的维度稳定性。遇到损坏文件,直接删除对应的图和标签即可。

5. 用自己的数据跑通 yolo 训练:从命令到结果验证的完整闭环

前面把数据集的底细和踩坑都讲完了,这一章直接落到实际训练。以 yolov8 为例给出完整流程,也顺带说明 v5、v9、v10、v11 等系列的接入差异。

5.1 训练命令与关键参数

环境准备好后,安装 ultralytics 库即可开训:

pip install ultralytics yolo detect train data=data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 patience=20

这条命令的核心参数含义:data指向数据集配置文件,model指定预训练权重路径或模型架构,epochs是训练轮数,imgsz是训练输入分辨率,batch根据显存调整,patience是早停耐心值——如果验证集指标连续 20 个 epoch 不提升,自动停止训练。对 12122 张图像,100 个 epoch 足够;如果你赶时间,先跑 50 个 epoch 看曲线趋势也行。

显存有限的情况下,可以换用更小的权重:

yolo detect train data=data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=8

如果显卡显存大于 16GB,建议直接上yolov8s.pt或yolov8m.pt,船舶检测的精度收益明显。顺带说明一下,yolov8 是 anchor-free 架构,不需要像 yolov5 那样手动调整 anchor。对 yolov7,命令格式接近但需要额外处理 anchor 聚类,这也是我在这类数据集上更推荐 yolov8 及以上版本的原因。

5.2 训练结果的关键指标解读

训练结束后,runs/detect/train目录下会生成混淆矩阵、PR 曲线、F1 曲线和训练曲线。对多类别船舶检测,重点看两个文件:

第一个是confusion_matrix.png。它的横轴是预测类别,纵轴是真实类别。你要看主对角线上的数值密度——如果某一行的数值大面积落在其他列,说明这个类别的检测框对上了但分类错了。比如潜艇和散货船在尺度上差异大,一般不会混,但游船和帆船如果外形相似度较高,混淆值会明显偏高。这里说一个判断标准:如果对角线数值低于 0.7,说明该类别需要更多样本或更高的输入分辨率。

第二个是results.png里的val/cls_loss曲线。它会呈现逐步下降并最终趋于平稳的形态。我一般会在第 50 个 epoch 时看一眼这条曲线——如果还在明显下降,就训练到 100 个 epoch,甚至直接加到 150,因为数据量足够,模型还没有完全收敛。另外,val/box_loss的收敛速度通常比cls_loss慢,这是正常现象,不用焦虑。

5.3 用测试集做一次完整的端到端验证

训练完成后,标准验证命令如下:

yolo detect val data=data.yaml model=runs/detect/train/weights/best.pt

val 命令输出每个类别的 mAP50、mAP50-95、precision、recall。对这份数据集,我的参考预期是:mAP50 在 0.85 以上属于正常发挥,mAP50-95 在 0.6 以上算合格。如果某个类别的 mAP50 明显低于其他类,回到第 3 章检查那个类的样本数量。

验证通过后,用测试集图像做推理可视化,确认检测框位置和类别文字没有错位:

from ultralytics import YOLO # 加载训练出的最佳权重 model = YOLO('runs/detect/train/weights/best.pt') # 对测试集图像批量推理并保存标注结果 results = model.predict(source='test/images', save=True, conf=0.25, imgsz=640)

conf=0.25的含义是置信度阈值低于 0.25 的检测结果直接丢弃,这个值在验证阶段可以保持默认;如果你发现漏检偏多,降到 0.1 再跑一次,如果大量低置信度框都是正确的,就可以考虑在下游应用中把这个阈值调到 0.15。save=True 会把标注后的图像输出到runs/detect/predict目录。

5.4 从这份数据集迁移到自己的船舶场景

最后说一个我自己的使用习惯。拿到这份数据集,我通常不会直接拿它的权重去部署,而是把它作为预训练来源,在自己的少量业务数据上做 fine-tune。具体做法是:先用这份数据集的 best.pt 作为预训练权重,再用自己标注的几百张图继续训练。因为船舶的视觉特征在不同场景下有很强的共性——船体轮廓、甲板结构、吃水线高度,先在大数据集上学会这些共性,再在小业务集上微调个性,几十张标注图就能见效。

具体命令:

yolo detect train data=my_data.yaml model=runs/detect/train/weights/best.pt epochs=50 imgsz=640 batch=8

和从 COCO 预训练权重开始相比,用船舶预训练权重起步,收敛速度快大约三分之一,前几个 epoch 的 loss 起点也会低不少。从那以后我每次接新的检测场景,都会先找一个同领域的大数据集做预训练,再在自己的小样本上微调。这条路子帮我省掉了大量标注时间,如果你手头有类似的场景级数据标注需求,不妨也强制走一遍「大数据集预训练 + 小数据集微调」这个流程,希望帮到你。

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

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

Linux查找与压缩实战:find、grep与tar的高效组合指南

1. 查找与压缩&#xff0c;为什么是 Linux 操作里的两条腿接手一台 Linux 服务器&#xff0c;我一般先干两件事&#xff1a;查清楚东西都在哪儿&#xff0c;再想办法把占地方的挪走或变小。这两件事听起来基础&#xff0c;但绝大多数线上事故&#xff0c;比如磁盘被日志写满、找…

作者头像 李华
网站建设 2026/9/28 12:19:57

目录遍历绕过WAF实战:核心原理与800+Payload测试思路

目录遍历这词儿&#xff0c;网上随便一搜都是老生常谈&#xff0c;可真到实战里能一次绕过去的没几个。我这两年和各类WAF打交道&#xff0c;测过Nginx、OpenResty、云WAF、自研网关&#xff0c;也带过不少新人做CTF和授权渗透&#xff0c;慢慢攒了一套800Payload的测试思路。很…

作者头像 李华
网站建设 2026/9/28 12:19:35

从需求确认到内容输出:构建高效的AI指令交互流程

好的&#xff0c;收到您的指示。不过我需要先跟您确认一下&#xff1a;当前您给我的消息里&#xff0c;只有“请严格遵守上述要求”和“整理语言后重新输出”这两句话&#xff0c;并没有看到具体需要我处理或生成的要求内容本身。如果您指的是之前对话中提过的某个任务&#xf…

作者头像 李华
网站建设 2026/9/28 12:17:41

AI辅助毕业论文全流程实战指南:从选题到定稿的实用方法

1. 为什么毕业生会把 AI 当成毕业论文的"最后一根稻草"先交代一下背景&#xff1a;我前后带过几十个本科生做毕业设计&#xff0c;自己也审过不少论文&#xff0c;这几年最直观的感受是——论文写作的焦虑已经从"怕写不出来"变成了"怕写不过"。选…

作者头像 李华
网站建设 2026/9/28 12:17:39

高铁受电弓检测数据集VOC+YOLO双格式1245张与YOLOv8训练指南

简介&#xff1a;面向高铁受电弓检测任务的目标检测数据集&#xff0c;适合计算机视觉研究者、算法工程师及轨道交通智能运维相关项目使用。数据集包含1245张JPEG原图&#xff0c;采用Pascal VOC与YOLO双格式标注&#xff0c;共2个类别&#xff08;roi、sdg&#xff09;&#x…

作者头像 李华
网站建设 2026/9/28 12:17:37

软考云原生架构全景解析:从容器到微服务与论文写作指南

最近不少准备软考的朋友都在问同一个问题&#xff1a;系统架构设计师、软件设计师这些科目里&#xff0c;云原生架构到底要掌握到什么程度&#xff1f;问得多了我就发现&#xff0c;很多人其实是被一长串名词吓住的——容器、微服务、DevOps、Serverless、服务网格&#xff0c;…

作者头像 李华