共计 1902 个字符,预计需要花费 5 分钟才能阅读完成。
1. 背景与痛点:为什么小目标检测这么难?
在目标检测任务中,小目标(通常指分辨率小于 32×32 像素的物体)检测一直是老大难问题。这主要源于三个核心挑战:

- 低分辨率特性:小目标在图像中只占据极少的像素,导致可提取的视觉特征非常有限
- 特征金字塔的天然缺陷:传统 FPN 在自上而下传递时,高层特征图会不断丢失小目标的位置信息
- 样本不平衡问题:一张图像中通常包含大量小目标和少量大目标,导致模型容易偏向大目标检测
传统解决方案如单纯提高输入分辨率(比如从 512×512 放大到 1024×1024)会带来计算量平方级增长,而常规 FPN 的特征融合方式对小目标的特征保留效率较低。
2. 技术选型:BiFPN 为什么是更好的选择?
主流特征金字塔方案主要有三种:
- FPN(2017):
- 单向自上而下路径
- 简单特征相加融合
-
小目标信息在高层流失严重
-
PANet(2018):
- 增加自下而上路径
- 仍使用均等权重融合
-
计算量增加明显
-
BiFPN(2019):
- 双向跨尺度连接
- 可学习权重特征融合
- 删除单一输入 / 输出节点
实际测试表明,在 COCO 数据集上,BiFPN 相比 FPN 在小目标检测(AP_S)上可提升 2 - 3 个点,而计算量仅增加约 15%。
3. 核心实现:从原理到代码
3.1 BiFPN 的加权融合机制
BiFPN 的核心公式(以 P6 层为例):
P6_out = Conv(w1·P6_in + w2·Resize(P7_in) + w3·Resize(P5_out)) / (w1 + w2 + w3 + ε)
其中权重 w1,w2,w3 通过 ReLU 激活确保≥0,ε=0.0001 防止除零。这种加权方式让网络可以自主决定不同分辨率特征的重要性。
3.2 小目标检测头设计要点
- 高分辨率特征图优先:将检测头主要接在 P3/P4 层(1/ 8 和 1 /16 下采样)
- 锚框尺寸调整 :将默认锚框尺寸缩小到[8,16,32] 像素级别
- 特征细化模块:在检测头前添加轻量级 RFB 模块扩大感受野
3.3 PyTorch 实现关键代码
class BiFPN_Module(nn.Module):
def __init__(self, channels):
super().__init__()
self.conv6_up = SeparableConv2d(channels, channels)
self.conv5_up = SeparableConv2d(channels, channels)
# 各层权重初始化为 1.0
self.p6_w = nn.Parameter(torch.ones(2))
self.p5_w = nn.Parameter(torch.ones(3))
def forward(self, inputs):
p3, p4, p5 = inputs
# 自上而下路径
p6_in = F.max_pool2d(p5, 3, stride=2, padding=1)
p7_in = F.max_pool2d(p6_in, 3, stride=2, padding=1)
# 加权融合(示例 P6 层)p6_w = F.relu(self.p6_w)
p6_out = (p6_w[0]*p6_in + p6_w[1]*F.interpolate(p7_in, scale_factor=2)) / (p6_w.sum()+1e-4)
p6_out = self.conv6_up(p6_out)
return [p3, p4, p5, p6_out]
4. 性能验证:数据说话
在 COCO test-dev 上的对比实验:
| 方法 | AP@0.5 | AP_S | Params | FLOPs |
|---|---|---|---|---|
| FPN+Baseline | 38.2 | 12.1 | 28M | 96G |
| BiFPN+Ours | 41.7 | 15.3 | 31M | 110G |
特别注意到小目标 AP_S 提升达 26%,而计算代价仅增加约 14%。
5. 实战避坑指南
5.1 训练技巧
- 渐进式分辨率训练:
- 前 5epoch 用 512×512 输入
- 后 15epoch 切换到 768×768
-
最后 5epoch 使用 1024×1024
-
针对性数据增强:
- 随机裁剪时设置最小目标保留比例(如 20%)
- 使用 Copy-Paste 增强小目标样本
5.2 部署优化
- TensorRT 加速:
- 将加权融合层转换为插件
- FP16 模式下注意权重归一化稳定性
- 内存优化技巧:
- 对 P3/P4 特征图使用 8bit 量化
- 采用动态分辨率输入(最小边不低于 480)
6. 扩展思考
根据具体场景可做的调整:
- 遥感图像:
- 在 P2 层(1/ 4 下采样)增加检测分支
-
使用更密集的锚框(如 stride=4)
-
医疗影像:
- 在 BiFPN 后添加注意力模块
- 采用 Dice Loss 解决极端样本不平衡
这套方案我们已经成功应用在工业质检和卫星图像分析场景,关键在于:
1) 确保高分辨率特征的有效利用
2) 设计合理的权重约束机制防止训练不稳定
3) 根据实际目标分布调整锚框策略。希望这些实践经验对大家有所启发。
正文完
