class_docstr: Feature Pyramid Network from https://arxiv.org/pdf/1612.03144.pdf with options for modifications.
  by default is constructed with Pyramid levels P2, P3, P4, P5.
docstr: :param x: input image of shape (b, c, y, x, (z))
  :return: list of output feature maps per pyramid level, each with shape (b, c, y, x, (z)).
docstr_tok: [":","param","x",":","input","image","of","shape","(","b",",","c",",","y",",","x",",","(","z",")",")",":","return",":","list","of","output","feature","maps","per","pyramid","level",",","each","with","shape","(","b",",","c",",","y",",","x",",","(","z",")",")","."]
code: def forward(self, x):
      """
      :param x: input image of shape (b, c, y, x, (z))
      :return: list of output feature maps per pyramid level, each with shape (b, c, y, x, (z)).
      """
      if self.operate_stride1:
          c0_out = self.C0(x)
      else:
          c0_out = x
  
      c1_out = self.C1(c0_out)
      c2_out = self.C2(c1_out)
      c3_out = self.C3(c2_out)
      c4_out = self.C4(c3_out)
      c5_out = self.C5(c4_out)
      if self.sixth_pooling:
          c6_out = self.C6(c5_out)
          p6_pre_out = self.P6_conv1(c6_out)
          p5_pre_out = self.P5_conv1(c5_out) + F.interpolate(
              p6_pre_out, scale_factor=2
          )
      else:
          p5_pre_out = self.P5_conv1(c5_out)
  
      p4_pre_out = self.P4_conv1(c4_out) + F.interpolate(
          p5_pre_out, scale_factor=2
      )
      p3_pre_out = self.P3_conv1(c3_out) + F.interpolate(
          p4_pre_out, scale_factor=2
      )
      p2_pre_out = self.P2_conv1(c2_out) + F.interpolate(
          p3_pre_out, scale_factor=2
      )
  
      # plot feature map shapes for debugging.
      # for ii in [c0_out, c1_out, c2_out, c3_out, c4_out, c5_out, c6_out]:
      #     print ("encoder shapes:", ii.shape)
      #
      # for ii in [p6_out, p5_out, p4_out, p3_out, p2_out, p1_out]:
      #     print("decoder shapes:", ii.shape)
  
      p2_out = self.P2_conv2(p2_pre_out)
      p3_out = self.P3_conv2(p3_pre_out)
      p4_out = self.P4_conv2(p4_pre_out)
      p5_out = self.P5_conv2(p5_pre_out)
      out_list = [p2_out, p3_out, p4_out, p5_out]
  
      if self.sixth_pooling:
          p6_out = self.P6_conv2(p6_pre_out)
          out_list.append(p6_out)
  
      if self.operate_stride1:
          p1_pre_out = self.P1_conv1(c1_out) + self.P2_upsample(
              p2_pre_out
          )
          p0_pre_out = self.P0_conv1(c0_out) + self.P1_upsample(
              p1_pre_out
          )
          # p1_out = self.P1_conv2(p1_pre_out) # usually not needed.
          p0_out = self.P0_conv2(p0_pre_out)
          out_list = [p0_out] + out_list
  
      return out_list
  
file_path: medicaldetectiontoolkit/models/backbone.py
imports: import torch.nn
  import torch.nn.functional
  import torch
label_desc: Use image node_id 2 for calling the FPN obj's underlying member method code with example usage: obj.forward(x) and returns: out_list