code: def generate_pyramid_anchors(logger, cf):
      """Generate anchors at different levels of a feature pyramid. Each scale
      is associated with a level of the pyramid, but each ratio is used in
      all levels of the pyramid.
  
      from configs:
      :param scales: cf.RPN_ANCHOR_SCALES , e.g. [4, 8, 16, 32]
      :param ratios: cf.RPN_ANCHOR_RATIOS , e.g. [0.5, 1, 2]
      :param feature_shapes: cf.BACKBONE_SHAPES , e.g.  [array of shapes per feature map] [80, 40, 20, 10, 5]
      :param feature_strides: cf.BACKBONE_STRIDES , e.g. [2, 4, 8, 16, 32, 64]
      :param anchors_stride: cf.RPN_ANCHOR_STRIDE , e.g. 1
      :return anchors: (N, (y1, x1, y2, x2, (z1), (z2)). All generated anchors in one array. Sorted
      with the same order of the given scales. So, anchors of scale[0] come first, then anchors of scale[1], and so on.
      """
      scales = cf.rpn_anchor_scales
      ratios = cf.rpn_anchor_ratios
      feature_shapes = cf.backbone_shapes
      anchor_stride = cf.rpn_anchor_stride
      pyramid_levels = cf.pyramid_levels
      feature_strides = cf.backbone_strides
  
      anchors = []
      logger.info("feature map shapes: {}".format(feature_shapes))
      logger.info("anchor scales: {}".format(scales))
  
      expected_anchors = [
          np.prod(feature_shapes[ii])
          * len(ratios)
          * len(scales["xy"][ii])
          for ii in pyramid_levels
      ]
  
      for lix, level in enumerate(pyramid_levels):
          if len(feature_shapes[level]) == 2:
              anchors.append(
                  generate_anchors(
                      scales["xy"][level],
                      ratios,
                      feature_shapes[level],
                      feature_strides["xy"][level],
                      anchor_stride,
                  )
              )
          else:
              anchors.append(
                  generate_anchors_3D(
                      scales["xy"][level],
                      scales["z"][level],
                      ratios,
                      feature_shapes[level],
                      feature_strides["xy"][level],
                      feature_strides["z"][level],
                      anchor_stride,
                  )
              )
  
          logger.info(
              "level {}: built anchors {} / expected anchors {} ||| total build {} / total expected {}".format(
                  level,
                  anchors[-1].shape,
                  expected_anchors[lix],
                  np.concatenate(anchors).shape,
                  np.sum(expected_anchors),
              )
          )
  
      out_anchors = np.concatenate(anchors, axis=0)
      return out_anchors
  
imports: import numpy
  import scipy.misc
  import scipy.ndimage
  import torch
  from torch.autograd import Variable
  import torch.nn
label_desc: Use image node_id 9 for calling a global function with example usage: generate_pyramid_anchors(logger, cf) and returns: out_anchors