【目标检测】FPN(Feature Pyramid Network)

本文探讨了Feature Pyramid Network (FPN)在CVPR2017中的关键作用,如何通过融合高低层特征解决目标检测中尺寸问题,特别是在小物体检测上的优势。它结合Faster R-CNN,展示了如何在保持高速度的同时提高检测准确性。

【目标检测】FPN(Feature Pyramid Network) - 知乎Feature pyramid network是CVPR2017年的一篇文章,它在目标检测中融入了特征金字塔,提高了目标检测的准确率,尤其体现在小物体的检测上。 1. 动机(Motivation)识别不同尺寸的物体是目标检测中的一个基本挑战,而…https://zhuanlan.zhihu.com/p/62604038Feature pyramid network是CVPR2017年的一篇文章,它在目标检测中融入了特征金字塔,提高了目标检测的准确率,尤其体现在小物体的检测上。

1. 动机(Motivation)

识别不同尺寸的物体是目标检测中的一个基本挑战,而特征金字塔是多尺度目标检测中的一个基本的组成部分,但是由于特征金字塔计算量大,会拖慢整个检测速度,所以大多数方法为了检测速度而尽可能的去避免使用特征金字塔,而是只使用高层的特征来进行预测。

高层的特征虽然包含了丰富的语义信息,但分辨率低,很难准确地保存物体的位置信息。与之相反,低层的特征虽然语义信息较少,但分辨率高,就可以准确地包含物体位置信息。所以如果可以将低层的特征和高层的特征融合起来,就能得到一个识别和定位都准确的目标检测系统。所以本文就旨在设计出这样的一个结构来使得检测准确且快速。

虽然之前也有算法采用了多尺度融合的方式,但是一般都是在特征融合之后再做预测,而本文则是在不同的特征层都单独进行预测。

2. 结构(Architecture)

下图所示的三种结构是在目标检测中比较常见的结构:

图1 常见结构

(a) Featurized image pyramid:这种方式就是先把图片弄成不同尺寸的,然后再对每种尺寸的图片提取不同尺度的特征,再对每个尺度的特征都进行单独的预测,这种方式的优点是不同尺度的特征都可以包含很丰富的语义信息,但是缺点就是时间成本太高。

(b) Pyramid feature hierarchy:这是SSD采用的多尺度融合的方法,即从网络不同层抽取不同尺度的特征,然后在这不同尺度的特征上分别进行预测,这种方法的优点在于它不需要额外的计算量。而缺点就是有些尺度的特征语义信息不是很丰富,此外,SSD没有用到足够低层的特征,作者认为低层的特征对于小物体检测是非常有帮助的。

(c) Single feature map:这是在SPPnet,Fast R-CNN,Faster R-CNN中使用的,就是在网络的最后一层的特征图上进行预测。这种方法的优点是计算速度会比较快,但是缺点就是最后一层的特征图分辨率低,不能准确的包含物体的位置信息。

所以为了使得不同尺度的特征都包含丰富的语义信息,同时又不使得计算成本过高,作者就采用top down和lateral connection的方式,让低层高分辨率低语义的特征和高层低分辨率高语义的特征融合在一起,使得最终得到的不同尺度的特征图都有丰富的语义信息,如图2所示。

图2 Feature Pyramid Network

3. 特征金字塔(Feature Pyramid Network)

特征金字塔的结构主要包括三个部分:bottom-up,top-down和lateral connection。

图3 Feature Pyramid Network

3.1 Bottom-up

Bottom-up的过程就是将图片输入到backbone ConvNet中提取特征的过程中。Backbone输出的feature map的尺寸有的是不变的,有的是成2倍的减小的。对于那些输出的尺寸不变的层,把他们归为一个stage,那么每个stage的最后一层输出的特征就被抽取出来。以ResNet为例,将卷积块conv2, conv3, conv4, conv5的输出定义为{ C2、C3、C4、C5 } ,这些都是每个stage中最后一个残差块的输出,这些输出分别是原图的{  1/4、1/8、1/16、1/32 }倍,所以这些特征图的尺寸之间就是2倍的关系。

 

3.2 Top-down

Top-down的过程就是将高层得到的feature map进行上采样然后往下传递,这样做是因为,高层的特征包含丰富的语义信息,经过top-down的传播就能使得这些语义信息传播到低层特征上,使得低层特征也包含丰富的语义信息。

本文中,采样方法是最近邻上采样,使得特征图扩大2倍。上采样的目的就是放大图片,在原有图像像素的基础上在像素点之间采用合适的插值算法插入新的像素,在本文中使用的是最近邻上采样(插值)。这是最简单的一种插值方法,不需要计算,在待求像素的四个邻近像素中,将距离待求像素最近的邻近像素值赋给待求像素。待求像素灰度的值 的计算方式如下图所示:

图4 最近邻插值

最邻近法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。

 

3.3 Lateral connection

如下图所示,lateral connection主要包括三个步骤:

(1) 对于每个stage输出的feature map ,都先进行一个1*1的卷积降低维度。

