ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于YOLO的船舶检测数据集构建与训练实战复盘

基于YOLO的船舶检测数据集构建与训练实战复盘

做海事监测或者水上交通管理的项目,很多时候第一步就会被数据卡住。公开的船舶数据集不少,但真正拿到手能直接喂给YOLO训练、不用花大量时间去清洗整理的,其实没有想象中那么多。尤其是那种背景复杂、包含不同类型船只、光照变化明显的水域实拍数据,更是稀缺。

我手上这个项目是一个包含3000张图片的船舶检测数据集,专门为YOLO系列模型标注生成的,目标类别覆盖了常见的货船、客船、渔船以及小型游艇等。项目本身不复杂,但把整个流程走下来——从数据采集、清洗、标注规范,到训练时的踩坑记录——还是有不少值得写下来的经验。这篇文章就围绕这套数据集展开,从设计思路到实际训练细节,完整复盘一遍。

1. 项目背景与整体设计思路

1.1 核心需求解析:为什么需要专门做一套船舶检测数据

说白了,船舶检测本质上是一个目标检测任务,和行人检测、车辆检测在算法层面没有本质区别。但实际做起来就会发现,水上场景有很多特殊的地方,直接套用通用检测模型或者COCO预训练权重,效果往往不尽如人意。

先说背景复杂度的问题。陆地检测的背景相对可控,路面、建筑、树木这些都有比较固定的纹理特征。但水面是完全不一样的,光照反射、波浪纹理、雾霾遮挡、天色变化,都会让背景在视觉上产生很大的干扰。尤其是太阳低角度的时候,水面反光会让模型的注意力被完全带偏,这在训练的时候如果数据里没有覆盖到,模型到了实际场景基本就废了。

再说物体特征的问题。行人、车辆这类目标有相对固定的外观比例,但船舶的形态差异性极大。一艘几万吨的散货船和一艘小舢板,在图像中的尺度可能相差几十倍;即使在同一个画面里,近处的一艘大船和远处的一艘小船,其视觉特征也完全不在一个量级。这就对检测模型的尺度适应性提出了很高的要求。

还有一个很容易被忽略的问题:类别区分度。如果只检测“船”这一个类别,那模型相对好做。但如果需要区分货船、渔船、客船,那难度就上来了——很多小船远远看去外形高度相似,仅靠单张静态图像很难区分。这就是为什么很多海事监测项目最终只做“船舶目标检测”而不做“船舶细分类”的原因。

这套3000张数据集的定位很明确:解决的是“有没有船、船在哪里”的问题,也就是通用船舶检测。在这个基础上,如果想进一步做分类或者属性识别,可以在这个检测结果的基础上再接一个分类网络,效果会比端到端硬做要好得多。

1.2 3000张图片的规模够不够用

很多初学者一听到3000张,第一反应是“这么少,能训练出来吗”。这个想法可以理解,但其实不太准确。目标检测任务的训练效果,不能只看数据量,更要看数据质量和数据分布。

3000张图,如果全部是同一个码头、同一个角度的重复拍摄,那别说3000张,3万张也一样过拟合。但如果3000张图覆盖了不同水域、不同天气、不同时段、不同船型、不同拍摄距离,那这个数据集的泛化能力会非常可观。

我在项目里具体划分了一下:训练集2400张、验证集300张、测试集300张。这个比例基本遵循8:1:1的经验准则。在YOLOv8的训练配置里,测试集主要用于最终模型评估,验证集用于训练过程中的早停和调参。

关键在于每张图片的平均目标数量。这套数据集的统计结果是平均每张图片包含2.5个船舶目标,3000张图总共标注了约7500个框。相比每张图只有一个目标的稀疏标注,多目标样本能让模型在每个训练批次中学到更丰富的特征对比——船与船之间的遮挡关系、不同尺度船只的共存情况、密集港口的拥挤场景,这些都在数据里有体现。

