
简介面向遥感图像目标检测与舰船识别任务这份数据集提供2238张卫星遥感舰船影像及对应标注涵盖航空母舰、驱逐舰、潜艇、货船、油轮等17个细分类别并以Pascal VOC和YOLO两种主流格式同步交付可直接用于YOLO系列模型训练也可借助xml文件转换为COCO等格式省去自行标注和格式转换的繁琐环节。压缩包共2000个文件其中包含1999个xml标注文件和1个使用说明txt资源整体约109.32MB适合中高级算法工程师、科研人员及竞赛选手作为目标检测模型训练数据。随包附带“使用前必读”说明方便快速了解目录结构与标注规则。目前已有835人学习下载数据经过整理归类便于直接开展实验对比与模型调优。1. 卫星遥感舰船检测数据集 VOCYOLO 格式2238 张图能训出什么效果做遥感目标检测的人多半遇到过同一个尴尬公开数据集要么是航母级的几万张要么类别单一到只有 ship 一类。卫星遥感舰船检测数据集 VOCYOLO 格式 2238 张 17 类别.7z 这类资源正好卡在中间——2238 张图、17 个舰船相关类别双格式标注解压即用不用自己拿 LabelImg 重新画框。它的价值不在于大而在于已经按 VOC 和 YOLO 两种格式组织好了省掉的是数据准备阶段最琐碎、最容易出错的那一步。这个数据集适合两类人一是刚接触 YOLO 训练、想拿一份干净数据跑通全流程的入门者二是做港口监测、海域态势、船舶识别等实际项目的工程师需要一份带多种船型的样本做预训练或迁移学习。17 个类别意味着不是简单的有船/没船二分类而是驱逐舰、货轮、渔船、油轮等细分识别这比二分类难一截但也更贴近真实业务。YOLO 格式的 txt 标注和 VOC 格式的 xml 标注都存在意味着你既可以直接扔进 YOLOv5/v8 训练也可以转回 mmdetection、Faster R-CNN 这类以 VOC 为输入的主流框架两边都不耽误。后面我会按解压 7z → 核对标注格式 → 配好 YOLO 训练环境 → 调参跑通 → 处理高频踩坑的顺序把这条链路完整走一遍。中间会给出解压命令、格式转换脚本和训练参数都是可以直接复制去用的。2. 先解压 .7z环境安装、解压命令与目录结构核对2.1 Linux 与 Windows 下的 7z 安装方式拿到手是一个 .7z 压缩包第一步不是写训练脚本而是把它安全解压。7z 格式比 zip 压缩率高不少但系统默认不带解压工具Linux 上尤其明显——你敲unzip它不认识因为压根不是 zip。Linux 下Ubuntu/Debian 系装 p7zipsudo apt update sudo apt install -y p7zip-full装完以后验证一下7z i | head -n 20能打印出 7-Zip 版本信息就是成功了。CentOS/RHEL 系把包管理器换成yum install p7zip p7zip-plugins即可。Windows 用户直接装 7-Zip 官方客户端右键菜单里就有解压到当前文件夹。2.2 解压命令、输出路径与完整性检查解压 .7z 有几种方式区别在于是否保留原始压缩包。我一般先建一个独立目录再解避免把文件散到当前目录到处都是mkdir -p ship_dataset cd ship_dataset 7z x ../卫星遥感舰船检测数据集VOCYOLO格式2238张17类别.7z7z x会保留压缩包内的完整目录层次7z e则会把所有文件摊平到同一目录——这里必须用x因为后面要引用 images 和 labels 两套平行目录摊平了路径就全乱了。解压过程中如果报Cannot open file as archive先检查下载是否完整对比压缩包大小是否和源站一致如果报Wrong password那就是包有加密得找发布方要口令无解。解压完成后建议做一次目录核对find . -type f | wc -l du -sh .2238 张图 对应标注文件文件数通常在 4000 以上总大小几百 MB 到 1GB 左右都属于正常范围。如果文件数少了一大截说明压缩包被上传端截断过重新下载更稳妥。2.3 解压后必须核对的四个关键目录解压完别急着开训先把目录结构理清楚。这类数据集普遍按下面的布局组织路径内容说明JPEGImages/2238 张原图卫星/遥感影像的舰船切片Annotations/VOC 格式 xml每张图一个 xml含目标框和类别名labels/YOLO 格式 txt每张图一个 txt内容为 class cx cy w h归一化ImageSets/Main/数据集划分 txttrain.txt、val.txt 等列出不帶后缀的图片名JPEGImages 和 Annotations 是 VOC 的老搭档labels 是 YOLO 的标注目录ImageSets/Main 则是划分训练集和验证集的清单。不要自己凭感觉随机抽样分配直接用 .txt 里的划分——这是数据集的官方答案复现结果时和其他人用同一份划分才有可比性。这里有个容易被忽略的点labels 里的 txt 文件名必须和 JPEGImages 里的 jpg 文件名完全一致不能有前缀或后缀不一致的情况YOLO 训练是按文件名去匹配的对不上直接报Dataset is empty或者训练时找不到标注。3. VOC 与 YOLO 双格式对照XML 转 TXT 脚本与格式边界3.1 VOC 的 XML 里藏着哪些关键字段VOC 格式是很多检测框架的通用语言它的标注是一个 xml 文件和图片同名。打开一个典型的 xml里面真正影响训练的就几块annotation filename000001.jpg/filename size width1024/width height768/height /size object namecargo_ship/name bndbox xmin256/xmin ymin200/ymin xmax512/xmax ymax400/ymax /bndbox /object /annotationfilename在跨平台处理时要注意大小写问题size里的宽高是转 YOLO 格式时做归一化的分母必须和实际图片分辨率一致object可以出现多个每个代表图里的一艘船bndbox是左上角和右下角的像素坐标。框架解析 xml 时读的就是这几项多出来的difficult、truncated这类字段在纯 YOLO 训练里通常会被忽略不用管。3.2 用 Python 把 VOC 转成 YOLO txt 的通用脚本虽然这份数据集双格式都给了但你以后自己标注数据或者拿别人的 VOC 数据集迁移时九成会用到转换逻辑。核心是把像素坐标归一化到 0~1 之间YOLO 格式一行一个目标类别索引、中心点 x、中心点 y、框宽 w、框高 h。import xml.etree.ElementTree as ET import os # 类别列表必须和训练时用的 data.yaml 完全一致 class_names [aircraft_carrier, warship, cargo_ship, liquid_cargo_ship, fishing_boat, passenger_ship, fuel_ship, tug, submarine, coast_guard_ship, law_enforcement_ship, inflatable_boat, wooden_boat, canoe, other_ship, unknown_ship, civilian_ship] xml_dir Annotations txt_dir labels os.makedirs(txt_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) txt_name xml_file.replace(.xml, .txt) with open(os.path.join(txt_dir, txt_name), w) as f: for obj in root.iter(object): cls_name obj.find(name).text.strip() if cls_name not in class_names: continue # 类别不在名单里的直接跳过防止训练报错 cls_idx class_names.index(cls_name) xmin int(obj.find(bndbox/xmin).text) ymin int(obj.find(bndbox/ymin).text) xmax int(obj.find(bndbox/xmax).text) ymax int(obj.find(bndbox/ymax).text) x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h f.write(f{cls_idx} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n)这段脚本有几个细节值得展开。class_names的排列顺序不是随便定的——它决定了 YOLO 格式里第一列数字代表哪个类别训练配置里的names列表必须和这里完全一致错一位全盘皆错。归一化时w和h用的是像素宽高除以图片宽高而不是中心点坐标的差值这是新手最容易算错的地方。脚本里对不在类别白名单内的目标做了跳过处理因为遥感数据里偶尔会有ignored或拼写错误的类别名硬转进去会让类别索引错位。3.3 两种格式的使用边界别混着喂给模型VOC 的 xml 包含图片尺寸像素坐标人类可读、适合标注工具读取但训练时框架要现做归一化YOLO 的 txt 已经归一化训练时直接读字符串、毫秒级加载省掉了前处理。两者信息等价但使用场景不同你在 YOLOv5/v8 里训练就用 txt你把数据喂给 mmdetection 的 VOC 类检测器就用 xml。不要做用 YOLO 训练时还在 xml 里抠坐标这种绕路操作也别把 labels 目录交给 VOC 系框架——它们不认。数据集同时提供两份不是因为冗余而是让你省掉转换这一步直接用你熟悉的那一套。4. 用 YOLO 跑通舰船检测数据配置、训练命令与损失函数4.1 先准备 data.yaml 与数据集划分脚本YOLO 训练的第一步是写数据配置 yaml。它告诉模型三件事训练集和验证集的图片路径、有几个类别、类别名是什么。路径建议写绝对路径省得软链接和相对路径把新手绕晕# ship.yaml path: /home/yourname/ship_dataset train: images/train val: images/val nc: 17 names: [aircraft_carrier, warship, cargo_ship, liquid_cargo_ship, fishing_boat, passenger_ship, fuel_ship, tug, submarine, coast_guard_ship, law_enforcement_ship, inflatable_boat, wooden_boat, canoe, other_ship, unknown_ship, civilian_ship]如果解压出来的目录不是严格的images/train结构而是JPEGImages/和labels/两根平行目录先用一个脚本按 ImageSets/Main 里的 txt 划分。这个划分逻辑以后自己准备数据集时也能复用import os, shutil images_dir JPEGImages labels_dir labels os.makedirs(images/train, exist_okTrue) os.makedirs(images/val, exist_okTrue) os.makedirs(labels/train, exist_okTrue) os.makedirs(labels/val, exist_okTrue) with open(ImageSets/Main/val.txt) as f: val_ids [line.strip() for line in f if line.strip()] for img_name in os.listdir(images_dir): stem os.path.splitext(img_name)[0] src_img os.path.join(images_dir, img_name) src_lbl os.path.join(labels_dir, stem .txt) if not os.path.exists(src_lbl): # 没有标注的图不参与训练直接跳过 continue if stem in val_ids: shutil.copy(src_img, images/val) shutil.copy(src_lbl, labels/val) else: shutil.copy(src_img, images/train) shutil.copy(src_lbl, labels/train)val.txt里放的是不带扩展名的文件主名判断时拿图片名去掉后缀后的 stem 去比。os.path.splitext提取主名是常规操作不要直接拿img_name[:-4]切万一图片是 .png 或 .jpeg 就出错了。没有标注文件的图直接跳过——这种图放进训练集YOLO 会对一个空 txt 做处理轻则 loss 波动重则报错。4.2 训练启动命令与关键参数说明划分好目录后启动训练的命令如下python train.py --data ship.yaml --weights yolov5s.pt \ --img 1024 --batch 16 --epochs 100 --project ship_experiment \ --name baseline_ship --exist-ok这段命令对应 YOLOv5 的入口v8 的话把train.py换成yolo train参数名的语义一致比如--img对应imgsz。几个参数按经验给个参考参数建议值说明--img1024遥感舰船目标尺寸占比小默认 640 容易把小船细节磨掉升到 1024 有明显收益--batch168~32 均可显存不够时用--batch 8配合梯度累积--epochs1002238 张图的数据量不算大太多轮过拟合太少训不透--weightsyolov5s.pt从 COCO 预训练权重起步比从零训练收敛快得多--img 1024不是玄学。舰船目标在遥感图里经常只占几十个像素你缩到 640 时小目标区域可能只剩十几个像素模型根本学不到纹理特征。当然显存会吃紧1080Ti 的 11GB 跑 batch 8 基本上稳batch 16 要看运气。4.3 用损失函数曲线判断训练有没有跑偏训练日志里会持续打印三组 lossbox_loss、cls_loss和obj_loss。box loss 负责回归框的位置和大小cls loss 负责类别判断obj loss 负责判断这个格子有没有目标。这三个值各自承担不同职责不要只盯总 loss。对遥感舰船数据我一般重点看 obj loss 和 box loss。开场几轮 obj loss 下降极快是正常的——模型在快速学会哪里有东西如果经过 20 轮 obj loss 还在高位反复横跳先考虑两类问题学习率太大导致震荡或者标注噪声太高框位置偏了、漏标了。box loss 如果完全不降查看是不是有小船目标因为下采样直接消失——这时--img提高或加数据增强里的scale参数更有效。这类数据量级的训练前 20 轮看趋势50 轮后看 mAP 的绝对涨幅曲线没有单一帅哥曲线别幻觉。5. 舰船检测数据集踩坑记录五条高频翻车与排查路径5.1 类别索引整体错位loss 却一直正常下降现象训练了几十轮 loss 降到很低Train/val mAP 看起来还行但推理时看到一艘货轮却标成了军舰。原因labels 里第一列数字是按某个顺序编码的类别索引而你 data.yaml 里的 names 列表顺序和它不一致。VOC 的 xml 是字符串类名不容易错YOLO 的数字索引一旦和 data.yaml 错位整个模型学的是索引 0 是驱逐舰但你喂给它的索引 0 是货轮。解决训练前写一条最笨的检查逻辑——随机抽 3 张图打开 txt把每行第一个数字对应到 names 里的类别名与原图对照确认。这比事后分析混乱矩阵快得多。5.2 验证集 mAP 很高但实际检测漏掉大量小船现象训练集和验证集上的 mAP0.5 到了 0.8 以上但丢到一张港口全景图上只检出大船很多几像素的渔船完全没框出来。原因2238 张的规模决定了它和 MS COCO 这类大库完全不同小目标占比高但绝对数量少。YOLO 的默认锚框尺寸是按 COCO 目标分布设计的对小目标召回天然偏弱此外--img 640会把小船缩得更小被骨干网络下采样到 8 倍甚至 16 倍之后特征直接丢失。解决把--img提到 1024 或 1280启用 YOLOv5 的--multi-scale如果用 v8 做迁移检查 anchors 分布必要时启用 autoanchor。更直接的方案是切 patch 训练把大图切成 640×640 的块再训练后面第 6 章会展开说明。5.3 同一艘船被重复框出七八个框NMS 压不下去现象密集港口场景一艘船周围堆了多个高置信框非极大值抑制之后还会残留重复框。原因舰船排列密、多船紧挨NMS 用的 IoU 阈值默认 0.45 在遥感场景偏向保守另一层面目标密集时相邻船体的特征在深层特征图上彼此干扰产生重复预测。属于模型和 NMS 参数的双重问题。解决YOLOv5/v8 的推理参数里把--iou-thres适当降到 0.3~0.35允许抑制更激进的重复框另一个经验是把类别置信度阈值--conf-thres从默认 0.25 提到 0.35重复框一般置信度偏低会被先一步滤掉。还没有改善的话检查是不是--agnostic-nms开了遥感多类密集场景下按类别独立的 NMS 效果往往更好。5.4 解压后 labels 目录出现一堆 0KB 空 txt现象训练日志报Train dataset is empty或No labels found in检查 labels 下有些 txt 是完全空的。原因原图存在但标注缺失的图片被一起打进了压缩包或者转换脚本对没有目标的图片生成了空文件。个别空 txt 不影响大局面但如果几百个空文件且恰好集中在某类会让模型对该类别的学习直接降级。解决解压后先清理。把所有空 txt 对应的图片从训练目录移除只留有图有标的干净样本。同时可以把空 txt 收集起来统计哪些类别缺失如果空文件刚好集中在小船上这个数据集的完整性就要打个问号了。5.5 训练时 BN 层崩溃或 loss 变成 NaN现象训练到中途obj_loss突然变成nan随后整个日志输出异常模型权重无法保存。原因遥感图像里偶尔有全黑或过曝的切片像素分布极端在训练前几轮触发数值不稳定另一常见原因是学习率配合大 batch 时带动量积压梯度爆炸。解决先把--batch调小看是否复现如果 NaN 只在 batch 大时出现就是显存发散问题把--lr从默认 0.01 降到 0.005。另外在 Dataset 加载前加一道过滤把灰度方差过低全黑全白的图片剔除。这两个操作成本低但能救回一半以上的 NaN 情况。6. 把舰船检测精度再往上顶mAP 验证方法与三个进阶技巧训练完成后别急着部署先在 val 集上跑一次标准验证得到 mAP0.5、mAP0.5:0.95 和每类的 AP 曲线。v5 里直接python val.py --data ship.yaml --weights runs/train/baseline_ship/weights/best.pt --img 1024最值得看的不是总 mAP而是混淆矩阵里哪两类互相串。遥感船舶里货轮和油轮长得像、小渔船和木质船边界模糊类别串扰是这类数据集的家常便饭。如果某两类 AP 互相拉低用类名里的confusion去针对性增补样本比盲目调训练参数有效得多。验证完做三件事。第一件是 patch 推理——把测试大图切成 1024×1024 的 patch每个 patch 独立推理再用权重合并结果小目标召回通常能拉回 5~8 个点第二件是 TTA 推理--augment打开水平翻转和缩放融合跑一次增加 1~2 个点代价是推理时间翻几倍第三件是锚框重聚类用 K-Means 在这个数据集上重新算锚框替换默认值小目标 AP 提升非常明显。这个数据集我实际跑过类似配置说句掏心窝的话2238 张的体量能支撑你把一款 YOLO 从零训到业务可用但别指望它覆盖所有港口场景——特征分布偏单一换一片海域风格后掉点是正常现象。拿它做预训练再用自己业务数据微调才是性价比最高的用法。希望帮到你少走点弯路训出一个能真正上线的检测模型。本文还有配套的精品资源点击获取