简介:这份资源面向从事遥感图像目标检测的算法工程师、研究生及竞赛选手,提供一套按YOLOv5目录规范整理的卫星图像数据集,可直接投入训练,省去格式转换与清洗环节。数据覆盖飞机、油罐、船只三个类别,图像为800×600的RGB卫星图,标注清晰,适合做遥感场景下的检测模型训练与算法验证。包内共2000个文件,以1999个txt标注文件和1个Python可视化脚本为主,压缩包约237.68MB,其中txt文件对应训练集2398张、验证集1393张图片的边界框标签,脚本可随机读取一张图片绘制检测框并保存到当前目录,无需修改即可运行。资源按datasets-images-train与datasets-images-val分目录存放,并附类别说明文件,目录结构清晰,便于快速接入YOLOv5训练流程。目前已有219人学习下载,适合需要遥感小目标检测数据、希望快速复现实验或开展课程项目的读者参考使用。
1. 遥感卫星图像下的飞机、油罐、船只检测:为什么这三类目标值得单独做一个 YOLOV5 数据集
拿到一张遥感卫星图,你想让模型自动框出停机坪上的飞机、储油区的油罐、港口里的船只——这件事听起来像是把 YOLOV5 跑通就行,但真正动手过的人都知道,卡住你的往往不是模型结构,而是数据。遥感图像里的飞机可能只有十几个像素宽,油罐是密集排列的圆形,船只有时贴着码头、有时在开阔水面,三类目标的尺度、背景、分布规律完全不同。这就是为什么一个按 YOLOV5 目录格式整理好的三类别遥感检测数据集,比随便找一堆图丢进网络要值钱得多。
这篇文章面向的是想用 YOLOV5 训练自己数据集、尤其是做遥感卫星图像目标检测的从业者。不管你是刚接触 YOLOV5 训练自己数据集的新手,还是已经在调 yolov5 超参数的老手,下面会从目录结构、标注格式、类别设计、训练配置到量化部署前的数据准备,把这条链路拆开讲清楚。遥感卫星图像和普通自然图像最大的区别在于:目标小、方向任意、背景纹理复杂,这三类目标恰好覆盖了遥感检测里最典型的几种难点。读完你应该能判断这个方向值不值得投入,以及怎么用最小成本先跑通一版。
2. YOLOV5 目录格式到底长什么样:从 images 到 labels 的映射关系
2.1 标准目录结构与文件命名约定
YOLOV5 对数据集的目录组织有比较固定的约定,核心就两条:图片和标签分开放,文件名一一对应。常见做法是建一个数据集根目录,下面分 images 和 labels 两个子目录,各自再分 train、val、test。结构如下:
dataset/ ├── images/ │ ├── train/ │ │ ├── rs_aircraft_0001.jpg │ │ ├── rs_tanker_0002.jpg │ │ └── ... │ ├── val/ │ └── test/ └── labels/ ├── train/ │ ├── rs_aircraft_0001.txt │ ├── rs_tanker_0002.txt │ └── ... ├── val/ └── test/这里有个血泪经验:images/train 下的 rs_aircraft_0001.jpg 对应的标签必须是 labels/train/rs_aircraft_0001.txt,文件名主干完全一致,只是扩展名不同。YOLOV5 在加载时会用图片路径替换 images 为 labels、替换扩展名为 .txt 去找标签,找不到就当作负样本处理。很多人第一次训练 loss 不降,排查半天发现是标签文件名带了多余后缀或者大小写不一致。
图片格式常见的是 jpg 或 png,遥感卫星图像原始可能是 tif,建议先转成 jpg 或 png,避免训练时解码开销过大。标签文件是纯文本,每行一个目标,格式为:
<class_id> <x_center> <y_center> <width> <height>这五个值都是归一化到 0 到 1 之间的浮点数,x_center、y_center 是目标框中心点相对整图宽高的比例,width、height 是框宽高相对整图宽高的比例。注意不是像素值,也不是左上角坐标。遥感图像里目标小,归一化后数值可能只有 0.01 量级,这是正常的。
2.2 三类别标签的类别索引与 data.yaml 配置
三类别分别是飞机、油罐、船只,需要给它们分配 class_id。常见做法是按字母序或按重要性排:
| class_id | 类别名 | 英文名 | 典型尺度 |
|---|---|---|---|
| 0 | 飞机 | aircraft | 小目标,10-40 像素 |
| 1 | 油罐 | tanker | 中小目标,15-50 像素 |
| 2 | 船只 | ship | 变化大,10-100 像素 |
然后在数据集根目录建一个 data.yaml,YOLOV5 训练时通过这个文件找到数据:
# data.yaml path: /data/rs_dataset # 数据集根目录 train: images/train # 相对 path 的训练图片目录 val: images/val test: images/test nc: 3 # 类别数 names: ['aircraft', 'tanker', 'ship'] # 类别名,顺序必须和 class_id 对应参数说明:path 可以写绝对路径,也可以写相对路径,但 train/val/test 是相对 path 的。nc 必须等于 names 长度,否则训练时报维度不匹配。names 的顺序决定了 class_id,如果标注时飞机是 0、油罐是 1、船只是 2,这里就必须一致,否则模型学出来的类别会错位。我一般会在 data.yaml 旁边放一个 README 记录标注规则,避免多人协作时类别索引对不上。
2.3 从原始标注到 YOLO 格式的转换脚本
遥感数据集的原始标注可能是 VOC XML、COCO JSON 或者 shapefile。假设你拿到的是 VOC 格式,每个图片对应一个 XML,里面记录了目标的左上角和右下角像素坐标。转成 YOLO 格式的脚本如下:
import os import xml.etree.ElementTree as ET from PIL import Image # 类别名到 class_id 的映射,必须和 data.yaml 一致 CLASS_MAP = {'aircraft': 0, 'tanker': 1, 'ship': 2} def voc_to_yolo(xml_path, img_path, out_txt_path): # 读取图片宽高,用于归一化 with Image.open(img_path) as im: img_w, img_h = im.size tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.findall('object'): name = obj.find('name').text.strip() if name not in CLASS_MAP: continue # 跳过不在三类里的目标 cls_id = CLASS_MAP[name] bbox = obj.find('bndbox') xmin = float(bbox.find('xmin').text) ymin = float(bbox.find('ymin').text) xmax = float(bbox.find('xmax').text) ymax = float(bbox.find('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 # 裁剪到 0-1,防止标注越界 x_center = min(max(x_center, 0.0), 1.0) y_center = min(max(y_center, 0.0), 1.0) w = min(max(w, 0.0), 1.0) h = min(max(h, 0.0), 1.0) lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}") with open(out_txt_path, 'w') as f: f.write('\n'.join(lines))逻辑说明:先读图片宽高,再把 VOC 的左上右下坐标转成中心点加宽高,最后除以宽高归一化。参数上,保留 6 位小数足够,YOLOV5 内部会再处理。裁剪到 0-1 是防止有些标注框超出图片边界导致训练异常。如果原始标注是 COCO JSON,思路一样,只是解析方式换成读 JSON 的 annotations 字段,注意 COCO 的 bbox 是左上角加宽高,转换时先算中心点。
转换完建议抽查几个标签文件,用可视化脚本画框确认。遥感图像目标小,标注偏移几个像素在归一化后可能看不出,但训练时会影响回归精度。
3. 遥感卫星图像的目标特性:飞机、油罐、船只为什么不能混在一起训
3.1 三类目标的尺度分布与锚框选择
遥感卫星图像里,飞机通常停在机场,长度几十米,在 0.5 米分辨率下大概 20 到 40 像素;油罐是圆形或椭圆形,直径十几米到几十米,像素尺度 15 到 50;船只变化最大,小渔船可能 10 像素,大型货轮能到 100 像素以上。这三类目标的尺度分布差异明显,如果直接用 YOLOV5 默认的 COCO 锚框,小目标召回会很低。
YOLOV5 默认锚框是在 COCO 上聚类得到的,最小锚框对应约 8x8 像素,但遥感小目标可能只有 10 像素宽,默认锚框偏大。常见做法是用自己的数据集重新聚类锚框。YOLOV5 仓库里提供了 kmeans 脚本,但更直接的是用下面这段代码快速统计:
import numpy as np from sklearn.cluster import KMeans # 假设所有标签的宽高已经收集到 wh 列表,单位是像素 # wh = [(w1,h1), (w2,h2), ...] wh = np.array(wh) k = 9 # YOLOV5 用 9 个锚框 kmeans = KMeans(n_clusters=k, random_state=0).fit(wh) anchors = kmeans.cluster_centers_ # 按面积排序,YOLOV5 要求锚框按从小到大排列 anchors = anchors[np.argsort(anchors[:, 0] * anchors[:, 1])] print(anchors)参数说明:k 固定为 9,因为 YOLOV5 每个检测层 3 个锚框,共 3 层。聚类前要把所有训练标签的宽高从归一化值还原成像素值,否则聚类结果没有物理意义。得到锚框后,在训练配置里替换 anchors 字段。我一般会对比默认锚框和聚类锚框在验证集上的 mAP,遥感小目标通常能提升 3 到 8 个点。
3.2 方向任意性与旋转框的取舍
遥感图像里的飞机和船只方向是任意的,水平框会引入大量背景。比如一架斜向停放的飞机,水平框面积可能是实际目标的 1.5 到 2 倍,框内混入跑道或水面。油罐相对好一些,圆形目标用水平框也能接受。
如果你追求更高精度,可以考虑旋转框检测,但 YOLOV5 原生不支持旋转框,需要改网络头或换用 YOLOV5 的旋转框变体。对于大多数落地场景,我的建议是先用水平框跑通,因为标注成本低、生态成熟、部署简单。如果水平框的 mAP 已经满足业务要求,没必要上旋转框。只有在密集排列的船只或飞机场景下,水平框重叠严重导致 NMS 误删,才考虑旋转框。
一个折中做法是在数据增强里加入随机旋转,让模型对方向更鲁棒。YOLOV5 的 augment 配置里可以开 degrees 参数,但注意遥感图像旋转后目标可能超出边界,需要配合平移和缩放。
3.3 背景纹理与负样本策略
遥感卫星图像的背景非常复杂:机场跑道有标线,海面有波浪和云影,储油区有管道和建筑。这些纹理容易被模型误检成目标。常见做法是加入负样本,即没有三类目标的图片,标签文件为空。YOLOV5 支持空标签文件,训练时会把这些区域当作背景抑制。
负样本的比例需要控制。我一般按正样本的 10% 到 20% 加入负样本,太多会导致模型过于保守、召回下降。负样本要选那些容易混淆的场景,比如带标线的跑道、有波浪的海面、圆形建筑屋顶。这些在遥感图像里很常见,不加负样本的话,模型可能把圆形屋顶当成油罐。
另外,遥感图像常有云层遮挡,被云遮住的目标标注时应该跳过,不要强行标一个看不见的框。训练时模型会学到云层区域没有目标,反而有助于抑制云层误检。
4. 用 YOLOV5 训练三类别遥感数据集:配置、命令与参数调优
4.1 环境准备与最小训练命令
假设你已经装好 PyTorch 和 YOLOV5 依赖,数据集按第 2 章的目录结构放好,data.yaml 也写好了。最小训练命令如下:
python train.py \ --data /data/rs_dataset/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --project runs/train \ --name rs_3cls参数说明:--data 指向 data.yaml;--weights 用预训练权重,遥感数据量不大时从 COCO 预训练迁移能加快收敛;--img 是输入尺寸,遥感小目标建议用 640 或更大,但显存有限时 640 是平衡点;--batch 根据显存调,16 是 8G 显存的保守值;--epochs 100 起步,看验证集 mAP 是否还在涨。--project 和 --name 决定输出目录。
训练过程中重点看几个指标:box_loss、obj_loss、cls_loss 是否下降,验证集 mAP@0.5 和 mAP@0.5:0.95 是否上升。如果 box_loss 不降,先检查标签格式;如果 obj_loss 高,可能是负样本太少或背景太复杂;如果 cls_loss 高,检查类别是否平衡。
4.2 针对小目标的超参数调整
YOLOV5 的超参数在 hyp.scratch.yaml 里,遥感小目标需要调几个关键项:
| 参数 | 默认值 | 遥感建议值 | 作用 |
|---|---|---|---|
| img | 640 | 640-1024 | 输入尺寸,越大越小目标越清晰 |
| anchor_t | 4.0 | 3.0-4.0 | 锚框匹配阈值,小目标可适当降低 |
| fl_gamma | 0.0 | 1.0-1.5 | focal loss,缓解正负样本不平衡 |
| box | 0.05 | 0.03-0.05 | 框回归权重 |
| cls | 0.5 | 0.3-0.5 | 分类权重 |
| obj | 1.0 | 0.7-1.0 | 目标置信度权重 |
img 增大能提升小目标召回,但显存和推理时间也增加。如果显存够,建议用 1024 训练,推理时再降到 640。anchor_t 控制锚框和真实框的匹配,小目标匹配更难,适当降低可以让更多锚框参与。fl_gamma 开 focal loss 对遥感小目标有帮助,因为小目标正样本少,focal loss 能聚焦难样本。
另外,YOLOV5 的 mosaic 增强对小目标有效,但遥感图像拼接后目标可能出现在不合理的位置,比如飞机出现在海面。如果发现模型学出奇怪的上下文,可以降低 mosaic 概率或关闭。
4.3 训练日志解读与早停策略
训练日志里每轮会打印各类损失和验证指标。重点看验证集的 P、R、mAP@0.5。如果训练集 mAP 很高但验证集低,说明过拟合,需要加数据增强或减模型容量。如果两者都低,说明欠拟合,需要加训练轮数或调大模型。
YOLOV5 默认 patience 是 100,即 100 轮没有提升就早停。遥感数据集通常不大,我一般设 patience 50,避免浪费时间。早停后取 best.pt 做推理。如果训练过程中 mAP 波动大,可能是 batch 太小或学习率太高,可以调低学习率或增大 batch。
还有一个玄学问题:同样的配置,不同随机种子结果可能差几个点。建议固定种子,或者跑两三次取平均。如果时间紧,至少固定种子保证可复现。
5. 避坑与排查:遥感三类别数据集训练中最容易翻车的 5 个点
5.1 标签归一化用错基准尺寸
现象:训练 loss 正常下降,但推理时框的位置整体偏移或大小不对。 原因:标注时用了缩放后的图片尺寸做归一化,但训练时加载的是原图,或者反过来。遥感图像经常被裁剪或缩放,基准尺寸不一致就会导致归一化错误。 解决:统一以训练时实际加载的图片尺寸为基准。转换脚本里读图片宽高要用同一份图片。如果图片被预处理过,确保标签和图片同步处理。
5.2 类别索引与 data.yaml 不一致
现象:模型能检测到目标,但类别全错,飞机被标成船只。 原因:标注文件里的 class_id 和 data.yaml 的 names 顺序不一致。比如标注时飞机是 1,但 data.yaml 里 aircraft 在索引 0。 解决:转换脚本里的 CLASS_MAP 和 data.yaml 的 names 必须严格对应。建议在 data.yaml 里用注释写明每个索引对应的类别,转换后抽查几个标签文件确认。
5.3 小目标被下采样丢失
现象:大目标检测正常,小目标召回极低。 原因:YOLOV5 的 stride 8 检测层对应 80x80 特征图,输入 640 时每个格子 8 像素,小于 8 像素的目标在特征图上可能消失。 解决:增大输入尺寸到 1024 或 1280,或者修改网络增加更浅的检测层。另一个办法是把小目标图片裁剪成小块训练,推理时再拼接。常见做法是滑窗裁剪,每块 512x512,重叠 128 像素。
5.4 负样本过多导致召回下降
现象:误检少了,但漏检多了,mAP 反而降。 原因:负样本比例过高,模型学到背景占主导,对目标变得保守。 解决:负样本控制在正样本的 10% 到 20%,并且选容易混淆的场景。如果已经加多了,减少负样本或提高 obj 权重。
5.5 验证集和训练集分布不一致
现象:训练集指标很好,验证集差很多。 原因:验证集图片来自不同区域、不同季节或不同传感器,分布和训练集差异大。 解决:划分数据集时按区域或时间划分,确保验证集能代表真实场景。如果无法避免,在训练集里加入类似分布的图片。遥感图像尤其要注意不同光照、云量、地物类型的影响。
6. 从训练到落地:量化部署前的数据准备与验证技巧
训练出 best.pt 只是第一步,真正落地还要考虑推理速度和部署平台。如果你打算把模型量化后部署到 RK3568 或树莓派 4B 这类边缘设备,数据准备阶段就要为量化做铺垫。量化对数据分布敏感,校准集最好从训练集里抽,覆盖三类目标和各种背景。常见做法是抽 100 到 200 张,按类别和场景分层采样。
验证量化后模型是否掉点,不能只看 mAP,还要看单类召回。遥感小目标量化后容易丢失,因为量化误差对小目标的特征影响更大。我一般会单独统计飞机、油罐、船只的召回率,如果某一类掉超过 5 个点,就要考虑混合量化或保留部分层为浮点。
另一个技巧是推理时用 TTA(测试时增强),比如水平翻转和缩放,把多次结果融合。遥感图像方向任意,TTA 对旋转敏感,水平翻转可能反而有害。我试过只做多尺度 TTA,即 640 和 1024 两个尺度各跑一次再 NMS 融合,小目标召回能提升 2 到 3 个点,代价是推理时间翻倍。边缘设备上要权衡。
最后说一个我自己的习惯:每次训练完,我会把验证集里漏检和误检的图片单独挑出来,按类别和场景归类,看看是标注问题还是模型问题。遥感数据集标注成本高,很多漏检其实是标注漏了。这个复盘习惯帮我省了很多调参时间。希望帮到你。
本文还有配套的精品资源,点击获取