算法笔记(六)多尺度特征融合之FPN/PANet

本文介绍了多尺度特征融合技术在目标检测中的应用,包括特征金字塔网络FPN的设计思路及实现方式,以及FPN如何与RPN和ROI结合提高检测精度。此外还探讨了PANet在此基础上的改进。

前言

最近论文快deadline了,一直没空更新…今天复习一下多尺度特征融合的常用操作。

1. FPN 特征金字塔

论文:feature pyramid networks for object detection 论文链接

设计思路:

  • 底层的特征语义信息比较少,但是目标位置准确。
  • 高层的特征语义信息比较丰富,但是目标位置比较粗略。

模型设计:自底向上Bottom-up,自顶向下Top-down,横向连接Lateral connection。
在这里插入图片描述

  • 自底向上:特征图随着左半部分的网络的加深,尺寸会不断变小,语义信息会更加丰富,这里是将每个stage(尺寸不变的网络集合为一个stage)的最后一个特征图构成特征金字塔。
  • 自顶向下:通过upsampling的方法,不断放大特征图,使得低层特征也包含丰富的语义信息。
  • 横向连接:将上采样的结果和自底向上生成的相同大小的特征图进行融合。即:从左边过来的特征图,先经过1*1的卷积操作,然后与上面下来的特征图相加(element-wise addition),之后再经过3*3的卷积能得到本层的特征输出(消除上采样产生的混叠效应aliasing effect:插值生成的图像灰度不连续,在灰度变化的地方可能出现明显的锯齿状)。

FPN+RPN

原先的RPN网络,输入的是经过主干网络提取的特征图(单尺度),设置的anchor有3种尺寸,3种宽高比,故有9种anchor:

加入了FPN后,RPN的输入是多尺度特征图,也就是每一层特征图后连接一个RPN head,因为已经有多尺度特征图了,就不需要设置另外3种尺寸,故有15种anchor:

FPN+ROI

ROI的作用是将输入的(检测框,整特征图)进行pooling,得到相同尺寸的目标特征图。使用了FPN之后,就有了多尺度特征图,考虑到实际目标有大有小,所以使用下公式判断将哪一层的特征图输入到ROI中:

### 多尺度特征融合模块FPN的工作原理 FPN(Feature Pyramid Network)是一种用于多尺度目标检测的特征提取网络。其核心思想是通过自顶向下的路径和横向连接,整合不同尺度的特征[^1]。具体而言: - **基础网络**:FPN通常基于一个预训练的基础网络(如ResNet),该网络负责初步提取图像的高层次语义特征。 - **自顶向下路径**:从最高层的特征图开始,逐步上采样生成更高分辨率的特征图,并将其与较低层的特征图进行融合。 - **横向连接**:在每一层,将来自顶层下采样的特征图与对应低层的高分辨率特征图相加或拼接,从而保留更多细节信息。 这种方法有效解决了传统单一尺度特征提取中存在的问题,提升了对小目标的检测能力。 --- ### FPN的具体实现方法 #### 1. 自顶向下路径 FPN利用反卷积(即上采样操作)来增加特征图的空间尺寸,使高层语义丰富的特征能够传播到更低层。这一过程可以通过双线性插值或其他上采样技术完成。 #### 2. 横向连接 为了结合高低层特征的优势,在每个尺度上,FPN会将经过上采样的高层特征与对应的底层特征进行逐元素相加或者拼接操作。这一步骤有助于保持空间细节的同时增强语义信息。 #### 3. 输出特征金字塔 最终,FPN会在不同的尺度上生成一系列特征图,这些特征图被送入后续的目标检测头中,分别处理大中小目标。 --- ### FPN的代码示例 以下是基于PyTorch的一个简单FPN实现示例: ```python import torch import torch.nn as nn import torch.nn.functional as F class FPN(nn.Module): def __init__(self, in_channels_list, out_channels): super(FPN, self).__init__() # 定义 lateral layers (1x1 convs),减少通道数至统一维度 self.lateral_layers = nn.ModuleList([ nn.Conv2d(in_channel, out_channels, kernel_size=1) for in_channel in in_channels_list ]) # 定义 output layers (3x3 convs),平滑特征图 self.output_layers = nn.ModuleList([ nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1) for _ in range(len(in_channels_list)) ]) def forward(self, inputs): last_inner = self.lateral_layers[-1](inputs[-1]) # 对最深层做lateral convolution outputs = [last_inner] # 自顶向下路径 + 横向连接 for i in range(len(inputs) - 2, -1, -1): inner_lateral = self.lateral_layers[i](inputs[i]) upsampled_output = F.interpolate( last_inner, size=(inner_lateral.shape[2], inner_lateral.shape[3]), mode="nearest" ) last_inner = inner_lateral + upsampled_output # 融合当前层与上一层的信息 outputs.insert(0, last_inner) results = [] for idx, feature in enumerate(outputs): results.append(self.output_layers[idx](feature)) # 平滑特征图 return results ``` 上述代码定义了一个简单的FPN模块,其中`in_channels_list`表示输入各层的通道数列表,而`out_channels`则是输出特征图期望具有的统一通道数。 --- ### 注意力机制在FPN中的扩展应用 除了基本的FPN结构外,一些改进版本还引入了注意力机制以优化特征融合的效果。例如CCFM模块就结合了通道注意力和空间注意力,进一步增强了跨尺度特征的学习能力[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nooobme

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值