如果一个数据集的总目标数只有几千个,那3000张图确实显得单薄。但7500个标注框撑起来,信息量是完全足够的。这个理念想明白之后,你就会理解,数据集的优劣评估不能只看图片数量,更核心的指标是“有效标注密度”和“场景多样性”。

1.3 目标检测方案选型:YOLO系模型为什么合适

针对船舶检测这个任务,选YOLO系列几乎是共识,原因有几个。

第一是实时性。海事监测很多场景都是视频流分析,不管是岸基监控还是船载摄像头,都要求模型能跑实时推理。YOLO系列在检测精度和推理速度之间找到了一个很好的平衡点,尤其是YOLOv8之后,默认的C2f结构和Anchor-Free设计,让模型在同等算力下有了更好的表现。

第二是部署友好。YOLO的生态太成熟了。从训练到导出ONNX、TensorRT,再到各种边缘设备上的部署,都有非常成熟的工具链和文档。对于做实际项目的团队来说,这能省掉很多不必要的开发时间。

第三是便于迁移学习。用COCO预训练权重做初始化,在船舶数据上微调,通常几百个epoch就能收敛到不错的精度。相比从零训练,这种迁移学习的方式既节省了训练时间,又降低了对数据量的需求。

最终我在这个项目中用的是YOLOv8m这个中等规模的模型。它相比n和s版本有更高的精度上限,比l和x版本推理更快,在边缘设备上跑起来相对从容。具体效果后面会给出完整数据。

2. 数据集的采集标准与预处理流程

2.1 图片来源与场景覆盖维度

这套数据集的图片来源主要有两个渠道:一部分来自公开的航拍影像和岸基监控截图,另一部分来自合作单位提供的实拍数据。这里不涉及任何版权问题,全部都是授权可用。我想重点说的是,在收集船舶图片的时候,做了哪些有意识的场景控制。

第一个维度的控制是水域类型。内河航道和海上航道的差异非常大。内河的水面相对平静,背景是岸上的建筑和植被;海上的水面波动剧烈,背景是海天线和天空。如果数据集里只有内河场景,那模型到海上就会水土不服。所以这套数据在收集时,内河、近海、远洋三类场景都做了覆盖,比例大致控制在4:4:2。

第二个维度是光照条件。白天顺光、白天逆光、清晨黄昏的弱光、夜间灯光,这四种情况都有样本。说实话,夜间船舶检测的难度比白天高一个档次,因为船体和背景水面的对比度很低,而且夜间亮灯的船和没有灯光的船外观差异巨大。为了保证模型在低光照下不至于完全失效,数据集中专门纳入了大概15%的低光照样本。

第三个维度是天气状况。晴天、多云、阴天、薄雾,甚至雨天的镜头都有涵盖。这里要特别说一下雾天样本的重要性。海上作业最常遇到的恶劣条件之一就是雾,空气中的水汽会显著降低画面清晰度,让船舶边缘模糊。如果训练数据里完全没有这种模糊样本,模型在真实雾天场景下的漏检率会高得吓人。

第四个维度是距离与尺度。我在标注的时候就刻意保留了不同距离下的船舶样本——既有占据画面四分之三的超近距离视角,也有缩在画面角落只有几十个像素的远距离目标。后者对模型的小目标检测能力是很好的锻炼。

2.2 数据清洗与质量筛选

数据收集回来不是直接标注的,清洗阶段至少要去掉四类不合格图片。

第一类是严重模糊的图片。这里要注意,不是所有模糊都要删。如果是整张图因为对焦失败或者相机抖动导致模糊,这种必须删,因为YOLO标注框的精度依赖清晰的物体边缘,模糊图的边界框会存在严重偏移。但如果只是在雾天场景下的整体柔和,这种可以保留,它就是真实极端环境的体现。

第二类是严重遮挡的图片。船舶目标被桥墩、岸上建筑大面积遮挡,导致无法判断船体完整轮廓的,直接放弃。我做了一个规定:目标被遮挡超过40%即视为无效样本。