(2) 然后再将得到的特征和上一层采样得到特征图进行融合,就是直接相加,因为每个stage输出的特征图之间是2倍的关系,所以上一层上采样得到的特征图的大小和本层的大小一样,就可以直接将对应元素相加 。

(3) 相加完之后需要进行一个3*3的卷积才能得到本层的特征输出 。使用这个3*3卷积的目的是为了消除上采样产生的混叠效应(aliasing effect),混叠效应应该就是指上边提到的插值生成的图像灰度不连续,在灰度变化的地方可能出现明显的锯齿状。在本文中,因为金字塔所有层的输出特征都共享classifiers/ regressors,所以输出的维度都被统一为256,即这些3*3的卷积的channel都为256。

图5 Lateral connection

 

4、应用(Application)

在文中,作者将FPN和Faster R-CNN相结合,将FPN用于RPN来提取proposal,将FPN用于Fast R-CNN来进行目标检测。

接下来这部分内容和Faster R-CNN比较相关,如果有不了解Faster R-CNN的,大家可以参考我这篇文章:Jacqueline:【目标检测】Faster R-CNNicon-default.png?t=M4ADhttps://zhuanlan.zhihu.com/p/61202658

### FPNFeature Pyramid Network)模型 示例代码 实现 以下是基于 PyTorch 的 Feature Pyramid Network (FPN) 模型的一个简单实现示例。此代码展示了如何构建一个多尺度特征金字塔结构,并将其应用于目标检测任务。 ```python import torch import torch.nn as nn import torchvision.models as models class FPN(nn.Module): def __init__(self, out_channels=256): super(FPN, self).__init__() # 使用 ResNet-50 作为 Backbone 提取基础特征 resnet = models.resnet50(pretrained=True) self.layer1 = nn.Sequential(resnet.conv1, resnet.bn1, resnet.relu, resnet.maxpool, resnet.layer1) self.layer2 = resnet.layer2 self.layer3 = resnet.layer3 self.layer4 = resnet.layer4 # Lateral connections to reduce channel size self.latlayer1 = nn.Conv2d(2048, out_channels, kernel_size=1, stride=1, padding=0) self.latlayer2 = nn.Conv2d(1024, out_channels, kernel_size=1, stride=1, padding=0) self.latlayer3 = nn.Conv2d(512, out_channels, kernel_size=1, stride=1, padding=0) # Top-down pathway and smooth layers self.toplayer = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1) self.smooth1 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1) self.smooth2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1) def _upsample_add(self, x, y): """Upsample tensor `y` to match the spatial dimensions of `x`, then add them together.""" _, _, H, W = x.size() return torch.nn.functional.interpolate(y, size=(H,W), mode='bilinear', align_corners=False) + x def forward(self, x): c1 = self.layer1(x) # Output shape: [B, 256, H/4, W/4] c2 = self.layer2(c1) # Output shape: [B, 512, H/8, W/8] c3 = self.layer3(c2) # Output shape: [B, 1024, H/16, W/16] c4 = self.layer4(c3) # Output shape: [B, 2048, H/32, W/32] p4 = self.latlayer1(c4) # Apply lateral connection on C4 p3 = self._upsample_add(p4, self.latlayer2(c3)) # Upsample P4 and add it with C3 after applying a lateral layer. p2 = self._upsample_add(p3, self.latlayer3(c2)) # Repeat process for C2. p4 = self.toplayer(p4) # Smooth top-layer output using convolutional smoothing operation. p3 = self.smooth1(p3) # Smooth intermediate outputs similarly. p2 = self.smooth2(p2) # Final smoothed result at highest resolution level. return p2, p3, p4 # Return multi-scale feature maps from different levels of pyramid structure. # Example usage: if __name__ == "__main__": model = FPN(out_channels=256).cuda() # Initialize FPN module with specified number of channels per map. input_tensor = torch.randn((1, 3, 224, 224)).cuda() # Create dummy batched image data tensor shaped appropriately. features = model(input_tensor) # Pass through network; get list containing three tensors corresponding to each scale's processed version. print([f.shape for f in features]) # Print shapes just so we can verify correctness visually here too! Should see something like [(1,256,H,W)] where height & width depend upon original input size divided by powers-of-two according to respective stages within architecture design itself... ``` 上述代码实现了基本的 FPN 结构,其中使用了 ResNet-50 作为骨干网络来提取多级特征图[^1]。通过横向连接和自顶向下的路径,该架构可以生成具有相同通道数但分辨率不同的多个特征图,从而支持多尺度目标检测需求[^4]。 #### 关键点解释 - **Backbone**: 这里选择了预训练好的 ResNet-50 模型作为主干网路,负责提取原始输入图片的基础特征[^3]。 - **Lateral Connections**: 利用卷积操作减少高层特征图的维度至统一尺寸以便后续融合处理。 - **Top-Down Pathway**: 将低分辨率高语义级别的特征逐步插值放大并与更高分辨率较低层次的信息相结合形成最终输出。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值