读懂FPN核心代码
在目标检测、图像分割、关键点检测等CV任务中,FPN(特征金字塔网络)是当之无愧的经典基石模块,几乎所有主流模型(YOLO、Mask R-CNN、RetinaNet)都能看到它的身影。
一、核心代码
def forward_fpn(self, c3, c4, c5): # 1. 横向卷积:统一通道、提纯主干特征 l3 = self.lateral_c3(c3) l4 = self.lateral_c4(c4) l5 = self.lateral_c5(c5) # 2. 自顶向下特征融合+平滑 p5 = self.smooth_p5(l5) p5_up = F.interpolate(p5, scale_factor=2, mode='bilinear', align_corners=False) p4 = self.smooth_p4(l4 + p5_up) p4_up = F.interpolate(p4, scale_factor=2, mode='bilinear', align_corners=False) p3 = self.smooth_p3(l3 + p4_up) # 返回三层多尺度特征金字塔 return p3, p4, p5二、前置基础:C3/C4/C5
主干网络(Backbone)输出的三级特征图,对应不同尺度、不同特征能力,也是FPN的输入原料:
C3(浅层特征):分辨率高、细节纹理丰富,擅长识别小目标,但语义信息弱,分不清物体类别
C4(中层特征):兼顾细节与语义,适配中等尺寸目标
C5(深层特征):经过多次下采样,分辨率最低、细节丢失多,但语义信息极强,擅长识别大目标、判断物体类别
核心痛点:单独用C3/C4/C5任意一层特征,都无法同时识别大、中、小目标。FPN的作用就是取长补短,融合三层特征的优势。
三、FPN整体结构图解
这段代码完整复刻了FPN的三大核心结构:横向连接 + 自顶向下上采样 + 特征融合平滑。下面是精准对应代码、带尺寸倍率的完整FPN结构流程图,完美匹配代码执行逻辑:
c5 (1/32 最大感受野、强语义) → lateral_c5 → l5 → smooth_p5 → p5 (1/32) ↓ upsample ×2 (bilinear) ↓ c4 (1/16 中等尺度) → lateral_c4 → l4 + p5_up → smooth_p4 → p4 (1/16) ↓ upsample ×2 (bilinear) ↓ c3 (1/8 高分辨率、富细节) → lateral_c3 → l3 + p4_up → smooth_p3 → p3 (1/8)倍率说明:1/8、1/16、1/32 代表特征图相对于原图的下采样倍数,数值越小、分辨率越高,对应目标检测的小、中、大目标检测分支。
四、逐行代码通俗拆解
1. 横向连接:l3、l4、l5 特征预处理
l3 = self.lateral_c3(c3) l4 = self.lateral_c4(c4) l5 = self.lateral_c5(c5)作用:统一特征通道、提纯有效特征。
主干网络输出的C3/C4/C5通道数各不相同(比如ResNet中C3=512、C5=2048),无法直接相加融合。
这里的lateral_c3/c4/c5都是1×1卷积层,核心功能:
统一三层特征的通道数(比如全部统一为256通道)
压缩冗余特征,保留核心信息,为后续融合做准备
2. 顶层特征初始化:生成P5
p5 = self.smooth_p5(l5)C5是主干最深层特征,语义信息最丰富,不需要融合上层特征(本身就是顶层)。
smooth_p5是3×3卷积层,作用是平滑去噪、优化融合后特征,消除上采样带来的锯齿、伪影,让特征更规整,这是FPN的细节优化精髓。
3. 第一次上采样+融合:生成P4
p5_up = F.interpolate(p5, scale_factor=2, mode='bilinear', align_corners=False) p4 = self.smooth_p4(l4 + p5_up)这是FPN自顶向下融合的核心步骤:
上采样:将顶层强语义特征P5,通过双线性插值放大2倍,分辨率和L4保持一致
特征相加:L4(中层细节特征) + P5_up(高层语义特征),实现细节+语义双向融合
平滑卷积:smooth_p4优化融合后的特征,提升特征鲁棒性
4. 第二次上采样+融合:生成P3
p4_up = F.interpolate(p4, scale_factor=2, mode='bilinear', align_corners=False) p3 = self.smooth_p3(l3 + p4_up)逻辑和P4完全一致,层层传递融合:
将已经融合好的P4特征再次放大2倍,和浅层L3细节特征相加,让最细分辨率的P3特征,也具备深层语义信息,彻底解决浅层特征“看得清、认不出”的问题。
5. 输出三级特征金字塔
return p3, p4, p5最终输出的P3、P4、P5,和原始C3/C4/C5一一对应,但性能全面升级:
P3:高分辨率+丰富细节+语义信息 → 适配小目标检测
P4:细节与语义均衡 → 适配中等目标检测
P5:强语义+全局特征 → 适配大目标检测
五、关键参数详解
1. bilinear 双线性插值
FPN默认的上采样方式,相比于最近邻插值,它放大特征图时不会产生锯齿,特征过渡更平滑,精度更高,是CV任务的最优选择。
2. scale_factor=2
每次上采样放大2倍,严格匹配主干网络下采样倍率,保证特征图尺寸完全对齐,才能精准相加融合。
3. align_corners=False
PyTorch官方推荐配置,避免坐标偏移问题,保证上采样后的特征像素位置精准,融合特征不错位。