第三类是目标过小的图片。如果一张图中船只在画面的占比小于几个像素,人眼都无法辨认,这种样本即使标了,对训练也基本没有正向帮助,反而会让模型学到一些无意义的纹理噪声。清洗时把这部分剔除掉。

第四类是重复度过高的图片。从视频抽帧得到的图片往往存在大量高度相似的连续帧,如果全部塞进数据集,会让模型过拟合到特定的船只和场景。我做了一个去重操作,确保同一艘船在相同背景下不会出现过多近似样本。

2.3 图片整合与统一格式处理

清洗完毕之后,所有图片统一处理成统一格式。原始图片来源不同,有1920x1080的监控截图,也有4000x3000的高清航拍,还有一些老旧的1280x720素材。我采用了比较简单的策略:统一缩放成分辨率不低于1280x720,这样既保留了足够的检测细节,又控制了训练时显存的消耗。

文件命名也做了统一规范:ship_0001.jpg、ship_0002.jpg这样按序号排。数据集根目录按常规的检测数据集结构组织,毕竟后续都是要喂给YOLO的,遵循标准结构可以最大程度避免后续写脚本适配格式的麻烦。

3. 目标标注规范与细节执行

3.1 类别定义与判定标准

标注是整个数据集质量的核心环节。只有把标注做规范了,训练出来的模型才有实用价值。这套数据集的类别定义经过了仔细权衡,最终确定为四个类别:cargo(货船)、fishing(渔船)、passenger(客船)、other(其他船只)。

为什么不把类别拆得更细呢?比如油轮、集装箱船、拖船单独分类。因为从检测的角度看,货船底部的轮廓和油轮并没有本质区别,过细的分类反而会增加标注难度和标注不一致性,导致模型在类别判断上反复震荡。而other这个类别的存在,则用来兜底所有无法明确归入前三类的船只——比如军用舰艇、工程船、私人游艇等,这个兜底策略在训练时非常实用。

在标注时还定义了一个重要原则:不管目标的类别是什么,边界框必须紧密贴合船体的可见部分。这里有一个细节值得多说一句——如果船体被另一艘船部分遮挡,边界框必须截断在遮挡边界处,而不是把被遮挡的部分也估算进去。

3.2 边界框标注的坐标体系细节

YOLO格式的标注坐标是归一化的,也就是边界框的中心点x、中心点y、宽度w、高度h都是相对于图片宽度和高度的比例值,取值在0到1之间。每一行标注对应一个目标,格式为:class_id x_center y_center width height。

举个例子,一张1280x720的图片中,某个货船的边界框左上角坐标是(320, 180),右下角坐标是(960, 540)。那么计算过程是:

# 边界框原始像素坐标 x1, y1 = 320, 180 x2, y2 = 960, 540 # 归一化计算 img_width, img_height = 1280, 720 x_center = ((x1 + x2) / 2) / img_width # (320+960)/2/1280 = 0.5 y_center = ((y1 + y2) / 2) / img_height # (180+540)/2/720 = 0.5 width = (x2 - x1) / img_width # (960-320)/1280 = 0.5 height = (y2 - y1) / img_height # (540-180)/720 = 0.5

最终写入标注文件的内容就是:0 0.5 0.5 0.5 0.5,代表这是类别0(货船)的目标,中心点在画面中央,宽高各占画面的50%。

这个坐标换算看起来简单,但实际操作中踩过一个坑。有些标注工具导出的坐标是基于左上角的X,Y和宽高W,H,而不是中心点。如果直接硬套YOLO模板,就会导致全部标注整体偏移。我在写转换脚本时单独针对这一点做了处理,后面在常见问题部分会展开说明。

3.3 标注工具与复核机制

