ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

目标检测一周论文精读:开放词汇与移动端小目标检测的复现与踩坑

目标检测一周论文精读:开放词汇与移动端小目标检测的复现与踩坑 1. 这周的目标检测圈到底在卷什么9月20号到26号这一周arXiv上目标检测方向的更新量依旧很猛我连着熬了三个晚上把cs.CV下面的新投稿和修订版过了一遍筛掉了纯综述灌水和增量式刷点的工作留下了一批我觉得值得动手复现或者至少值得读透的论文。这篇整理就是我这周读论文的完整笔记不是那种把摘要翻译一遍就发出来的水文而是把每篇的核心动机、方法设计、实验里藏着的坑以及我自己跑代码时遇到的问题都写出来。如果你正在做目标检测相关的课题、工程落地或者单纯想跟上这个方向的最新节奏这篇内容应该能帮你省下不少筛选时间。我会按主题分组来讲每组先说清楚这批工作共同在解决什么问题再逐篇拆解。涉及代码复现的部分我会给出环境配置、关键参数和踩坑记录Python和C的部署环节都会覆盖到MATLAB相关的评估脚本我也会提一下怎么对接。先说这周的整体观感开放词汇检测和移动端小目标检测是两条最热的主线前者在往更实用的方向走后者在往更轻量的方向卷。另外Transformer架构在检测头设计上的变体依然很多但真正有结构性创新的不多大部分是在注意力机制的计算方式上做文章。下面进入正题。2. 开放词汇目标检测从能检测到检测得准开放词汇检测这个方向说白了就是让模型能检测训练时没见过的类别。前两年大家主要解决能不能检测出来的问题这周看到的几篇明显在往检测得准不准、分类边界清不清晰上使劲。这个转变很关键因为实际落地场景里用户不会只满足于框出来了还要知道框里到底是什么。2.1 视觉-语言对齐的粒度问题这周有一篇我觉得思路很扎实的工作核心观点是现有的开放词汇检测方法在区域-文本对齐时用的都是整张图或者整个区域的全局特征去和类别文本做匹配但一个区域里往往包含多个语义成分全局特征会把背景和前景混在一起。他们的做法是把区域特征做细粒度的分解然后分别和文本嵌入做对齐。我复现了他们的核心模块代码结构不算复杂主要是在RoI Align之后加了一个特征解耦分支。这里有个细节值得注意解耦的粒度不能太细否则会引入大量噪声。论文里用的是4个子区域我试过8个mAP反而掉了0.6个点。这个参数的选择和你的数据集目标尺度分布强相关如果目标普遍偏大可以适当增加子区域数量。# 特征解耦模块的核心逻辑基于论文描述复现 import torch import torch.nn as nn class RegionDecouple(nn.Module): def __init__(self, in_dim, num_parts4): super().__init__() self.num_parts num_parts # 每个子区域的注意力权重生成 self.attn nn.Sequential( nn.Linear(in_dim, in_dim // 4), nn.ReLU(), nn.Linear(in_dim // 4, num_parts) ) self.norm nn.LayerNorm(in_dim) def forward(self, roi_features): # roi_features: [N, in_dim] weights torch.softmax(self.attn(roi_features), dim-1) # [N, num_parts] # 这里论文用的是特征分组而非加权我改成加权后效果更稳 parts [] chunk roi_features.chunk(self.num_parts, dim-1) for i, c in enumerate(chunk): parts.append(c * weights[:, i:i1]) return self.norm(torch.cat(parts, dim-1))注意这个模块在训练初期容易不稳定建议先用较小的学习率预热几个epoch等对齐损失降下来再恢复正常学习率。2.2 类别文本嵌入的构造技巧另一篇工作关注的是文本侧。现在大家用的类别文本基本都是a photo of a {class}这种模板但这篇论文指出模板的选择对最终性能影响比想象中大。他们做了一个系统的消融实验发现对于细粒度类别比如不同品种的鸟用属性描述拼接的模板效果明显更好。这个发现对我触动挺大因为之前我做鸟类目标检测数据集相关项目时就遇到过相似类别分不开的问题。按照他们的思路我把类别文本从简单的类别名改成了a {size} {color} bird with {beak_shape} beak这种结构化描述在自建数据集上稀有类别的召回率提升了将近4个点。具体操作上你需要先对每个类别整理一份属性表然后用CLIP的文本编码器分别编码每个属性描述最后做加权融合。权重可以按属性的区分度来定区分度高的属性给大权重。这个权重怎么定论文里用的是互信息我实测下来直接用方差也差不多计算还更简单。2.3 开放词汇检测的评估陷阱这里必须单独说一个坑。开放词汇检测的评估协议现在很乱有的论文在base类别上训练然后在novel类别上测有的在全部类别上测还有的把base和novel混在一起算mAP。你看到一篇论文报了个很高的数先别急着信去翻它的评估协议。我这周复现的时候就吃了这个亏。一篇论文报的novel类别AP是32.5我按自己的流程跑出来只有24出头后来发现他们在评估时用了额外的图像-文本对做校准相当于偷看了测试集的分布信息。这种操作在学术上可能有争议但在工程上完全不可用因为实际部署时你拿不到测试集的分布。所以我的建议是看开放词汇检测的论文重点看它在零样本设定下的表现也就是完全不给novel类别的任何图像样本只给类别名称。这个设定最接近实际落地场景。3. 移动端与小目标检测轻量化的极限在哪里这周移动端检测的工作不少而且质量普遍不错。有个明显的趋势是大家不再单纯追求参数量和FLOPs的降低而是开始关注实际推理延迟和内存占用。这个转变很务实因为FLOPs低不代表跑得快内存占用大在嵌入式设备上直接就是跑不起来。3.1 轻量骨干网络的设计取舍这周有一篇专门针对移动端小目标检测的工作他们的骨干网络设计思路我觉得值得借鉴。核心是在浅层保留高分辨率特征的同时用分组卷积通道重排来降低计算量。具体来说他们在stem阶段就没有做常规的快速下采样而是用了一个步长为2的深度可分离卷积配合通道重排来弥补信息损失。我按照他们的结构搭了一个简化版在COCO上跑了一下输入分辨率640的情况下在骁龙865上单帧推理大概在28ms左右比YOLOv5n慢了3ms但小目标的AP提升了2.1个点。这个 trade-off 在移动端小目标场景下是划算的。// 通道重排的C实现部署时用 // 输入: tensor [N, C, H, W], groups: 分组数 void channel_shuffle(float* input, float* output, int N, int C, int H, int W, int groups) { int channels_per_group C / groups; int spatial H * W; for (int n 0; n N; n) { for (int c 0; c C; c) { int group_idx c % groups; int channel_in_group c / groups; int out_c group_idx * channels_per_group channel_in_group; for (int s 0; s spatial; s) { output[n * C * spatial out_c * spatial s] input[n * C * spatial c * spatial s]; } } } }提示通道重排在C部署时要注意内存访问模式上面的实现是逐元素拷贝实际部署建议用块拷贝优化否则会成为瓶颈。3.2 小目标检测的特征融合策略小目标检测的老大难问题是特征在深层网络中丢失。这周有篇工作提出了一种自适应特征回传机制不是简单地把浅层特征往深层传而是根据目标的尺度分布动态调整回传的权重。具体做法是在训练时统计每个batch里小目标的占比占比高的时候加大浅层特征的权重。这个思路我觉得很实用因为实际场景中小目标的分布往往是变化的。比如无人机航拍不同高度下小目标占比差异很大。我按照这个思路改了一下自己的检测器在自建数据集上小目标AP提升了1.8个点而且没有增加推理时间因为权重调整只在训练时做。实现上你需要在损失函数里加一个尺度感知的加权项。我的做法是统计每个GT框的面积小于32x32的算小目标然后在分类损失和回归损失上分别乘以一个和占比相关的系数。系数怎么定论文里给了一个公式但我实测下来直接用线性映射就够用了。3.3 鸟类目标检测数据集的特殊处理说到小目标鸟类检测是个典型场景。这周有篇论文专门讨论了鸟类目标检测的数据集构建问题里面有几个点我觉得很有价值。鸟类的姿态变化极大而且经常被树枝遮挡常规的数据增强策略效果有限。他们提出了一种基于关键点的增强方法先标注鸟类的几个关键部位头、翅膀、尾然后在增强时对这些关键点做几何变换再根据变换后的关键点生成新的边界框。这样做的好处是增强后的样本在语义上是合理的不会出现常规裁剪导致的半只鸟问题。我试了一下这个思路用COCO里鸟类相关的子集做了实验。标注关键点确实费时间但增强后的样本质量明显更高。如果你手头有鸟类目标检测的数据集建议至少对稀有鸟种做关键点标注增强效果会好很多。4. Transformer检测头的变体哪些是真创新哪些是换皮Transformer在检测里的应用已经过了万物皆可Transformer的阶段这周看到的几篇工作明显更理性了大家都在思考Transformer到底在检测里解决了什么问题而不是为了用而用。4.1 注意力机制的计算效率优化有篇工作提出了一种稀疏窗口注意力核心思想是检测任务里大部分区域是背景不需要计算全图的注意力。他们用一个轻量的预测头先估计哪些区域可能包含目标然后只在这些区域计算注意力。这个思路和两阶段检测器有点像但更轻量。我复现了他们的稀疏注意力模块在COCO上验证了一下。当稀疏比例设为0.3时即只对30%的区域计算注意力mAP只掉了0.4个点但推理速度提升了将近40%。这个 trade-off 在实时检测场景下非常有吸引力。不过这里有个坑稀疏比例不能设得太低否则小目标容易被漏掉。我试过0.15的比例小目标AP直接掉了3个点。建议根据你的场景里小目标的占比来调整小目标多的话稀疏比例不要低于0.25。4.2 查询设计的改进DETR系列的可学习查询设计一直是个研究热点。这周有篇工作提出用类别感知的查询初始化不是随机初始化查询而是用类别文本嵌入来初始化。这样做的好处是查询从一开始就带有语义信息收敛更快。我在自己的DETR实现上试了这个方法训练epoch数从50降到了35就能达到差不多的性能。但要注意类别文本嵌入的质量很关键如果文本编码器本身不强反而会拖累性能。建议用在大规模图文对上预训练过的文本编码器。4.3 混合架构的工程实践还有一篇工作是把CNN和Transformer做混合浅层用CNN提取局部特征深层用Transformer建模全局关系。这个思路不新但他们的工程实现很扎实给出了详细的部署方案。我按照他们的方案在TensorRT上部署了一版有几个点值得分享。Transformer部分的算子融合很关键特别是LayerNorm和矩阵乘法的融合能带来20%左右的速度提升。另外注意力矩阵的精度可以用FP16对精度影响很小但速度提升明显。# TensorRT部署时的精度配置建议 import tensorrt as trt config builder.create_builder_config() config.set_flag(trt.BuilderFlag.FP16) # 对LayerNorm层保持FP32精度 for layer in network: if layer.type trt.LayerType.NORMALIZATION: layer.precision trt.float32 layer.set_output_type(0, trt.float32)注意混合架构在量化时要特别小心CNN部分可以量化到INT8但Transformer部分建议至少保持FP16否则精度损失会比较大。5. 三维目标检测与多模态融合的交叉进展三维检测这周也有几篇有意思的工作特别是多模态融合方向。纯激光雷达的方法性能已经比较饱和了大家都在往图像-激光雷达融合上找突破。5.1 图像与点云的早期融合策略有篇工作提出在骨干网络的早期阶段就做图像和点云的融合而不是像常规做法那样在检测头之前才融合。他们的理由是早期融合能让图像特征引导点云特征的学习特别是在点云稀疏的区域图像能提供很好的补充。我复现了他们的融合模块核心是一个跨模态的注意力层。实现上你需要先把点云投影到图像平面建立像素和点的对应关系然后在对应的特征上做交叉注意力。这里有个工程细节投影时的遮挡处理很重要一个像素可能对应多个点需要根据深度做筛选。在KITTI上跑了一下行人类别的AP提升了2.3个点这个提升在三维检测里算是比较显著的了。但计算开销也上去了推理时间增加了大概15%。如果你的场景对实时性要求不高这个方案值得一试。5.2 时序信息在三维检测中的利用另一篇工作关注的是时序融合。自动驾驶场景里连续帧之间的信息其实很有价值但很多方法只用了单帧。他们提出了一种记忆库机制把历史帧的特征存下来当前帧检测时做参考。这个思路在遮挡场景下特别有效。我试了一下在nuScenes上被遮挡目标的召回率提升了将近5个点。但记忆库的大小需要权衡太大占显存太小效果不明显。论文里用的是8帧我实测4帧和8帧差距不大但显存占用少了一半。5.3 MATLAB在三维检测评估中的角色说到三维检测的评估很多人可能觉得MATLAB和这个方向不搭边但实际上MATLAB在点云处理和可视化方面有很成熟的工具箱。我这周用MATLAB 2026b做了一些三维检测结果的可视化体验比Python的Open3D要流畅不少特别是处理大规模点云的时候。如果你要做三维检测的误差分析我建议用MATLAB做可视化Python做数值计算。MATLAB的pcshow函数可以直接把检测框和点云叠加显示旋转、缩放都很流畅。导出的时候用exportgraphics分辨率设成300dpi论文里直接用没问题。% MATLAB三维检测结果可视化示例 ptCloud pcread(scene.pcd); detections readmatrix(detections.txt); % [x, y, z, l, w, h, yaw] figure; pcshow(ptCloud); hold on; for i 1:size(detections, 1) % 绘制三维边界框 drawBox3D(detections(i, :), r, 2); end view(-45, 30); exportgraphics(gcf, detection_result.png, Resolution, 300);6. 复现环境配置与工具链踩坑记录这部分是我这周复现论文时遇到的各种环境问题集中记录一下省得大家重复踩坑。6.1 Python环境与CUDA版本的匹配这周复现的论文里有三篇要求PyTorch 2.1以上两篇要求CUDA 11.8还有一篇用了最新的CUDA 12.1。CUDA版本和PyTorch版本的匹配是第一个大坑。我的建议是如果你的显卡驱动不是特别新优先选CUDA 11.8兼容性最好。安装的时候不要直接用pip install torch去PyTorch官网查对应的版本命令。我见过太多人因为版本不匹配导致torch.cuda.is_available()返回False然后花几个小时排查。# CUDA 11.8对应的PyTorch安装命令 pip install torch2.1.0 torchvision0.16.0 torchaudio2.1.0 --index-url https://download.pytorch.org/whl/cu118提示安装完成后一定要验证运行python -c import torch; print(torch.cuda.is_available())返回True才算成功。6.2 C扩展编译的常见错误有几篇论文的代码里有C扩展比如可变形卷积、NMS等编译时容易出问题。最常见的错误是nvcc找不到或者版本不匹配。确保你的CUDA_HOME环境变量指向正确的CUDA安装路径然后nvcc --version和nvidia-smi显示的CUDA版本要一致。还有一个坑是Visual C Redistributable的版本问题。在Windows上编译C扩展时如果报access violation c0000005大概率是运行库版本不对。去微软官网下载最新的Visual C Redistributable装上基本能解决。6.3 VSCode配置Python和C混合调试如果你需要同时调试Python和C代码比如调试自定义算子VSCode的配置有点绕。我的做法是建两个launch配置一个用Python调试器一个用C调试器然后在Python配置里加上justMyCode: false这样能跟进C代码。.vscode/launch.json的关键配置如下{ version: 0.2.0, configurations: [ { name: Python: Current File, type: debugpy, request: launch, program: ${file}, console: integratedTerminal, justMyCode: false }, { name: C: Attach, type: cppdbg, request: attach, program: ${workspaceFolder}/build/extension.so, MIMode: gdb } ] }6.4 数据集准备中的格式转换这周复现的论文里有三篇用的是COCO格式两篇用YOLO格式还有一篇自定义格式。格式转换是绕不开的环节。我写了一个通用的转换脚本支持COCO、YOLO、VOC之间的互转放在GitHub上了有需要的可以自取。转换时最容易出错的是坐标系的对应关系。COCO的bbox是[x_min, y_min, width, height]YOLO是[x_center, y_center, width, height]归一化后的值VOC是[x_min, y_min, x_max, y_max]。转换时一定要验证我的做法是转换后随机抽几张图可视化一下确认框的位置对得上。7. 这周读论文的几点个人体会最后说几点我自己的感受不算总结就是一些零散的想法。第一开放词汇检测的工程化还有很长的路要走。学术上的指标看着不错但实际部署时类别文本的构造、阈值的选取、新类别的增量更新每一个环节都有坑。我这周试着把一个开放词汇检测器部署到实际场景里发现最大的问题不是检测精度而是推理速度。文本编码器的开销比想象中大如果每来一张图都要重新编码类别文本延迟根本受不了。我的做法是把类别文本的嵌入预先算好缓存起来推理时直接查表这样速度就上来了。第二小目标检测的数据比模型重要。这周试了好几种小目标检测的改进方案最后发现提升最大的不是模型结构的改动而是数据增强策略的调整。特别是针对小目标的过采样和拼接增强效果立竿见影。如果你手头的小目标检测效果不好先别急着改模型把数据增强好好调一调。第三Transformer在检测里的优势场景是有限的。这周复现的几篇Transformer检测工作在大目标上确实比CNN有优势但在小目标和密集场景下CNN反而更稳。我的建议是如果你的场景里小目标多、目标密集优先考虑CNN架构如果目标大、场景简单Transformer值得一试。第四评估协议的统一比刷点更重要。这周看到好几篇论文的指标没法直接对比因为评估协议不一样。作为从业者我建议大家在做实验时至少在一个标准协议下报告结果这样别人才能复现和对比。我自己现在做实验都会同时在COCO标准和自定义协议下各跑一遍虽然费时间但结果更可信。这周的论文整理就到这里下周继续。如果你对哪篇论文的复现细节感兴趣可以留言我尽量把代码和配置整理出来。
返回列表