简介这份资源面向目标检测方向的研究人员、算法工程师及计算机视觉学习者提供一套可直接落地的YOLOv7船舶检测完整方案帮助解决舰船识别场景中数据准备、模型训练与效果评估的全流程问题。压缩包共2377个文件约247.63MB以772张jpg图像、742个xml标注、741个txt标签为主体另含31个py脚本、36个yaml配置、14个ipynb笔记本及2个pt权重文件覆盖数据、代码与训练产物。数据集同时提供VOC与YOLO两种标签格式便于按需选用训练曲线与TensorBoard事件文件可用于观察损失和mAP收敛情况辅助调参优化。资源还包含训练脚本与预训练权重支持从零训练或微调迁移。目前已有1057人学习下载适合希望快速搭建船舶检测系统或深入研究YOLOv7架构的读者参考实践。1. 船舶检测为什么值得单独拆一个 YOLOv7 工程做内河航道监控或者港口卡口项目的朋友大概率遇到过这个场景水面反光、船体遮挡、远近尺度差异巨大拿 COCO 预训练的通用检测器直接跑小渔船漏检、客滚船和货船混为一类mAP 掉得没法看。YOLOv7 船舶检测这套代码加数据集解决的正是这个垂直场景——它不是通用检测 demo而是把舰船这一类目标从数据标注、anchor 匹配到训练推理整条链路都调过的工程包。适合两类人一是手里有航道/港口视频流、想快速搭一个可用检测基线的一线开发二是想拿一个真实垂直数据集练 YOLOv7 微调流程的算法同学。整套东西的核心价值在于省掉你自己标几千张船图、调 anchor 的时间直接进训练和部署环节。2. 拆开这个工程目录结构、数据格式与选型理由2.1 拿到包先看什么目录与文件职责一个能直接跑的 YOLOv7 船舶检测工程目录结构基本是固定的先认清每个目录干什么后面改配置才不会迷路。常见做法是长这样yolov7-ship/ ├── cfg/ │ └── training/ │ └── yolov7-ship.yaml # 模型结构配置改类别数在这里 ├── data/ │ └── ship.yaml # 数据集路径与类别名配置 ├── datasets/ │ └── ship/ │ ├── images/ │ │ ├── train/ # 训练集图片 │ │ └── val/ # 验证集图片 │ └── labels/ │ ├── train/ # 对应 txt 标注 │ └── val/ ├── models/ # 网络结构定义 ├── utils/ # 数据加载、指标、绘图工具 ├── weights/ │ └── yolov7.pt # 预训练权重 ├── train.py # 训练入口 ├── detect.py # 推理入口 └── requirements.txtcfg/training/yolov7-ship.yaml决定网络结构船舶检测如果只有一类nc要改成 1同时 anchors 那几行要按你数据集的真实框分布重新聚类别直接沿用 COCO 的 anchor。data/ship.yaml是数据入口里面写 train/val 的路径和names类别名。weights/yolov7.pt是 COCO 预训练权重用来做迁移学习起点没有它从零训收敛会慢很多。很多人第一次跑报No labels found八成是data/ship.yaml里的路径写成了相对路径但工作目录不对这个后面避坑章节细说。2.2 标注格式YOLO txt 的五个字段到底怎么填这套工程用的是标准 YOLO 标注格式每张图对应一个同名 txt每行一个目标五个字段class_id x_center y_center width height全部是归一化到 0~1 的值不是像素坐标。举个例子一张 1920×1080 的图里有个船左上角 (400, 300)右下角 (800, 600)那么0 0.3125 0.4167 0.2083 0.2778计算方式是中心 x (400800)/2/1920 0.3125中心 y (300600)/2/1080 0.4167宽 (800-400)/1920 0.2083高 (600-300)/1080 0.2778。这里最容易翻车的是把像素坐标直接写进去训练时 loss 会直接爆炸或者一直不降。如果你手上是 VOC 的 xml 或者 COCO 的 json得先转转换脚本网上很多但要注意类别 id 从 0 开始还是从 1 开始YOLO 要求从 0 开始。2.3 为什么选 YOLOv7 而不是 v5/v8 做船舶检测选型理由得说清楚不然你换模型时心里没底。YOLOv7 在 5FPS 到 160FPS 这个区间里精度和速度的平衡点做得比较靠前尤其是它引入的 E-ELAN 结构和 aux head 辅助训练对小目标和遮挡目标更友好——船舶检测里远处的小渔船、被浪花遮一半的船体正好吃这个红利。相比 YOLOv5v7 的 anchor 机制和正负样本分配策略更细密集停靠的码头场景误检会少一些。相比 YOLOv8v7 的工程包生态更成熟很多现成的船舶数据集和部署脚本都是按 v7 的目录约定写的拿来即用。当然边界也要说如果你追求极致轻量化上边缘设备v7-tiny 可以但精度会掉如果数据集特别小几百张v7 的参数量反而容易过拟合这时候要么加数据增强要么退回 v5s。3. 从零跑通训练环境、配置与启动命令3.1 环境搭建与依赖安装先确认 CUDA 和 PyTorch 版本对得上这是后面所有步骤的前提。常见做法是建一个独立 conda 环境避免和系统里的包打架conda create -n yolov7-ship python3.8 -y conda activate yolov7-ship # 按你的 CUDA 版本装 PyTorch下面以 CUDA 11.3 为例 pip install torch1.12.1cu113 torchvision0.13.1cu113 \ --extra-index-url https://download.pytorch.org/whl/cu113 # 装工程依赖 pip install -r requirements.txtpython3.8是 YOLOv7 官方验证过的版本别上 3.11有些依赖轮子还没跟上。PyTorch 版本要和 CUDA 对齐torch.cuda.is_available()返回 False 的话先查驱动版本别急着怀疑代码。requirements.txt里通常有 opencv、numpy、tqdm、pyyaml 这些装完可以python -c import cv2, torch; print(torch.cuda.is_available())验一下。3.2 改两个 yaml类别数与数据路径训练前必须改的两个文件改错一个就跑不起来。先改data/ship.yamltrain: ../datasets/ship/images/train val: ../datasets/ship/images/val nc: 1 names: [ship]train和val写图片目录不用写 txt 路径代码会自动去找同名 label。nc是类别数船舶检测如果只分「船」一类就写 1如果还要分货船/客船/渔船就改成对应数字names列表顺序要和标注里的 class_id 对上。再改cfg/training/yolov7-ship.yaml把nc也改成 1anchors 部分如果不想自己聚类可以先沿用默认值跑一版看效果但通常建议用utils/autoanchor.py重新算一遍命令后面讲。3.3 启动训练与关键参数含义启动命令本身不复杂关键是每个参数你得知道改了会怎样python train.py \ --weights weights/yolov7.pt \ --cfg cfg/training/yolov7-ship.yaml \ --data data/ship.yaml \ --hyp data/hyp.scratch.p5.yaml \ --epochs 100 \ --batch-size 16 \ --img-size 640 640 \ --device 0 \ --workers 8 \ --name ship_exp--weights指向预训练权重迁移学习起点别省。--batch-size看显存16 是 8G 显存比较稳的值爆显存就降到 8 或 4。--img-size船舶检测里很关键如果你的图里船都很小640 可能不够可以上到 1280但显存和速度代价要自己权衡。--hyp是超参文件hyp.scratch.p5.yaml是给 P5 结构用的别拿错成 p6。--device 0指定第一块 GPU多卡用0,1。--name是这次实验的输出目录名结果会存到runs/train/ship_exp/下面里面有权重、loss 曲线、混淆矩阵。训练过程中重点盯三个东西box_loss和obj_loss是否稳定下降mAP0.5是否在涨以及runs/train/ship_exp/weights/下有没有生成best.pt和last.pt。如果 loss 前几个 epoch 就 NaN回去查标注格式如果 mAP 一直卡在 0.1 以下大概率是 anchor 和你的数据分布差太远。4. 推理、评估与部署把模型用起来4.1 用 detect.py 跑单图和视频训练完拿到best.pt先用推理脚本验证效果别急着上生产python detect.py \ --weights runs/train/ship_exp/weights/best.pt \ --source datasets/ship/images/val \ --img-size 640 \ --conf-thres 0.25 \ --iou-thres 0.45 \ --device 0 \ --save-txt \ --project runs/detect \ --name ship_val--source可以是单张图、一个目录、一段视频甚至摄像头编号0。--conf-thres是置信度阈值船舶检测里如果漏检多就降到 0.2误检多就升到 0.4这个值没有标准答案得看你的场景。--iou-thres控制 NMS 的合并力度密集停靠的码头场景可以适当调低到 0.4避免把相邻两条船合并成一个框。--save-txt会把检测结果按 YOLO 格式存下来方便你后续做二次分析。结果图默认在runs/detect/ship_val/里。4.2 评估指标怎么看mAP、Precision、Recall 的实际含义跑完test.py会输出一张指标表别只看 mAP 一个数指标含义船舶场景关注点mAP0.5IoU 阈值 0.5 时的平均精度整体检测能力基线参考mAP0.5:0.95多 IoU 阈值平均框的定位精度靠港精确计数时重要Precision检出的里有多少是对的误报多不多影响告警可信度Recall真实目标里检出了多少漏检多不多影响安全监控船舶检测里 Recall 往往比 Precision 更关键漏掉一条船可能意味着安全事故误报顶多多看几眼。所以调阈值时宁可放宽一点。如果 Recall 明显偏低先看是不是小目标太多考虑提高--img-size或者用切片推理。4.3 导出 ONNX 与部署侧注意点要上生产基本都得转 ONNX 或者 TensorRTpython export.py \ --weights runs/train/ship_exp/weights/best.pt \ --img-size 640 640 \ --batch-size 1 \ --device 0 \ --include onnx--batch-size 1是给推理用的如果服务端要批处理可以设大。--include支持 onnx、torchscript、engine 等转 engine 需要本机装 TensorRT。导出后务必用onnxruntime跑一遍对比输出确认和 PyTorch 结果一致常见坑是动态轴没设对导致 batch 维度写死。部署侧还要注意预处理必须和训练时一致letterbox 的填充颜色、归一化方式差一点精度就掉。5. 避坑与排查船舶检测里最容易翻车的五件事5.1 训练报 No labels found现象启动训练直接报No labels found in ...或者AssertionError: train: No labels。原因data/ship.yaml里的路径是相对路径而 train.py 的工作目录和你以为的不一样或者 label 目录名不叫labels。解决把train/val写成绝对路径先跑通确认图片和 txt 同名同目录结构label 目录必须和 images 平级且名字固定。5.2 loss 不降或直接 NaN现象前几个 epoch box_loss 就是 nan或者一直卡在很高不降。原因九成是标注格式错了把像素坐标当归一化坐标写进去了或者 class_id 超了nc范围。解决写个脚本扫一遍所有 txt检查每个值是否在 0~1 之间class_id 是否小于 nc。这个检查我每次换数据集都强制跑一遍能省掉大半天排查。5.3 小目标漏检严重现象大船检得到远处小渔船基本漏。原因--img-size太小下采样后小目标特征丢了或者 anchor 尺寸和真实框分布不匹配。解决先把 img-size 提到 1280 试如果显存扛不住就用切片推理SAHI 那套思路同时用python utils/autoanchor.py重新聚类 anchor让 anchor 覆盖你数据集里小框的尺度。5.4 水面反光导致误检现象平静水面反光被检成船或者船头浪花被框进去。原因训练集里这类负样本太少模型没学会区分。解决往训练集里补一批纯水面、反光、浪花的负样本图对应空 txt再训一轮。数据增强里可以开一点 HSV 扰动和随机裁剪提升对光照变化的鲁棒性。5.5 转 ONNX 后精度对不上现象PyTorch 推理正常ONNX 输出框偏移或者置信度整体偏低。原因预处理不一致最常见是 letterbox 的缩放比例和填充值不同或者 NMS 在导出时被固化。解决把预处理代码单独抽出来PyTorch 和 ONNX 两条路用同一份导出时确认--grid参数和训练配置一致NMS 建议放在后处理里做别固化进模型。6. 进阶技巧用 autoanchor 和切片推理把船舶检测精度再抬一档前面跑通的是基线真到项目里想再提几个点有两个技巧我每次都会用。第一个是重新聚类 anchor。YOLOv7 默认 anchor 是 COCO 分布船舶的宽高比和 COCO 里的车、人差很远直接沿用等于让模型用错误的先验去匹配。跑之前先把data/ship.yaml配好然后python utils/autoanchor.py \ --cfg cfg/training/yolov7-ship.yaml \ --data data/ship.yaml \ --img-size 640它会输出一组新的 anchor 建议值你手动替换到cfg/training/yolov7-ship.yaml的 anchors 字段里。注意聚类用的 img-size 要和你训练时一致否则算出来的尺度对不上。我一般会对比聚类前后的mAP0.5船舶数据集上通常能涨 1~3 个点小目标多的场景提升更明显。第二个是切片推理专门治小目标漏检。思路是把大图切成有重叠的小块分别推理再把结果拼回去。核心代码逻辑大概是这样import cv2 import numpy as np def sliced_inference(model, img, slice_size640, overlap0.2): h, w img.shape[:2] stride int(slice_size * (1 - overlap)) detections [] for y in range(0, h, stride): for x in range(0, w, stride): patch img[y:yslice_size, x:xslice_size] # 边缘不足 slice_size 的补零记录偏移量 offset (x, y) results model(patch) # 把 patch 坐标加回原图坐标 for det in results: det[bbox][0] offset[0] det[bbox][1] offset[1] detections.append(det) # 跨 patch 的重复框用 NMS 合并 return nms(detections)slice_size一般设成和训练 img-size 一样overlap取 0.2 左右太小会切断裂目标太大推理变慢。这个方法的代价是推理时间成倍增加所以只在你确认小目标漏检是主要瓶颈时才上。拼回去之后的 NMS 阈值要比单图推理时略高一点因为重叠区域会产生大量重复框。还有个习惯每次改完 anchor 或者换推理策略我都会固定拿同一批验证图跑一遍把结果图存下来肉眼对比别只看 mAP 数字。数字涨了但实际场景里框歪了的情况血泪经验告诉我真不少见。从那以后我每次调完参数都强制走一遍可视化对比确认框的位置和置信度都合理才收工。希望帮到你。本文还有配套的精品资源点击获取