标注工具选用的是LabelImg,这是最经典的一款YOLO格式标注工具,界面操作逻辑简单,学习成本低。当然,实际项目中也有朋友推荐用Label Studio或者X-AnyLabeling,后者支持半自动标注,能大幅提升效率。但考虑到LabelImg在社区的使用广泛度更高,出问题的概率更小,最终选定了它。

标注流程分为两轮。第一轮是标注员逐张标注,第二轮是复查员对所有标注框进行交叉复核。这个步骤很重要,因为人工标注总会存在个体差异,有人习惯把边框稍微大一圈,有人习惯紧贴边缘。不统一的话,模型学到的边界框回归目标就会有噪声干扰。我的做法是找了一个对目标检测有基础经验的同事负责复核,逐张检查,凡是框得不准的,直接修改坐标,这个环节花了两天时间,但换来了后续训练时不必反复调试标注问题的省心。

3.4 标注均衡性分析

标注完成后,我做了一次数据分布统计。四个类别的目标数量分布如下:

类别目标数量占比
cargo(货船)285038%
fishing(渔船)232531%
passenger(客船)167522%
other(其他船只)6509%
总计7500100%

这个分布比例是刻意为之的。货船和渔船是监测场景中最常见的作业船只,多配一些样本让模型学得更扎实;其他类别的数量较少,但足以让模型意识到“不是所有水上的东西都长得像货船”。整体分布偏均衡,没有出现某个类别样本量极端不足的情况,这样模型不会在类别维度上产生严重的先验偏差。

这里插一句,为什么我没有做更多张图片。如果继续堆图,可以到5000张甚至10000张,但边际收益未必成比例增长。3000张精心筛选、标注规范的图片,在训练效果上完全有可能超过10000张粗糙图片。数据量不是目标,数据质量带来的模型表现才是目标。

4. 数据集在YOLO模型训练中的应用实践

4.1 数据集划分与目录结构

拿到清洗标注好的数据后,第一件事是划分训练集、验证集和测试集。我写了一个小工具脚本用Python完成随机划分,并且加了种子参数保证每次运行的结果可复现。

划分原则很简单:同一艘船或者同一个连续场景的照片,全部划分到同一个集合里,不能一部分进训练集,一部分进测试集。如果一个场景的图片既用于训练又用于测试,模型相当于已经见过测试题的答案,测试结果会虚高,这个数据泄露问题在目标检测项目里特别容易出现。

划分完成后的目录结构如下:

datasets/ ├── images/ │ ├── train/ # 2400张 │ ├── val/ # 300张 │ └── test/ # 300张 ├── labels/ │ ├── train/ # 2400个txt文件 │ ├── val/ # 300个txt文件 │ └── test/ # 300个txt文件 └── data.yaml # YOLO训练配置文件

data.yaml文件的配置内容如下:

train: datasets/images/train val: datasets/images/val test: datasets/images/test nc: 4 names: ['cargo', 'fishing', 'passenger', 'other']

这个文件在YOLO训练时必须保证路径正确,否则会直接报错找不到图片。我在实际项目里顺便说明一下,不同YOLO版本的data.yaml字段是一样的,这个文件在v5、v8、v11之间可以直接通用。

4.2 数据增强策略与参数配置

数据增强是提升模型泛化能力最强有力的手段之一,尤其对于船舶检测这种场景复杂度高的任务。YOLO内置了丰富的数据增强策略,在训练配置中可以通过参数控制强度。

我使用的YOLOv8训练配置文件部分参数如下:

# 数据集路径 path: datasets/ # 训练超参数 epochs: 300 batch: 16 imgsz: 640 # 数据增强参数 hsv_h: 0.015 # 色调增强 hsv_s: 0.7 # 饱和度增强 hsv_v: 0.4 # 明度增强 degrees: 0.0 # 旋转角度,设为0 translate: 0.1 # 平移增强 scale: 0.5 # 尺度缩放增强 fliplr: 0.5 # 水平翻转 flipud: 0.0 # 垂直翻转,设为0 mosaic: 1.0 # Mosaic增强 mixup: 0.1 # Mixup增强

