
这张图其实有问题,一个特征图的来源最多有四个,图中画了5个,绿色和紫色的来源不能同时存在,如果配置文件的paths=['bu'] 则是绿色,否则是紫色。
这是配置文件
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        inter_channels=256,
        num_outs=5,
        stack_times=4,
        paths=['bu'] * 4,
        same_down_trans=None,
        same_up_trans=dict(
            type='conv',
            kernel_size=3,
            stride=2,
            padding=1,
            norm_cfg=norm_cfg,
            inplace=False,
            order=('act', 'conv', 'norm')),
        across_lateral_trans=dict(
            type='conv',
            kernel_size=1,
            norm_cfg=norm_cfg,
            inplace=False,
            order=('act', 'conv', 'norm')),
        across_down_trans=dict(
            type='interpolation_conv',
            mode='nearest',
            kernel_size=3,
            norm_cfg=norm_cfg,
            order=('act', 'conv', 'norm'),
            inplace=False),
        across_up_trans=None,
        across_skip_trans=dict(
            type='conv',
            kernel_size=1,
            norm_cfg=norm_cfg,
            inplace=False,
            order=('act', 'conv', 'norm')),
        output_trans=dict(
            type='last_conv',
            kernel_size=3,
            order=('act', 'conv', 'norm'),
            inplace=False),
        norm_cfg=norm_cfg,
        skip_inds=[(0, 1, 2, 3), (0, 1, 2), (0, 1), (0, ), ()]))stack_times=9,这个时一共多少列
paths=['bu'] * 9, 这个时路径,bu是从下而上,大特征图用stride卷积逐步变小,特征图从下往上计算,最后计算最小的特征图
skip_inds=[(0, 1, 2, 3), (0, 1, 2), (0, 1), (0, ), ()]))
这个很难理解,五个元组代表五层输出,一个元组代表一列即一个stack
第0层的0,1,2,3列,跳过,也就是从上一列对应层数直接拿过来,不处理
第1层的第0,1,2 列直接从上一列拿
第2层的第0,1列直接从上一列拿
第3层的第0,0列直接从上一列拿
第4层不从前面拿
一个特征图如果没被跳过,则有4个来源,除了顶层和底层只有三个来源之外。这里只说bu方向,4个来源分别:正下方的特征图下采样,左上的特征图上采样,正左方向的特征图1*1卷积,第0列的对应层的特征图1*1卷积,然后把这几个加起来。如果是顶层和底层就没有左上方上采样和下方下采样。
注意上采样时,先进行一个3*3卷积再进行一个上采样。
最开始的时候
# build all levels from original feature maps
feats = [
    lateral_conv(inputs[i + self.start_level])
    for i, lateral_conv in enumerate(self.lateral_convs)
]
for downsample in self.extra_downsamples:
    feats.append(downsample(feats[-1])) 
先变成256通道的,如果层数不够,则上采样,凑出额外层,也就时FPN的extra_layer= 'input'
最后的时候:把最后一列做一个3*3的卷积
我把self.fpn_transitions 网络显示出来,篇幅限制我把bn 和激活去了。
(0): ModuleList(
     (0): ModuleDict()
     (1): ModuleDict()
     (2): ModuleDict()
     (3): ModuleDict()
     (4): ModuleDict((same_up): ConvModule(
         (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
       (same_down): None
       (across_lateral): ConvModule(
         (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
       (across_down): None
       (across_up): None
       (across_skip): ConvModule(
       )
     )
   )
最外层的(0): ModuleList代表一列,里面的(0): ModuleDict()    (1): ModuleDict()    (2):ModuleDict()
     (3): ModuleDict()    (4): ModuleDict 代表每一层。
如果为空则他被跳过了,
如果不为空,下面举例,他是顶层所以只有三个部分。
(4): ModuleDict(
正下方下采样,如果来自同一列则用same,不同列用across
(same_up): ConvModule(
         (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
       (same_down): None
前一列对应层卷积
       (across_lateral): ConvModule(
         (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
bu的时候左上角上采样
       (across_down): None
tb的时候右下角上采样
       (across_up): None
对第0列卷积
       (across_skip): ConvModule(
fpn_transitions:
ModuleList(
  (0): ModuleList(
    (0): ModuleDict()
    (1): ModuleDict()
    (2): ModuleDict()
    (3): ModuleDict()
    (4): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): None
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
  )
  (1): ModuleList(
    (0): ModuleDict()
    (1): ModuleDict()
    (2): ModuleDict()
    (3): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): UpInterpolationConv(
        (conv): ConvModule(
          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (activate): ReLU()
        )
      )
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
    (4): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): None
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
  )
  (2): ModuleList(
    (0): ModuleDict()
    (1): ModuleDict()
    (2): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): UpInterpolationConv(
        (conv): ConvModule(
          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (activate): ReLU()
        )
      )
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
    (3): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): UpInterpolationConv(
        (conv): ConvModule(
          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (activate): ReLU()
        )
      )
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
    (4): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): None
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
  )
  (3): ModuleList(
    (0): ModuleDict()
    (1): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): UpInterpolationConv(
        (conv): ConvModule(
          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (activate): ReLU()
        )
      )
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
    (2): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): UpInterpolationConv(
        (conv): ConvModule(
          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (activate): ReLU()
        )
      )
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
    (3): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): UpInterpolationConv(
        (conv): ConvModule(
          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (activate): ReLU()
        )
      )
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
    (4): ModuleDict(
      (same_up): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (same_down): None
      (across_lateral): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
      (across_down): None
      (across_up): None
      (across_skip): ConvModule(
        (conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (activate): ReLU()
      )
    )
  )
)









