ARTICLE DETAIL

资讯详情

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

YOLOv8海上目标识别实战:从数据集构建到部署

YOLOv8海上目标识别实战:从数据集构建到部署 简介在计算机视觉领域目标检测技术正不断向复杂场景延伸其中海洋环境因其光照多变、目标尺度小、背景干扰强对检测模型的精度与速度提出了更高要求。小目标检测作为长期存在的技术挑战在船只、落水人员和航道标志物识别中尤为突出。YOLOv8作为单阶段检测器的代表通过C2f模块、解耦头与TaskAlignedAssigner等机制在推理速度与定位精度之间取得良好平衡成为海上监控、智慧港口、无人机巡检等工程任务的热门选择。一套高质量的训练数据集和合理的迁移学习策略是模型能否在实际场景中稳定运行的关键。从数据清洗、标注规范、增强策略到TensorRT部署完整工程链路都能有效降低误检与漏检风险。本文围绕海上目标识别项目展示基于YOLOv8的实践方法为相关视觉应用提供可复用的技术参考。 海上目标识别这件事这些年我陆陆续续经手过不少项目从智慧港口到海上风电巡检再到海事应急救援的预警系统核心任务基本都绕不开船、人和海上标志物这三类目标。无论是做航道安全管理还是落水人员搜救或者是港口船舶调度都需要一套能实时跑起来、识别足够准的目标检测模型。这次我把一个完整的项目整理一下用YOLOv8做船只、行人、海上标志物的识别配套一套1万张规模的数据集和最终训练好的权重整个过程从数据构建、标注、训练到部署我尽量把关键细节都写出来。这套方案解决的核心问题是海上场景目标检测为什么难做如何用一套公开可复现的方法拿到能直接上线的权重。适合正在做海事相关视觉项目的工程师、做遥感或无人机巡检的算法同学以及准备用YOLOv8训练自定义数据集的入门者参考。内容会比较长但每一步都会讲清楚为什么这么干而不是只给一段配置完事。1. 项目背景海上目标识别到底难在哪1.1 三类目标各自的识别难点先说船只。船的类型多样从货轮、渔船、快艇到橡皮艇尺寸差异极大。大船几十米甚至上百米小船可能只有几米。YOLOv8这类基于锚框的目标检测算法天然对大目标友好但小目标的特征在大分辨率的特征图上已经被压缩了好几轮远端小渔船往往会丢特征这就导致漏检。另一方面船与船之间还有遮挡港口里停靠密集时一艘船的边界框会直接压到另一艘上也容易误检成一个目标。行人在海上场景里难度更高。和地面道路不同海上行人通常出现在救生艇、甲板、岸边、落水人员等场景中身体姿态多变很多只能看到半身或者头盔光照不好的时候甚至只有一个小亮点。摄像头离目标远像素占比低这在检测中属于标准的小目标难题。再加上水面反光会干扰背景建模行人和船身的颜色还可能接近这些都是单靠主干网络难以搞定的。海上标志物的定义要明确一下我这里指的是航道浮标、警示灯桩、系泊点标识、渔网浮球等多类静态或半静态目标。这类目标的特点是形状小、颜色偏橙色或红色、常年和海水背景混在一起远看就是一个色块。加上水面太阳反光和波浪的干扰很容易被漏检或误分类。但它在事故预警里反而很关键因为标志物识别错误会直接导致船只碰撞或偏离航道。1.2 为什么是YOLOv8选YOLOv8之前我也对比过Faster R-CNN、SSD甚至一些Transformer结构的检测器。Faster R-CNN精度够但两阶段结构在推理速度上有天然瓶颈部署到边缘设备后帧率上不去不适合港口实时监控这类场景。SSD速度还行但小目标检测能力偏差海上目标恰恰以小目标居多。YOLOv8作为单阶段检测器速度和精度的平衡比较理想官方提供的基础权重预训练效果扎实而且Ultralytics仓库维护很活跃训练、验证、导出部署一条链路完整省去很多工程胶水工作。YOLOv8相对之前的YOLOv5改动主要体现在三个地方C2f模块替换了原来的C3模块增强了梯度流检测头从耦合头换成了解耦头分类和回归分支分开标签分配策略改成TaskAlignedAssigner。这些改进直接带来的收益是收敛更快、相同训练轮数下精度略高尤其是对小目标的定位更稳。对海上场景这种小目标占主体的任务选YOLOv8是合理的。1.3 整体技术路线选型整套方案的路线可以拆成四条线数据线、训练线、评估线和部署线。数据线负责完成1万张图像的采集、清洗、标注和增强目标是让数据集覆盖不同天气、不同距离、不同光照条件。训练线负责在统一的数据集划分下跑YOLOv8训练并迭代超参数。评估线通过mAP、混淆矩阵、PR曲线判断模型短板。部署线最终把权重导出成ONNX和TensorRT格式落到嵌入式或服务器环境去跑。四条线里面数据线是最耗时间的大概占了整个项目六成以上的工作量。很多教程会把数据集作为一种附属品一笔带过但真实项目里数据质量几乎决定了最终模型的上限。同样的YOLOv8权重在清晰规范的数据上能跑出很高的mAP在脏乱的数据上就各种漏检。所以我先把数据集这部分单独拎出来讲透。2. 1万数据集的构建与标注思路2.1 数据来源与类别分布设计1万张这个数字不是拍脑袋定的在海上目标识别这类任务里太少了覆盖不了场景多样性太多了收集和标注成本又控制不住。经过前期测试目标规模控制在1万张左右配合数据增强基本能撑起一个可落地的检测模型。数据来源主要有三块一是现有的公开海上目标数据集比如SeaShip、SeaDronesSee这类用于学术研究的数据集可以提取一部分合规使用的数据二是项目中实际采集的港口摄像头、船载摄像头画面三是无人机俯拍视角的少量影像用来补充俯视角度下目标外观变化的数据。类别分布上要特别小心。如果全部数据均匀分成三类每类3333张看起来合理但实际效果会差很多。因为船只的出现频率在真实场景里远高于落水行人和标志物。我建议按照目标本身在场景中出现频次来调整比例船只占最大头约5000张左右行人含船上人员、岸边行人、落水人员约3000张海上标志物约2000张。合计正好1万张。这样模型能学到更真实的先验分布而不是人为制造出来的均匀分布。每一张图里的目标数量也需要注意。如果绝大部分图都只有一个目标模型对密集场景的泛化就弱。我要求标注团队在保留原始场景的前提下尽量包含一些多目标交织的图片比如一条集装箱船旁边跟着一艘拖轮、旁边还有半个浮标。一张图5到10个目标的状态是最常见的这对训练友好。2.2 标注规范与工具实操标注规范先定死否则后面返工成本极高。我建议遵循这几条目标只有可见部分超过整框面积50%以上才标注被严重遮挡的可以不标类别无法明确判断时宁可不标也不要乱标边界框要贴合目标轮廓特别是船只这种细长目标框太松会导致定位误差被放大。标注工具我用的是CVAT和LabelImg。CVAT适合团队协作能直接导出YOLO格式的txt文件每个txt文件名与图片名一一对应里面每行是一个目标类id、中心点x、中心点y、宽、高全部归一化到0到1之间。LabelImg更适合单人小批量操作。无论用哪个标注完成后都要做一轮交叉复核我会随机抽20%的图片让第二个人重新标注一遍计算标注一致性。如果一致性低于90%说明标准执行有问题需要返工。每张图片标注完成后都要自动检查一遍坐标是否越界、某类目标数量是否异常、图片是否存在全黑全白的无效样本。这些检查可以写一个几十行的Python脚本完成千万别手查1万张图手查会看吐。2.3 海上场景的数据增强策略海上场景第一个典型问题是雾天和低照度。正常数据分布里晴天、光照好的图片占比高但我建议在训练时加入随机亮度对比度调整、加入高斯噪声模拟雾气导致的目标对比度下降。这些可以通过Ultralytics自带的数据增强参数打开比如hsv_h、hsv_s、hsv_v调节色域degrees做随机旋转。第二个典型问题是小目标太少。单纯增加图像尺寸对显存不友好更有效的做法是用马赛克增强mosaic把4张图拼接成一张训练相当于强制模型在小区域内同时学习4种场景的目标。Ultralytics默认开启mosaic但要留意mosaic在训练后期应该关闭或降低概率否则会让模型对真实分布的适应变慢。第三个典型问题是拍摄视角单一。摄像头固定高度拍出来的图片和无人机俯拍、船载相机低角度拍摄的视角差异巨大。我在数据里保留了部分俯拍和贴水面的图片并配合随机水平翻转、小角度旋转尽量让模型学到目标的视角不变性。3. 训练环境搭建与资源优化3.1 GTX1660Ti的实际训练配置我注意到不少人在问GTX1660Ti能不能跑YOLOv8答案是能但需要做一些取舍。GTX1660Ti的显存是6GB跑YOLOv8s在640分辨率下batch size开到16是没有问题的但如果用YOLOv8m或者更大模型显存会直接溢出。我实际跑下来比较稳的组合是YOLOv8s 输入尺寸640 batch size 16 AMP自动混合精度开启。这个组合在6GB显存下显存占用大约5.2GB训练速度约每秒3到4张图1万张数据训练150轮大概需要十几个小时可以接受。如果非要用更大的模型也有两个办法一是把输入尺寸降到480二是开启梯度累积让batch size维持16但实际每次回传梯度前累积2步等效batch size 32。不过这两种方式都会增加训练时间而且对小目标检测可能有副作用我建议优先从YOLOv8s起步。因为CPU内存不足导致的训练卡顿也要提前防范。Windows环境下特别容易踩内存泄漏或者页面文件不够的坑数据集图片比较多时dataloader预读取会大量占用内存建议内存小于16GB的机器把workers从默认8调低到4。3.2 环境安装与版本选择Ultralytics的YOLOv8安装其实已经非常简化了。我推荐用Python 3.9或3.10PyTorch根据CUDA版本选择合适的wheel稳定方案是先装PyTorch再装Ultralytics。PyTorch 2.x对YOLOv8的编译优化有好处实测比1.x浮点精度一致的情况下速度提升明显建议优先安装PyTorch 2.1以上版本。整个依赖环境可以用conda装也可以直接用pip装到虚拟环境里。装哪个版本都有讲究我建议不要用最新版的Ultralytics而不看版本有些新版本会改动API导致老代码失灵。如果是照着这篇博文做建议锁定一个稍微保守的版本训练命令、参数以官方文档为基准即可。安装完成后先做一个最小验证用官方预训练权重跑一次推理确认模型能加载、GPU能正常参与计算。很多环境问题会在这一步暴露出来比如CUDA版本和PyTorch不匹配、cuDNN缺失等提前验证可以避免训练到一半才报错。3.3 关键训练参数怎么定训练参数别照抄默认值要结合自己的数据量来调整。首先是epochs。1万张数据、3个类别这个规模150轮比较合理。很多人喜欢直接开300轮但船和标志物的数据分布相对稳定150轮足够收敛继续训练容易过拟合。batch size在前面说了GTX1660Ti上选16。这里补充一个计算原则显存允许的情况下batch尽量大因为大batch带来的梯度估计更稳定损失曲线震荡更小。但batch太大又会导致模型泛化能力下降所以一般16到32是常用区间。imgsz即输入分辨率直接影响小目标检测效果。640是YOLOv8官方默认分辨率也是速度和精度的平衡点。如果发现远处小船漏检严重可以试试960输入但显存占用会变成原来的2.25倍6GB卡带不动YOLOv8s960需要相应调小batch。学习率lr0我习惯从0.01开始。如果训练初期损失不降可以降到0.005。优化器默认SGD够用如果追求更快收敛也可以用AdamW但AdamW在检测任务上的最终精度不一定比SGD强。3.4 训练循环与权重保存流程Ulitralytics训练时会自动保存last.pt和best.pt其中best.pt是根据验证集mAP50-95选出的最优权重这是一个非常实用的机制。训练结束后项目目录下会生成runs/detect/trainN/exp文件夹里面有每轮的损失txt、曲线图、混淆矩阵、PR曲线等结果文件。我的习惯是训练完成后马上做一次完整验证命令用val模式看验证集上的所有类别AP值。如果某个类别的AP明显偏低回过去检查该类别的标注问题而不是急着调模型结构。数据问题没解决之前调模型架构基本是浪费时间。训练中断的情况也遇到过建议每训练完一个epoch及时确认last.pt是否正常生成这样即使突然掉电也能用resume参数从断点继续训练不至于全盘重来。4. 实战训练与调优4.1 数据集与模型配置文件YOLOv8训练需要定义一个数据集配置yaml。我的做法是在项目根目录下建data.yaml内容大概是这样train: /path/to/dataset/train/images val: /path/to/dataset/val/images nc: 3 names: 0: ship 1: person 2: buoy注意train和val的路径建议写绝对路径或者用相对路径时保持工作目录一致。图片文件夹和标注文件夹都放在images目录里标注文件路径会自动匹配同名的txt。如果标注文件是COCO格式或者VOC XML可以在标注工具里先转换成YOLO格式或者用Ultralytics自带的转换脚本。数据集划分上我用train:val 9:1训练9000张、验证1000张。在划分前先按场景分桶确保不同摄像头采集的图片不会全部落到某一个集合里。最怕的是同一个监控点位拍的连续帧既在训练集又在验证集这样验证结果虚高部署后性能直接掉一截。4.2 预训练权重与迁移学习从零训练一个检测网络需要海量数据海上目标只有1万张量级远远不够。但有了COCO预训练权重做迁移学习情况完全不一样。COCO上有80类目标其中包含船boat、人person特征提取器已经学好了通用的纹理、边缘、形状表征我们在它基础上微调相当于站在一个已经见过大量自然图像的模型上去适配特定业务场景。Ultralytics里这种做法非常简单在训练命令中直接用yolov8s.pt作为权重路径即可。它会自动加载COCO预训练权重同时把分类头输出类别数改成你自己的类别数。我当时选的是YOLOv8s因为它在精度和速度之间最均衡。如果追求极致速度部署到边缘端还可以选YOLOv8n如果计算资源充足想要更高精度选YOLOv8m或l。迁移学习阶段的学习率策略也和从零训练不同。加载预训练权重后前5轮可以考虑用一个较低的学习率热身warmup避免因为初始学习率过大把预训练好的特征破坏掉。Ultralytics默认带warmup_epochs配置默认值3到5我一般保持默认。4.3 训练中的曲线怎么看训练过程中真正要盯着看的不是每一轮的loss值而是验证集上的指标。Ultralytics会在训练完成后输出mAP50、mAP50-95、precision、recall几个核心数字。mAP50表示IOU阈值0.5下的平均精度适合快速判断整体识别效果mAP50-95是把IOU阈值从0.5到0.95之间以0.05间隔取平均后计算的更能反映定位精度。我当时的训练结果大致是船类mAP50在95%左右person类mAP50在88%左右buoy类mAP50在90%左右。整体mAP50-95大概在70%到75%之间。如果你的训练结果明显低于这个水平优先怀疑数据标注质量其次才是模型配置。损失曲线方面训练loss会持续下降验证集loss则需要防止它在后期反弹。如果验证loss先降后升说明过拟合了。这时候优先做的是增加数据增强强度、降低学习率或提前停止训练而不是继续堆epoch。4.4 针对典型难点的模型改进基础训练跑完之后如果要求更高精度可以考虑两类改进。第一类是在数据层面做难例挖掘。训练完第一版模型后用它对训练集做一遍预测找出那些预测错误或置信度低的图片人工看一遍把有价值的错误样本挑选出来修改标签或补充标注放进下一轮训练的采样池。这样做比盲目加数据更有效。第二类是在网络层面做小幅改动。YOLOv8自带的一些改进点可以按需开启比如添加注意力机制模块、增大检测头、优化特征融合方式。但每改动一处都需要重新训练验证成本较高。我的建议是先吃透数据再考虑改网络。很多项目所谓模型精度不够深挖下去其实是标注质量和数据分布的问题网络结构本身在YOLOv8这个量级上已经足够强。5. 问题排查与避坑实录5.1 显存不够怎么办GTX1660Ti跑YOLOv8s的过程中如果开了浏览器或者有其他程序占用显存训练时大概率会报CUDA out of memory。先关掉不用的程序然后看batch size有没有开太大。实在不行可以在训练命令中加--amp开启混合精度或者降低图像尺寸。注意不要频繁手动设置gpu内存清理训练过程中反复清内存反而会拖慢速度。还有一种情况是显存够但训练速度极慢。这种往往是CPU内存或者磁盘IO卡住。尤其数据集放到机械硬盘上时加载图片会成为瓶颈。把数据集放到SSD上速度能提升好几倍。训练日志里如果每个batch耗时忽高忽低基本就是IO问题。5.2 损失不收敛和过拟合损失不收敛最常见的原因是标签文件错乱比如类id越界、坐标出现负值、图片和txt对不上。我的排查方法是写脚本统计所有标注文件的行数、坐标范围、类别取值一次定位异常。如果标签没问题再看学习率把lr0调到0.005甚至0.001再试。过拟合的典型表现是训练集损失持续下降验证集mAP停滞甚至下降。解决办法按优先级排序降低训练轮数或提前停止增强数据增强强度增大训练数据量对模型加正则化。不要在验证集上反复调参调多了模型会对验证集产生隐式过拟合最终上线的时候才发现翻车。5.3 小目标漏检与波浪误检的现场处理海上项目里最典型的问题是小目标漏检和波浪误检。小目标漏检最直接的办法是提高输入分辨率分辨率不够时模型压根看不清远端目标。同时可以尝试分块检测把一张大图切块后分别推理再合并结果。波浪误检则相反很多时候是训练集里缺少没有目标的纯海面负样本图片。我在数据集里刻意保留了10%左右的纯背景图不标注任何目标让模型学会在纯净海面下输出空结果误检率降低了一个层级。另一个容易踩的坑是把远处的桥墩、岸边的石头误检成船。这种误检通常来自训练样本里缺少类似外观的负样本。可以在训练集里保留一些包含船只但同时也有岩石、码头堆物、堤坝的图片而不是把所有干扰物都裁剪掉。模型需要见过这些干扰物才知道它们不该被归为船。5.4 标注不平衡与噪声标签的处理类别不平衡最先体现在loss的分布上。YOLOv8默认的分类损失会按类别统计进行一定程度平衡但效果有限。如果buoy类只有船类的一半数据那就需要适当增加buoy类的数据增强倍数或者对该类别的loss乘一个权重系数。尽量避免删除其他类别数据来硬凑均匀这样会牺牲模型在真实场景中的表现。噪声标签也就是标注错误在小数据集上影响很大。我整理了一个快速检查方法训练完后取验证集中预测错误度最高的20张图人工检查是模型错还是标签错。大部分时候是标签画框不准、类别标错。手动修正这几十张图重新训练mAP提升经常比改任何结构都明显。6. 模型部署到真实业务场景6.1 导出ONNX与TensorRT加速训练好的模型不能只在Python里跑着玩实际业务需要服务化部署或边缘推理。第一步就是导出。Ultralytics里一条命令导出成ONNX格式yolo export modelbest.pt formatonnx opset12导出后可以用onnxruntime验证输出是否与PyTorch推理一致。这里有一个经验导出的ONNX通常包含过多的动态shape信息在部署到TensorRT前最好固定输入尺寸比如固定成640x640这样可以避免许多兼容性报错也让TensorRT可以做出更强的图优化。TensorRT加速在NVIDIA设备上效果非常明显。用trtexec工具把ONNX转成engine推理速度能比PyTorch原生模型提升一倍多。在Jetson Orin Nano这类边缘设备上跑YOLOv8sTensorRT优化后帧率能做到30fps左右。这个结果对海上监控来说完全够用。6.2 嵌入式设备部署思路不少读者问训练好的模型怎么部署到嵌入式设备比如Jetson系列、瑞芯微RK3588、海思芯片等。第一步都是先看芯片的算力有没有支持对应的加速推理框架。Jetson用TensorRT瑞芯微用RKNN海思用NNIE或者转自己的OM格式。不要想着拿PyTorch模型直接在板子上跑嵌入式环境要的是经加速框架转换后的engine文件。转换的基本链路都类似PyTorch权重 → ONNX → 目标平台的模型格式 → 板端推理代码。转换过程里最容易踩坑的是某些算子不支持比如部分注意力模块的自定义算子、Transpose类操作在不同策略下有不同表现。所以我在选网络结构时尽量选官方标准YOLOv8而不是已经改动过的变体。改动太深的网络上了板子很可能因为算子兼容问题被卡住一两天。还有一条量化路线FP16量化几乎没有精度损失INT8量化能把推理速度再提一档但需要校准数据集而且精度可能下降。对海上目标检测这种低容错场景我一般先保住FP16INT8只在线处理量大且检测精度足够冗余时使用。6.3 部署后还能扩展什么功能部署完基础的检测模型业务上还会有一些自然延伸。比如对船只做实时计数和轨迹绘制对落水人员进行目标追踪对浮标进行位置异常预警。这些都可以基于检测结果再做一层后处理或单独的小模型。如果要接视频流还要注意推理线程和视频解码线程之间的解耦。我的做法是用队列管理帧数据解码线程负责拉流和解码推理线程从队列里取帧做检测再把检测结果合成到画面上推出去。这样即使推理暂时跟不上视频帧率也不会堵死整个管线。另外检测模型还可以和追踪算法配合比如ByteTrack、StrongSORT对连续帧中的目标分配ID从而判断目标是否停留、是否逆行、是否有落水者长时间未活动。这类功能在海事管理里很有价值。6.4 我最后的几点实战体会整个项目做完我最大的体会是数据集构建永远是最耗时的核心环节模型训练反而是相对流水线化的事情。海上场景复杂多变如果只靠一个数据集想覆盖所有情况几乎不可能所以训练完一定还要持续采集新场景图片定期微调模型。我每隔一段时间就会把新收集的图片加入训练集重新训练一版权重保证模型能跟上实际环境变化。另一条经验是不要贪大。YOLOv8s在很多场景里已经够用追求更大模型对6GB显存的本地实验不友好对边缘部署也是负担。先跑通一个小模型把数据、流程、部署链路全部打通再根据精度瓶颈决定是否升级模型这个节奏在真实项目中更稳。最后多说一句海上监控项目往往缺少负样本数据也就是没有目标的纯海面。这类数据一定要舍得收集对降低误检率的效果远超你到时候调阈值或者换模型。项目就是一个不断和数据共舞的过程把数据伺候好了模型自然就不差。本文还有配套的精品资源点击获取
返回列表