这里有几个参数的选择理由值得单独说说。

degrees设为0而不是常见的15或30,是因为船舶和水面的关系在物理上是稳定的,船底永远是朝下的。训练时如果引入大幅度的旋转增强,会让模型学到“倒置的船也是合法的船”这种错误概念,反而干扰检测精度。这一点跟车辆检测很不一样,旋转增强在车辆检测中相对有效,但船舶场景不适用。

flipud垂直翻转设为0也是同样的道理。但fliplr水平翻转保留0.5的概率,因为船舶在水平方向上的朝向本来就没有固定规律,从左往右开的船和从右往左开的船都是正常情况。

mosaic增强默认开启,它的原理是把四张图片拼接成一张,相当于在一个样本中同时引入多个场景和目标。这能显著提升模型对多尺度目标的适应能力,特别是在小目标检测方面,效果立竿见影。

Mixup增强我设置得比较保守,只开了0.1。这个参数过大的话,样本之间的混合会让船舶的边缘轮廓变得非常模糊,反而削弱边界框回归的精度。

4.3 训练过程实测记录

训练环境用的是单张RTX 3090显卡,24GB显存,PyTorch 2.0环境,Python 3.10,CUDA 11.8。YOLOv8m模型在imgsz=640输入尺寸下,batch=16可以稳定训练不会显存溢出。

训练指令如下:

yolo detect train \ data=datasets/data.yaml \ model=yolov8m.pt \ epochs=300 \ batch=16 \ imgsz=640 \ patience=50 \ device=0 \ project=ship_detection \ name=exp1

这里设置patience=50的含义是:如果连续50个epoch在验证集上的mAP没有提升,训练就提前终止。这个早停机制能节省大量无效训练时间,实测中模型在训练第160个epoch左右就已经收敛,最终实际跑了220个epoch就触发了早停。

训练过程中的损失曲线非常直观地反映了一个规律——边界框损失在前期下降非常快,前50个epoch就从初始的0.1级别降到了0.03左右;而分类损失下降相对平缓,到了后期才逐渐收敛。这也符合船舶检测任务的特点:因为船体轮廓相对清晰,定位容易收敛;而部分小船的外观相似度高,分类难度更大,收敛更慢。

最终模型在测试集上的评估结果为:

指标数值
mAP@0.50.892
mAP@0.5:0.950.634
Precision0.91
Recall0.87
推理速度(RTX 3090)约3.2ms/帧

这个成绩对于一套3000张图片的数据集来说,已经相当理想了。其中mAP@0.5达到接近0.9的水平,说明模型在绝大多数场景下都能正确框出船只位置。

4.4 模型推理效果与可视化验证

训练完成后,我挑选了一批测试集图片做推理可视化,直接观察检测效果。顺光条件下的近景船舶检测非常稳定,边界框基本紧贴船体,类别置信度普遍在0.9以上。远距离的小目标船舶,置信度略有下降,在0.65到0.85之间,但依然能被正确检出。

逆光条件下,低对比度确实会让模型出现个别漏检,但因为训练数据中包含了逆光样本,整体漏检率控制在可接受范围内。夜间场景的表现是相对最弱的,仅有灯光特征明显的船舶能被稳定检出,完全无光的小船则基本检测不到。这个局限性在预期之内——训练数据集中夜间样本占比本身就只有10%左右。

我还拿着模型在几段真实监控视频上做了一下模拟测试,包含一段港口作业视频和一段航道通行视频。在线推理时画面帧率能稳定保持在25FPS以上,满足常规的实时监测需求。如果换到Jetson Orin这样的边缘设备上,推理速度会有所下降,但配合TensorRT加速和半精度推理,也依然能跑出实时的表现。Web端实时推流的时候,我会优先选择YOLOv8s或YOLOv8n做权衡。

5. 训练过程中的常见问题与排查实录

5.1 标注坐标偏移:LabelImg导出格式的坑

