资讯动态

YOLOv5遥感图像目标检测实战:从数据切片到训练调参的完整指南

发布时间:2026/10/20 12:59:37 来源:尧图企业网站定制
遥感图像目标检测这几年是真火YOLOv5在这个领域也几乎成了默认的入门首选。不夸张地说我手里就有不下十个项目从本科毕设到横向课题最后落地的方案基本都是YOLOv5系。但我也见过太多人兴冲冲下载了一套开源代码把遥感影像丢进去一训练发现mAP低得没法看然后就开始怀疑模型本身有问题。这里我得先给个明确结论不是YOLOv5不行而是你把通用目标检测的思路原封不动搬到了遥感场景里。遥感图像和自然图像在目标尺度、目标密度、背景复杂度上的差异比你想象中大得多。本文就围绕基于YOLOv5的遥感图像目标检测这个主题把我做这类项目从数据准备、模型改造、训练调参到推理部署的完整流程以及那些论文里不会写、代码注释里也没提的坑一次性讲清楚。适合正在做毕设、准备投论文、或者刚接手遥感检测项目的朋友直接照着复现。1. 遥感图像目标检测为什么不能直接套通用模型1.1 通用检测器是在照片上长大的YOLOv5默认权重是在COCO数据集上预训练的。COCO是什么是日常照片里面有一个人占画面三分之一的大目标也有一个水杯只占几十个像素的小目标但总体来说目标的尺寸分布相对均匀一张640×640的图里你很少会遇到上百个密集排列的同类小目标。遥感图像完全是另一个世界。以常见的遥感检测数据为例一张原始影像动辄几千像素见方里面的飞机、车辆、船只、储油罐往往只占几十像素甚至几个像素。你如果把整张大图直接resize到640×640送进网络小目标的尺寸可能只剩两三个像素特征图上一个点都覆盖不到模型当然学不出来。更麻烦的是目标方向和排列方式。自然照片里的目标大多是正着的YOLOv5的锚框和水平边界框天然适配这种分布。而遥感图像里的飞机朝向任意、船舶在港口挤成一团、操场和球场形状各异直接用水平框去表达本身就存在大量冗余背景检测精度自然被拖累。1.2 遥感图像的三个典型难点我做遥感检测项目这几年总结下来遥感场景给目标检测模型制造的麻烦主要集中在这三个方向小目标密集分布大量目标在512×512的切片里只有10×10甚至5×5像素。YOLOv5下采样32倍后5×5的目标在特征图上连一个单元格都占不满属于典型的不可见特征。背景极其复杂自然图像中的背景相对纯净而遥感影像里有大量的纹理干扰——建筑阴影、植被、水体反光、道路边缘这些区域的特征和目标高度相似模型很容易误检。方向信息丢失YOLOv5输出的是水平框遥感目标如飞机、舰船带有明显朝向。水平框虽然也能用但跨目标的长宽比变化巨大锚框很难同时覆盖横着的飞机和竖着的飞机。1.3 既然如此为什么还要用YOLOv5你可能要问既然有这么多问题为什么不直接用专门为遥感设计的检测器比如旋转框检测、大模型检测器我的答案是YOLOv5仍然是现阶段性价比最高的起点。它有几个天然优势恰好打在遥感项目需求上维度YOLOv5优势对遥感检测的意义生态成熟源码结构清晰、社区活跃、B站知乎资料一抓一大把毕设和论文复现成本极低遇到问题基本都能搜到够用性好单阶段结构在速度和精度上均衡遥感图像往往要处理海量切片推理速度直接影响项目进度可扩展性锚框、骨干网络、检测头都可以模块化替换可以从通用版本开始逐步针对遥感任务做改动资源门槛低单卡即可训练显存需求可控学校实验室拿到的基本都是消费级显卡这是现实条件我做过的绝大多数遥感检测项目没有对YOLOv5的网络结构本身做魔改只是在数据管线、训练策略和最基础的锚框/输入尺寸上动手就已经能把精度拉到可用水平。那些一上来就加注意力模块、改BiFPN的项目反而经常因为训练不稳定导致效果还不如原版YOLOv5s。这背后的逻辑是遥感检测的主要瓶颈在数据分布和输入表达不在网络结构的高深程度。1.4 定义清楚论文源码项目到底要交付什么在做任何工作之前先想清楚成果形态。多数论文源码类型的遥感检测项目核心交付物是三件事一套能在公共数据集或自建数据集上跑通的完整代码——包括训练、验证、推理、可视化脚本以及一份清晰的README。一组可复现的实验数据——不同模型规模、不同输入尺寸、不同训练策略的对比表这是论文的实验章节素材。一个能讲清楚的技术故事——你的论文得有一个核心论点比如基于切片推理的YOLOv5遥感小目标检测优化方法然后把你的改进措施和消融实验都围绕这个论点展开。我见过不少同学把精力全花在调模型上最后代码勉强能跑但论文缺实验对比。实际上一个认真做数据处理的YOLOv5项目其产出价值往往高于一个粗糙堆模块的改进YOLOv5项目。2. 环境准备与数据集从拿到影像到能跑通训练脚本2.1 一套稳到不行的软件版本组合先说环境。YOLOv5官方仓库对版本的要求其实相当宽松但为了少踩坑我建议按下面这个组合来配Python3.8或3.9。别用3.11以上有些依赖库还不适配你会被编译错误折磨到怀疑人生。PyTorch1.10到2.0之间都行。如果用的是30系或40系N卡直接装官方推荐的CUDA版本即可比如torch 1.13.1cu117或torch 2.0.1cu118。CUDA与cuDNN跟着PyTorch的预编译包走不需要单独另外装一套系统级的CUDA只要NVIDIA驱动版本够新就行。依赖库进入YOLOv5目录后直接跑pip install -r requirements.txt它会装好opencv、matplotlib、numpy、seaborn这些。这里有个小提示YOLOv5的requirements.txt里包含了一个pycocotools包在Windows上经常编译失败。如果你不是跑COCO数据完全可以直接删掉这个依赖项不影响任何功能。当年我第一次在Windows上配环境就卡在这个包上卡了一下午。2.2 公共遥感数据集怎么选做遥感检测不建议一开始就上自建数据先用公共数据集把整个流程跑通再针对自己的数据做调整。目前业内常用来做YOLOv5遥感检测的数据集我按上手难度排个序RSOD只有飞机、操场、桥梁、油罐四类图像尺寸不大目标相对清晰。非常适合第一次跑通代码、验证训练流程。缺点是数据量小几百张类别太少论文说服力不够。NWPU VHR-10经典的10类遥感数据集包含飞机、船舶、储油罐、棒球场、网球场等目标大小差异比较明显是目前做消融实验最常见的选择之一。只有约800张图但标注质量高类别分布比较平衡。DIOR20个类别6000多张图像每张都是统一尺寸。类别多、场景丰富适合做完整的论文实验。缺点是单张图像尺寸偏大需要切片处理。DOTA这是遥感检测里的硬核数据集图像尺寸巨大有些几千×几千图像内容极其复杂标注既有水平框也有旋转框。如果你能在DOTA的子集上跑出一个像样的结果论文实验部分就基本稳了但新手直接上手DOTA容易劝退。我的建议路径是先用RSOD或NWPU VHR-10跑通全流程确认你的代码和训练策略没问题然后再在DIOR上进行正式的实验对比。DOTA做进阶挑战即可不必作为主力数据集。2.3 大影像切片与标注坐标换算遥感原始影像一般不能直接整张送入YOLOv5训练原因前面已经说过——目标太小了。通用的做法是滑窗切片把大图切成固定尺寸的小图同时把落在每个小图里的标注框一并切出来、换算好坐标。切片时有两个关键参数切片尺寸常用的是512×512或640×640。如果你的显卡是8GB显存建议512如果是12GB以上640更推荐因为更大的输入尺寸对小目标更友好。重叠率10%~25%。为什么要重叠因为目标可能正好待在被切开的边缘上没有重叠的话这个目标会被拦腰截断变成两个残破的小目标既难训练又难推理。坐标换算的逻辑其实不复杂。假设原图尺寸为W×H切片起始点为x0, y0切片尺寸为S×S那么原图中坐标为x, y的标注框左上角点在切片中的坐标就是x-x0, y-y0。同理标注框的右下角点也做同样的减法。但如果切片原图中某个标注框只有一部分落在切片内我一般会把中心点落在切片内的完整框保留其余的直接丢弃或者做边缘裁剪。这里给你一段切片时进行标注过滤的伪代码我实际项目里就是这么干的def crop_image_and_boxes(img, boxes, x0, y0, crop_size): img: 原图 boxes: (N, 5) [x1, y1, x2, y2, cls] x0, y0: 切片左上角在原图中的坐标 crop_size: 切片边长 crop img[y0:y0crop_size, x0:x0crop_size] new_boxes [] for box in boxes: x1, y1, x2, y2 box[:4] cx, cy (x1 x2) / 2, (y1 y2) / 2 # 只保留中心点落在切片内的框 if x0 cx x0 crop_size and y0 cy y0 crop_size: # 换算坐标 nx1, ny1 x1 - x0, y1 - y0 nx2, ny2 x2 - x0, y2 - y0 # 裁剪到切片范围内 nx1 max(0, nx1) ny1 max(0, ny1) nx2 min(crop_size, nx2) ny2 min(crop_size, ny2) # 过滤掉裁剪后过小的框 if nx2 - nx1 5 and ny2 - ny1 5: new_boxes.append([nx1, ny1, nx2, ny2, box[4]]) return crop, np.array(new_boxes)2.4 标注格式转换VOC/COCO转YOLO格式切片完成之后接下来是比较枯燥但极其重要的格式转换工作。YOLOv5训练用的标签是txt文件每行一个目标格式为class_id x_center y_center width height注意这里的x_center、y_center、width、height全部是归一化到0~1的相对坐标除以的是图片宽高不是原始像素坐标。我见过太多人在这里翻车直接拿像素坐标当成归一化坐标喂给模型结果训练时边界框全部乱飞。如果是PASCAL VOC格式的XML标注转换公式非常简单x_center (xmin xmax) / 2 / img_width y_center (ymin ymax) / 2 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height两个注意点一是类别ID必须从0开始连续编号不能跳号二是YOLOv5要求每张图片的txt标签文件名与图片文件名完全一致不含扩展名且标签文件与图片文件的存放路径要按照data配置文件的定义放好。如果图片在images/下标签在labels/下目录结构不对训练时会报DataLoader错误一个目标都读不进去。3. 真正影响遥感检测效果的六个关键改造点解决了数据和环境模型的效果开始取决于几个看起来不起眼但影响极大的细节。我按影响程度从高到低挨个说。3.1 输入尺寸和锚框必须重新设计YOLOv5默认输入分辨率是640×640锚框尺寸也是按COCO目标分布聚出来的。遥感图像的目标平均尺寸远小于COCO你必须做两件事第一把训练和推理的输入尺寸适当调大。我有一次实验里同一套NWPU VHR-10数据把输入尺寸从640提高到960mAP0.5直接从71%升到79%几乎立竿见影。不过输入尺寸不是越大越好太大显存吃不消训练速度也会明显下降一般定在640到1280之间比较合理。第二重新聚类锚框。YOLOv5自带了自动锚框优化功能训练时会在数据上重新跑K-Means聚类但它在训练开始时就会做会消耗一定时间。如果你觉得聚出来的锚框质量一般也可以手动先跑一次聚类把结果写进模型配置文件里这样训练启动时不会反复计算也更可控。# 模型配置文件中手动指定锚框示例 anchors: - [10, 13, 16, 30, 33, 23] # P3/8 - [30, 61, 62, 45, 59, 119] # P4/16 - [116, 90, 156, 198, 373, 326] # P5/323.2 用整图训练还是用切片训练这个问题在我做遥感检测时纠结了很久。整图训练的好处是上下文信息完整模型能看到目标的周围环境有助于理解目标与背景的关系坏处是目标太小难以学习到有效特征。切片训练的好处是目标相对尺寸变大特征更明显坏处是切掉了很多上下文信息边界处目标可能被截断还会产生很多只有背景没有目标的空切片。我的实践经验是训练阶段以切片为主推理阶段采用整图切片后再拼接的方式。训练切片没有必须使用重叠但推理阶段一定要用重叠切片。此外一种折中方案是多尺度训练比如同时采样512、640、960三种尺寸让网络在不同尺度上都能保持一定的敏感性。3.3 数据增强的取舍不是你堆得越多就越好YOLOv5自带的Mosaic增强确实强大四张图拼一起相当于变相增大了batch size、丰富了上下文这在自然图像上几乎是必开。但遥感检测里Mosaic有个副作用四张不同的遥感切片强行拼接后拼接边界上会出现大量不自然的地物混合区如果原图中目标较稀疏Mosaic反而会稀释目标的密度导致模型学到一些奇怪的上下文。我的做法是Mosaic增强只在前一半训练轮次开启后一半关闭让模型在接近真实分布的增强条件下完成最后的收敛。可以通过YOLOv5的训练参数传入增强配置也可以直接在数据集配置文件中调整增强项。另外遥感图像特有的增强其实很有效随机旋转90的倍数或任意角度、随机亮度和对比度调整、模拟云层遮挡的随机掩膜。这些增强模拟了遥感影像中常见的变化对提高模型的泛化能力有奇效。相比之下大幅度随机缩放这种自然图像里常用的增强在遥感小目标场景下反而容易把小目标缩没了我一般都把尺度抖动幅度控制得很小。3.4 类别不平衡让模型瞎了一半遥感数据集里类别不平衡问题相对突出。比如船舶和飞机类目标极多而桥梁、操场类目标可能少一个数量级。YOLOv5默认的类别损失对所有类别一视同仁如果某个类别样本特别少模型会倾向于不管它导致这个类别的召回率接近零。处理办法有三种按推荐程度排序对每张图按类别比例做欠采样/过采样的混合策略。对样本多的图做轻度裁剪对样本少的类别所在的图像块重复使用同时尽量保证一个epoch里各类别出现的次数接近。这个办法实现最简单效果也最可控。修改类别损失权重。YOLOv5的损失函数中类别损失是BCEWithLogitsLoss可以给它传入一个按类别频次反比计算的权重向量让模型在反向传播时对稀有类别加大惩罚力度。引入Copy-Paste增强。把稀有类别的目标从其他图上抠出来随机贴到当前图上同时把它对应的标注框也贴过去。这和YOLOv5自带的CopyPaste增强功能很接近可以直接开启。3.5 迁移学习的正确姿势不是直接解冻从头训练如果你完全从随机初始化开始在遥感数据上训练YOLOv5收敛会非常慢最终效果往往也不如意。正确做法是加载COCO预训练权重这是必要的因为遥感数据和自然图像共享大量低级视觉特征——边缘、纹理、角点这些预训练权重能帮你有一个很好的起点。先冻结骨干网络的前几层。第一个阶段只训练检测头的层骨干网络不动大约训练10~20个epoch让检测头先适应遥感数据的目标分布和格式。第二阶段再解冻全部层进行完整微调此时学习率要调低通常是把初始学习率降到第一阶段的1/10。这个两阶段迁移策略几乎适用于所有遥感检测项目。我也试过直接全程训练效果确实不如两阶段法。类似的技巧在YOLOv5里有现成的参数支持可以通过调整模型配置文件中的冻结层列表来实现第一阶段训练等模型稳定后去掉冻结再跑第二阶段。3.6 后处理细节置信度阈值和NMS的调节训练完成后推理时的置信度阈值和NMS参数也需要根据遥感场景单独调。COCO等自然图像任务里置信度阈值设0.25是一个常用默认值但在遥感场景下由于背景复杂模型会给很多背景区域打出中等置信度的分数。我建议多类别任务里置信度阈值从0.25往上调试到0.35~0.45之间观察漏检率和误检率的平衡。NMS的IoU阈值默认是0.45对密集排列的遥感目标来说偏严——船舶在港口里排列紧密目标框重叠很高NMS可能把相邻的两个真目标误删成一个。可以适当把NMS IoU阈值放宽到0.5~0.6同时检查有没有因为放宽而引入重复框。这些参数在YOLOv5验证脚本里都有直接的参数配置方法就是在运行val.py时加上--conf-thres和--iou-thres去调整。不要用默认值跑完就下结论一定要做一小组参数扫描实验。4. 训练细节与调参把mAP从50拉到80的实操记录4.1 一份可直接抄的训练配置单这里放一份我在中等规模遥感数据集比如NWPU VHR-10上验证过的配置你可以直接拿来做起点# train配置示例 model: yolov5s.yaml # 模型规模数据集小用s或m就够 data: my_remote.yaml # 数据集配置注意路径和类别数 epochs: 100 # 第一遍先跑满100个epoch看趋势 batch-size: 16 # 8GB显存建议816GB建议16 imgsz: 960 # 遥感小目标建议640以上 hyp: hyp.scratch-low.yaml # 低增强策略适合遥感数据 weights: yolov5s.pt # COCO预训练权重 cache: ram # 数据集不大时缓存到内存大幅提速这份配置的核心逻辑是什么用较小的模型、较大的输入尺寸、较低的数据增强强度起步。很多人在遥感检测上一上来就选YOLOv5x显存爆掉训练巨慢最后效果反而和s差不多。数据规模不大时模型容量过大会导致严重过拟合越小越稳。4.2 训练日志里藏着的三个信号训练时不要只看终端输出的mAP数值。YOLOv5的训练日志里有几个信号值得逐个追踪box_loss、obj_loss、cls_loss三个分量的下降形态。box_loss如果在前10个epoch快速下降后趋平说明回归任务学得还可以obj_loss如果持续高位不降说明大量目标没有被合理分配检测可能和锚框尺寸有关。验证集的P精准率和R召回率变化。如果P很高、R很低说明模型检出来的框大多是准的但漏检了很多目标此时应当提高召回率导向的参数或适当降低置信度阈值如果R高、P低说明误检多需要调高阈值或增加负样本。mAP0.5:0.95与mAP0.5的差距。这个差距如果很大说明检测框定位精度不够——目标虽然找对了位置但框的大小位置不准确。对遥感小目标来说这是常见问题缓解手段是更大输入尺寸和更强的回归优化。4.3 三种经典训练问题的现场排查我在做遥感检测项目中反复遇到过三种问题可以说大家基本都会遇到问题一loss不降或下降极慢。先检查是不是标签文件格式错了比如归一化坐标算错导致模型在拟合一堆无效目标。我再三强调坐标要除以图片宽高我自己也犯过这个错。排除标注问题后再看学习率是否过低或过高——YOLOv5通常默认的学习率下前10个epoch应该有明显下降。问题二训练集mAP高验证集mAP低。这是典型的过拟合。遥感数据集普遍偏小模型很容易记住训练图像的特殊纹理和布局。解决方向是引入更强的增强、加大数据集切片后等于变相增多了样本数量、或者减小模型规模。问题三验证集mAP波动巨大曲线像锯齿。这往往是因为验证集图像切片数量过少导致统计量不稳定。增加验证集的切片数量、使用更多的重叠切片能有效平滑这条曲线。4.4 消融实验怎么设计论文素材怎么攒论文里最核心的实验部分就是消融实验。很多人在设计消融时犯的错误是随意组合改动项导致无法解释每个模块的贡献。我比较推荐按照这个顺序做四组基础对比实验组改动内容记录指标Baseline官方YOLOv5s 640输入 默认锚框mAP0.5输入尺寸将输入尺寸改为960mAP、推理时间锚框重聚类为遥感数据重新聚类锚框mAP、召回率切片策略加入重叠切片训练/推理mAP、小目标AP每一张表都需要记录精确率、召回率、mAP0.5、mAP0.5:0.95、FPS。有了这张表论文的实验章节其实就已经完成了一大半。我一般还会额外加一组与现有方法对比的实验比如YOLOv5s、YOLOv5m、Faster R-CNN三者在同一数据集上的对比。这组数据不需要你自己去复现Faster R-CNN找一份已有的实现结果做参照即可但最好在描述里标注数据来源别让审稿人认为是编造。5. 推理阶段的切片检测与后处理合并训练完成算成功了一半推理阶段才是真正暴露问题的地方。尤其是遥感大图推理如果处理不当模型效果再好也会在最终输出上大打折扣。5.1 为什么推理也必须要切片训练时为了学小目标特征切片了推理自然也要切片。你不能把测试的原始大图直接丢给模型——一是显存放不下二是即使放得下目标缩小到像素级别后模型基本认不出来。推理切片有两种思路。第一种是独立切片每张切片独立送入网络得到检测结果后映射回原图坐标。第二种是重叠切片后合并切片之间有重叠一个目标可能在多个切片里出现需要用合并策略去重。第一种实现简单但边界处的目标容易被截断召回率偏低。第二种效果好代价是推理时间增加。我实测下来重叠率在15%左右即可覆盖大部分目标截断问题。再高收益不大时间成本却直线上升。5.2 边界框映射回原图的完整逻辑假设切片尺寸为S×S切片左上角在原图中的坐标是x0, y0。切片中检测到某个目标其归一化坐标为cx, cy, w, h——注意推理输出也是归一化的。那么在原图中的像素坐标是x1 (cx - w / 2) * S x0 y1 (cy - h / 2) * S y0 x2 (cx w / 2) * S x0 y2 (cy h / 2) * S y0然后要把这些坐标映射后裁到原图范围内防止坐标越界。如果这个目标处于重叠区域那么在多个切片的输出里都会出现它分别计算出了不同的框。此时就轮到合并策略上场了。5.3 重叠切片的去重合并NMS的两种常用做法最简单的做法是把所有映射回原图的框收集起来再做一次普通的NMS通常就能把多路检测合并成一个。但在重叠区域非常大、目标数量很多的情况下普通NMS可能把真实目标重复抑制掉。更稳的做法是用加权NMSSoft-NMS检测到同一个目标的多个框先按置信度排序保留最高置信度的框但在抑制阶段不是直接删除IoU超过阈值的框而是按IoU比例降低其置信度最后根据置信度阈值决定是否保留。这样在密集遥感场景下相邻目标不容易被误删。我提供一个从YOLOv5推理脚本改造的参考流程推理时记录每个检测框来自于哪张切片记录切片偏移量将坐标映射回原图后直接进入合并函数。合并完成后再按照最终置信度阈值输出结果。6. 复盘我在这类项目里踩过的坑最后想聊几个我做过多个YOLOv5遥感检测项目后最想让后来人避开的坑。6.1 切片坐标精度和标注错位问题切片的坐标计算必须用整数运算浮点数反复换算会积累误差让标注框和目标之间出现几像素的偏移。小目标本身只有十几像素几像素的错位就已经是毁灭性的。因此我统一用整数坐标做切片计算并且切出来的图片在可视化检查阶段必须逐张人工抽查几轮——专门看标注框和目标是否对齐。6.2 全背景切片是误检放大器遥感影像里大面积是背景切片会产生大量空图。这些空图参与训练时如果完全没有目标YOLOv5会把它们当作纯负样本有一定正面价值。但如果切片策略设计不当导致比例失衡严重的空图过多模型就会倾向于输出大量背景框作为安全预测。我处理的办法是切片后对每个切片检查包含目标的数量目标数低于一定阈值就放弃该切片或者用复制采样让有目标切片的数量在一个epoch中始终占据主导地位。6.3 锚框手动改砸了的典型症状很多人看了教程就手动修改锚框改完发现训练map不降反升或者目标漏检率变得非常高。原因往往是锚框数量与特征图尺度不匹配——YOLOv5有P3、P4、P5三层特征图分别对应小、中、大目标锚框要按层划分成三组每组3个。如果你把所有锚框放在一个组里模型只能在单一尺度上检测目标其他尺度的检测头基本瘫痪。手动改锚框前先跑一次官方自动聚类脚本把它的输出结果作为基准再人工微调这样出错的概率会小很多。6.4 显存不足时的应急方案显存不够时不要急着把batch设置为1死磕。YOLOv5自带梯度累积功能batch设小但梯度累积步数加大效果接近于大batch训练。再配合图像尺寸稍微降低一点从960降到768一般8GB显存也能把训练跑起来只是时间会久一些。还有一个偏方训练前期用较小的输入尺寸后期微调时再用大尺寸这样能明显降低显存峰值。最后再说个我用了很久的小习惯每训练完一版模型就把这版模型的推理结果从头到尾滚动可视化检查一遍。mAP数值看着再漂亮都不如自己肉眼扫一遍检测效果来得真实。遥感检测里的许多问题——类别混淆、背景误检、密集目标漏检——在mAP曲线上往往体现得很隐晦但在一张检测可视化图上却一目了然。这个习惯帮我避免了很多次模型指标还行一跑实际数据就露馅的尴尬局面。你如果正在做遥感检测项目不妨也试一试。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