从零复现 UAV-DETR:无人机目标检测论文复刻全流程踩坑记录
从零复现 UAV-DETR:无人机目标检测论文复刻全流程踩坑记录
本文记录了我复现 UAV-DETR 这篇无人机目标检测论文的完整过程,分享了环境搭建、数据集处理、训练调参中遇到的各种问题和解决方案。最终在 VisDrone 数据集上取得了 mAP@50 = 52.90% 的成绩,超过了原论文报告的 48.8%。
前言
最近在做无人机相关的毕设/课题,需要复现一篇目标检测论文。选来选去,最终选了今年 1 月份挂在 arXiv 上的 UAV-DETR,原因很简单:
- 它基于 RT-DETR(端到端检测),不需要 NMS 后处理,部署方便
- 它专门针对无人机图像的小目标问题做了改进
- 代码基于 Ultralytics 框架,上手相对容易
但实际复现下来,发现坑远比想象的多。这篇文章就是来记录这些坑的。
一、论文在讲什么?
UAV-DETR 的核心思路是:在 RT-DETR 的基础上,加入频域信息来增强小目标的检测能力。
无人机图像的特点是目标小、密度高。传统方法只在空间域做卷积,高频信息(边缘、纹理)在多次下采样后会丢失。UAV-DETR 的做法是引入 FFT(快速傅里叶变换),在频域中对特征进行增强。
它主要改了三个地方:
第一个改动:MFFF 模块
这个模块的全名是 Multi-Frequency Feature Fusion。它的核心思想是:先把特征图变换到频域,做一波注意力加权,再变换回来。
有意思的是,它并不是对所有通道都做频域处理,而是只处理 25% 的通道,剩下 75% 直接通过。这种"分组处理"的设计在控制计算量的同时保持了效果。
第二个改动:频域感知下采样
普通的下采样(MaxPool、Stride Conv)会丢掉高频信息。这个模块在下采样的同时,通过一个并行的频域分支来保留这些细节。
第三个改动:语义对齐校准(SAC)
不同尺度的特征图拼接时,空间位置可能对不齐。SAC 通过可变形采样来校正这个偏移,让融合更精准。
理解了这三个改动,后面看代码就清晰多了。
二、环境搭建的坑
坑 1:Windows 编译问题
论文代码里有一个可变形注意力模块 MSDeformAttn,需要编译 CUDA 算子。在 Linux 下问题不大,但在 Windows 下会报各种编译错误。
我折腾了半天,最后发现 Ultralytics 框架里已经内置了一个纯 PyTorch 的实现(在 ultralytics/nn/modules/utils.py 里),虽然慢一点但完全能用。所以如果你也是 Windows 用户,不要去编译那个 CUDA 算子,直接用 Python 版本就行。
坑 2:Ultralytics 版本冲突
我一开始习惯性地 pip install ultralytics,结果发现最新版的 API 跟论文代码不兼容,各种报错。
后来才明白,论文代码里自带了一份修改过的 ultralytics,你得用项目目录下的那个版本,不能用 pip 安装的。正确的做法是 cd 到项目根目录下运行,这样 Python 会优先导入当前目录的 ultralytics。
坑 3:显存不够
我的 GPU 显存不大,一开始用 batch=8 直接 OOM。后来降到 batch=4 才跑起来。
如果你也遇到这个问题,除了降 batch size,还可以试:
- 开启混合精度训练(
amp=True) - 降低输入分辨率(
imgsz=512) - 清理 GPU 缓存:训练前加
torch.cuda.empty_cache()
三、数据集处理的坑
我用的是 VisDrone-2019-DET 数据集,这是无人机检测领域最常用的数据集之一。
坑 4:标注格式转换
VisDrone 的标注格式是这样的:
bbox_left, bbox_top, bbox_width, bbox_height, score, category, truncation, occlusion
但 UAV-DETR 需要的是 YOLO 格式:
class_id center_x center_y width height
这里有个容易忽略的细节:VisDrone 的类别 ID 是从 1 开始的,而且 0 表示"忽略区域"。如果你在转换时没有过滤掉 category=0 的标注,模型会学到一些错误的信号,精度会明显下降。
坑 5:data.yaml 的类别顺序
这个坑很小但很致命。data.yaml 里的类别顺序必须和标注文件里的类别 ID 对应。如果顺序错了,模型会把"行人"识别成"汽车",精度直接归零。
建议转换完数据后,随机抽几张图用 OpenCV 画一下标注框和类别名,确认无误再开始训练。
四、训练调参:最花时间的部分
我的最终配置
model.train(
data='data/visdrone/data.yaml',
epochs=400,
batch=4,
imgsz=640,
optimizer='AdamW',
lr0=0.0001,
patience=40,
mosaic=1.0,
mixup=0.2,
amp=False
)
坑 6:warmup_epochs 不是你想的那个
配置文件里有个参数 warmup_epochs: 2000,我一开始以为是预热 2000 个 epoch,心想这也太夸张了。
后来查了源码才发现,这个值其实是 warmup 的迭代步数(steps),不是 epoch 数。如果 batch_size=4,训练集有 6471 张图,那每个 epoch 大约 1618 步,2000 步也就 1.2 个 epoch 的样子。
坑 7:学习率不衰减
配置里 lrf: 1.0,意思是最终学习率 = 初始学习率 × 1.0,也就是不衰减。
这跟我以前的习惯(cosine annealing)很不一样。我试过改成 cosine 衰减,结果精度反而下降了。后来想想也合理,AdamW 本身就有自适应学习率的能力,配合固定学习率可能更适合 DETR 这类模型。
坑 8:Early Stopping 时机
我设置了 patience=40,也就是连续 40 个 epoch 验证集精度不提升就停止。最终在第 342 个 epoch 触发了 early stopping。
从训练曲线来看,mAP 在 200 epoch 之后提升非常缓慢(从 51.3% 到 52.9%),但确实还在涨。如果你计算资源充足,建议把 patience 调大一些,可能会有更好的结果。
坑 9:训练日志的正确读法
Ultralytics 输出的 results.csv 里有很多列,我一开始没注意看,把 val/cls_loss 当成了训练 loss,白白分析了半天。
正确的关系是:
train/giou_loss+train/cls_loss+train/l1_loss= 训练总 lossmetrics/mAP50(B)= 验证集 mAP@50(这才是你要关注的精度指标)val/*开头的是验证集上的 loss
五、我的改进尝试
在跑通原论文代码后,我尝试了一些改进,主要是为了探索有没有进一步提升的空间。
改进 1:加 Coordinate Attention
坐标注意力(CA)把通道注意力分解成水平和垂直两个方向,可以更好地保留位置信息。我觉得这对无人机小目标可能有帮助。
实际测试下来,有一点提升但不大,大约 0.3-0.5 个点。
改进 2:用 GFNet 替换 FFM
GFNet(Global Filter Network)用可学习的全局滤波器在频域处理特征,比原版的 FFM 更简洁。好处是参数量更少,缺点是效果略有下降。
改进 3:MFFF + Coordinate Attention
把 CA 加到 MFFF 前面,让频域处理前先做一波坐标注意力。这个组合的效果还不错,但需要更多实验来验证。
总的来说,原论文的架构已经设计得很好了,简单的模块替换很难带来大的提升。如果要显著超越原论文,可能需要更深入的架构创新。
六、最终结果
精度对比
| 模型 | Backbone | AP | AP₅₀ |
|---|---|---|---|
| UAV-DETR-R50 (论文) | ResNet50 | 31.5 | 51.1 |
| UAV-DETR-R18 (论文) | ResNet18 | 29.8 | 48.8 |
| UAV-DETR-EV2 (论文) | EfficientFormerV2 | 28.2 | 46.7 |
| 我的复现 (R18) | ResNet18 | 32.87 | 52.90 |
我在 ResNet18 backbone 上取得了 mAP@50 = 52.90%,超过了原论文报告的 48.8%,甚至比 R50 的 51.1% 还高。
为什么能超越?
说实话我也没完全搞清楚,可能的原因有:
- 训练更充分:我跑了 342 个 epoch,原论文可能没有训练这么久
- 数据增强有效:Mosaic + MixUp 的组合可能比原论文用的增强更强
- 超参数差异:不同的学习率、weight decay 等都会影响最终结果
不过精度对比需要谨慎看待,不同的训练环境、随机种子、数据划分都可能导致差异。
七、总结
这次复现最大的收获不是精度数字,而是对 DETR 类检测器有了更深入的理解。以前用 YOLO 只知道调参,现在对 Transformer 在检测中的作用、频域特征增强的思路有了更清晰的认识。
给想复现论文的同学几点建议:
- 先读论文,再看代码。不要上来就跑代码,先搞清楚论文在讲什么
- 一次只改一个东西。调参时不要同时改多个参数,否则你不知道哪个改动起了作用
- 记录每次实验。用 Excel 或 Notion 记录每次的配置和结果,方便回溯
- 善用 Git。每次改动都 commit,出了问题可以快速回退
复现论文是个体力活,但也是最好的学习方式。共勉。
代码已开源:GitHub,如果对你有帮助,欢迎 star。
更多推荐

所有评论(0)