刚开始训练时,我发现模型的定位精度总是差一口气,边界框整体向右下角偏移了几个像素。排查了半天,问题定位在标注文件上。

LabelImg在保存YOLO格式时,界面上显示的是左上角坐标加宽高的形式,但底层的XML文件存储的也是这个结构。在写转换脚本的时候,如果直接照搬了目标检测开源项目中的某个坐标转换代码,而没有仔细验证数学关系,就很容易出错。

正确的计算方式我在前面已经给过了,这里再补充一个验证方法:随便挑一张训练图,用脚本把标注框画出来,和原图做并排对比,确认框的位置和船体实际位置完全吻合。这一步的视觉效果验证能最快发现问题,比直接看数字靠谱多了。

5.2 小目标船舶检测效果差:Mosaic增强的取舍

训练初期,小目标的召回率非常低。我一开始以为是模型问题,后来想了想,还是数据增强配置的问题。Mosaic增强虽然强大,但四张图拼接之后,图片尺寸缩小了一半,如果小目标已经很小了,拼接完之后就只剩下几个像素,标注框的信息基本被抹掉了。

解决办法是在训练后期关闭Mosaic增强。YOLOv8的配置中有一个close_mosaic参数,可以在最后若干个epoch自动关闭Mosaic。实测下来,在最后30个epoch关闭Mosaic,小目标的召回率有了明显提升。如果你的模型训练中没有这个参数,也可以在训练计划里按epoch阶段手动切换配置文件。

5.3 过拟合特征:类别区分不稳定的根源

有一次在验证集上发现,模型把几个明显是渔船的样本误判成了其他船只。排查下来,发现这些图片的背景都有类似的渔网堆叠特征。模型很可能是在用背景信息做类别判断,而不是真正学习船体特征,这就是过拟合到场景特征的典型表现。

解决思路有两个方向。一是在数据集中增加同类别不同背景的样本量,让模型忽略背景关联;二是在数据增强时增加HSV色彩增强的强度,破坏背景纹理的一致性。这个项目最终两个方法都用了,后续误判数量有了明显回落。

5.4 显存不足:批量大小与图像尺寸的权衡

在部分性能较低的显卡上训练时,batch=16和imgsz=640的组合会导致显存溢出。这种情况优先考虑降低batch而不是降低图像尺寸,因为图像尺寸直接影响检测精度。

如果batch降到8还是有溢出,那就考虑用YOLOv8s(小版本)替代YOLOv8m。曾经在一张8GB显存的显卡上,用YOLOv8s、batch=8、imgsz=544顺利完成了训练,虽然精度比m版本低一些,但整体差距很小,依旧在可接受范围内。

5.5 标注遗漏:空心框的误导

复查标注时发现,有些图里的船舶目标非常小,标注员直接漏掉了。这些漏标的目标在训练时会被当作背景处理,相当于给模型提供了“这部分不是船”的错误信息。如果漏标数量多,模型很容易在类似位置产生误检。

复检时我要求复查员特别关注画面边缘和远距离区域,一个目标都不能漏。同时我还写了一个统计脚本,计算每张图片的标注框面积占整张图面积的比例分布。如果发现一批图的平均目标面积异常偏小或分布过于集中,就会重点检查这些图是否出现了系统性漏标。

6. 工具链选型与实践建议

6.1 部署环境配置与运行流程

如果你是在PyCharm这类IDE里从零开始搭建环境,建议用Anaconda创建独立环境,避免污染系统Python环境。新建环境命令:

conda create -n yolo_env python=3.10 conda activate yolo_env pip install ultralytics torch torchvision

PyTorch建议根据本机CUDA版本选择合适的安装命令,具体可以在PyTorch官网查询。在Windows系统上安装时,如果遇到Microsoft Visual C++ Redistributable缺失的报错,去微软官网下载对应的运行库安装即可。

6.2 PyCharm环境配置要点

