FPN
FPN(Feature Pyramid Network特征金字塔)是解决多尺度问题的不二之选,至被提出以来,一直占据着模型的Neck层,faster rcnn、retinanet、FCOS、YOLO。几乎所有耳熟能详的基于CNN的目标检测模型都离不开FPN,也有很多工作是对FPN的魔改,如PAN(Path Aggregation Network),还有NAS方法
1.关键参数
- in_channels(list[int]):backbone的输出的所有特征层的通道数,注意不管用不到该特征层,都要指示该特征层的通道数
- out_channels(int):FPN输出的通道数(所有输出层的output_channels一致)
- num_outs(int):输出特征层的数量
- 如果num_outs>end_level-start_level并且不使用add_extra_convs,则默认在output上进行maxpool。
- 如果num_outs>end_level-start_level并且指定了add_extra_convs,那么就根据add_extra_convs进行3*3卷积
 
- start_level(int):FPN利用的backbone特征层的起始层序号,默认0
- end_level(int):FPN利用的backbone特征层的末尾层序号,默认-1。前闭后开,[start_level,end_level)
- add_extra_convs(str or None):
 如果为None,那么不使用额外的卷积
 如果为str,为以下选项:发现额外的卷积都是33,stride=2的下采样。
 - 'on_input': 在输入的backbone的最后一层特征层进行33的卷积,代表算法为retinanet。
 - 'on_lateral': 以图1为例,就是在第二列的最后一个特征层进行卷积,几乎不用。
 - 'on_output': 在输出的最后一层特征层进行3*3的卷积,代表算法为FCOS。
- relu_before_extra_convs(bool):是否在额外卷积前进行relu,如FCOS的P6经过relu和conv获得P7
简单测试
>>> from mmdet.models.necks import FPN
>>> import torch
>>> in_channels = [2, 3, 5, 7]
>>> scales = [340, 170, 84, 43]
>>> inputs = [torch.rand(1, c, s, s) for c, s in zip(in_channels, scales)]
>>> len(inputs)
4
>>> inputs[0].shape
torch.Size([1, 2, 340, 340])
>>> inputs[1].shape
torch.Size([1, 3, 170, 170])
>>> inputs[3].shape
torch.Size([1, 7, 43, 43])
>>> inputs[2].shape
torch.Size([1, 5, 84, 84])
>>> for i in inputs:
...     print(i.shape)
... 
torch.Size([1, 2, 340, 340])
torch.Size([1, 3, 170, 170])
torch.Size([1, 5, 84, 84])
torch.Size([1, 7, 43, 43])
>>> self = FPN(in_channels, out_channels=11, num_outs=len(in_channels)).eval()
>>> outputs = self.forward(inputs)
>>> for i in range(len(outputs)):
...     print(f'outputs[{i}].shape = {outputs[i].shape}')
... 
outputs[0].shape = torch.Size([1, 11, 340, 340])
outputs[1].shape = torch.Size([1, 11, 170, 170])
outputs[2].shape = torch.Size([1, 11, 84, 84])
outputs[3].shape = torch.Size([1, 11, 43, 43])
>>> self = FPN(in_channels, out_channels=11, num_outs=5).eval()
>>> outputs = self.forward(inputs)
>>> for i in range(len(outputs)):
...     print(f'outputs[{i}].shape = {outputs[i].shape}')
... 
outputs[0].shape = torch.Size([1, 11, 340, 340])
outputs[1].shape = torch.Size([1, 11, 170, 170])
outputs[2].shape = torch.Size([1, 11, 84, 84])
outputs[3].shape = torch.Size([1, 11, 43, 43])
outputs[4].shape = torch.Size([1, 11, 22, 22])
>>> self = FPN(in_channels, out_channels=11, num_outs=6).eval()
>>> outputs = self.forward(inputs)
>>> for i in range(len(outputs)):
...     print(f'outputs[{i}].shape = {outputs[i].shape}')
... 
outputs[0].shape = torch.Size([1, 11, 340, 340])
outputs[1].shape = torch.Size([1, 11, 170, 170])
outputs[2].shape = torch.Size([1, 11, 84, 84])
outputs[3].shape = torch.Size([1, 11, 43, 43])
outputs[4].shape = torch.Size([1, 11, 22, 22])
outputs[5].shape = torch.Size([1, 11, 11, 11])
3.使用FPN经典网络
Faster RCNN/RetinaNet/FCOS
三个模型略有不同,C1~C5指的是ResNet的特征层,FPN的主要结构是本特征层11的卷积结果和上一特征层上采样结果进行add,图中黄色的11卷积就是mmdetection代码中的lateral_convs,紫色的3*3卷积就是mmdetection代码中的fpn_convs。可见三种算法最后的输出都是5个特征层。
1.1 三种网络的定义
- faster rcnn利用了C2~C5,并且在output的P5上进行最大池化获得P6
neck=dict( type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        num_outs=5)
# start_level默认为0,end_level默认为-1,利用C2~C5
# num_outs>end_level-start_level,并且又没有指定add_extra_convs,那么将在output采用maxpool
- retinanet利用了C3~C5,并且在input的C5上进行3*3卷积依次获得P6和P7,值得注意的是P6还要经过Relu操作才获得P7
neck=dict( type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        start_level=1, # start_level为1,end_level默认为-1.利用C3~C5
        add_extra_convs='on_input', # 在input上进行卷积获得P6和P7
        num_outs=5)
# mmdetection中retinanet的参数relu_before_extra_convs为False,很奇怪,明明原论文中的结构P6还要经过Relu操作才获得P7
- fcos利用了C3~C5,并且在output的P5上进行3*3的卷积依次获得P6和P7,值得注意的是P6还要经过Relu操作才获得P7
neck=dict( type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        start_level=1,
        add_extra_convs='on_output',  # 在output上进行卷积获得P6和P7
        num_outs=5,
        relu_before_extra_convs=True)  # P6还要经过Relu操作才获得P7
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号