在PyCharm中新建项目后,把解释器指向conda的yolo_env环境。这里有一个很多新手容易忽略的配置,就是在Settings中找到Python Interpreter,选择Conda Environment并指向刚才创建的env路径。配置完成后,在包管理器中检查ultralytics是否已经正确安装并可导入。

6.3 商业工程落地建议

这个数据集的用途定位是海事监测系统的前端检测模块。商业场景落地时有一些额外建议:一是导出模型时先转换为ONNX格式,再根据部署硬件转为TensorRT引擎,能获得比原始PyTorch模型更优的推理性能;二是在实际部署中建议对检测结果做时间维度上的平滑处理,避免单帧抖动造成的误检漏检;三是有条件的团队可以在检测模块之后接一个多模态分析单元,对船舶的外观特征和运动轨迹做进一步的研判。

我自己实际部署的经验是,先用yolo export model=best.pt format=onnx导出ONNX,再用trtexec工具转换为TensorRT引擎,部署后推理耗时能从原始的6ms左右直接压到3ms以内。这一套链路已经成为我这边项目的标准流程。

7. 数据集的局限性与后续扩展思路

7.1 当前数据集覆盖不到的难点场景

虽然这套数据集的场景覆盖已经做了很多努力,但依然存在几个明显的盲区。首先是无人机视角的数据相对偏少。岸基监控大多是平视或者俯视角度,但无人机航拍是接近垂直的鸟瞰视角,船体呈现的形态完全不同。如果未来要部署无人机海事巡逻方案,需要补充大量鸟瞰视角数据。

其次是极端天气的数据有限。暴雨、台风、浓雾这类极端条件下的数据极难采集,只能通过后续在实际项目中慢慢积累,或者用图像生成的方式做仿真扩充。

7.2 小目标检测的进一步提升方向

当前模型对远距离小目标的检测能力还有提升空间。后续可以考虑将训练时的图像输入尺寸从640提升到960甚至1280,同时配合SAHI切片推理技术,对大图做切片后分别检测再合并结果。这套方法在遥感检测领域得到了广泛验证,实测可以对小目标召回率带来一个显著的提升。

不过要提前说明,输入尺寸增大后训练显存和推理延迟都会同步增长,具体要不要做这个优化,取决于业务场景对实时性的要求。

7.3 从检测到细分类的扩展路径

如果未来的业务需求升级成了船舶细分类,比如要求区分集装箱船和散货船,那么建议路径是:保留当前的四类检测模型作为前置模块,先框出目标位置,再增加一个细分类网络对每个框做二次判断。这样做的好处是检测模块和分类模块可以分别训练、分别迭代,某个类别数据不够时不会拖累整个模型的稳定性。

8. 写在最后的实操心得

做完这3000张YOLO船舶检测数据集的项目,一个很深的体会是,数据集的制作难度从来都不在拍摄和标注本身,而是在每一个容易忽略的决策细节上。

类别定几个、边界框的标准怎么定、训练增强参数怎么调、有没有做数据泄露检测,每一个决策都会实打实地影响最终模型的落地效果。数据集的价值不在于“我有3000张图”,而在于“我的3000张图能训练出一个在真实水域稳定工作的模型”。这套数据集最终的mAP@0.5达到0.89,说明哪怕数据量不大,只要质量控制和分布设计到位,训练效果完全可以达到实用水平。

还有一个小技巧值得分享:训练完成后,把模型在完全没见过的监控视频上跑一遍,用慢速播放的方式人工观察检测结果。很多在测试集上不容易暴露的问题,比如同一条船反复跳变检测框、夜间灯光闪烁导致的间歇性漏检,这样看一遍视频都会一目了然。这种方法不花一分钱,但能帮你发现大量容易被指标掩盖的问题。

如果你正在准备海事监测、水上交通管理或者港口智能监控相关的项目,一套规范标注的船舶检测数据集确实能节省大量的前期准备时间。希望这篇复盘能对你的项目实施有所参考。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进