class_docstr: Feature extractor with additional layers to append.
  This is very common in vision networks where extra branches are attached to
  backbone network.
  
  Parameters
  ----------
  network : str or HybridBlock or Symbol
      Logic chain: load from gluoncv.model_zoo if network is string.
      Convert to Symbol if network is HybridBlock.
  outputs : str or list of str
      The name of layers to be extracted as features
  num_filters : list of int
      Number of filters to be appended.
  use_1x1_transition : bool
      Whether to use 1x1 convolution between attached layers. It is effective
      reducing network size.
  use_bn : bool
      Whether to use BatchNorm between attached layers.
  reduce_ratio : float
      Channel reduction ratio of the transition layers.
  min_depth : int
      Minimum channel number of transition layers.
  global_pool : bool
      Whether to use global pooling as the last layer.
  pretrained : bool
      Use pretrained parameters as in gluon.model_zoo if `True`.
  ctx : Context
      The context, e.g. mxnet.cpu(), mxnet.gpu(0).
  inputs : list of str
      Name of input variables to the network.
code: def __init__(
      self,
      network,
      outputs,
      num_filters,
      use_1x1_transition=True,
      use_bn=True,
      reduce_ratio=1.0,
      min_depth=128,
      global_pool=False,
      pretrained=False,
      ctx=mx.cpu(),
      inputs=("data",),
      **kwargs,
  ):
      inputs, outputs, params = _parse_network(
          network, outputs, inputs, pretrained, ctx, **kwargs
      )
      # append more layers
      y = outputs[-1]
      weight_init = mx.init.Xavier(
          rnd_type="gaussian", factor_type="out", magnitude=2
      )
      for i, f in enumerate(num_filters):
          if use_1x1_transition:
              num_trans = max(min_depth, int(round(f * reduce_ratio)))
              y = mx.sym.Convolution(
                  y,
                  num_filter=num_trans,
                  kernel=(1, 1),
                  no_bias=use_bn,
                  name="expand_trans_conv{}".format(i),
                  attr={"__init__": weight_init},
              )
              if use_bn:
                  y = mx.sym.BatchNorm(
                      y, name="expand_trans_bn{}".format(i)
                  )
              y = mx.sym.Activation(
                  y,
                  act_type="relu",
                  name="expand_trans_relu{}".format(i),
              )
          y = mx.sym.Convolution(
              y,
              num_filter=f,
              kernel=(3, 3),
              pad=(1, 1),
              stride=(2, 2),
              no_bias=use_bn,
              name="expand_conv{}".format(i),
              attr={"__init__": weight_init},
          )
          if use_bn:
              y = mx.sym.BatchNorm(y, name="expand_bn{}".format(i))
          y = mx.sym.Activation(
              y, act_type="relu", name="expand_relu{}".format(i)
          )
          outputs.append(y)
      if global_pool:
          outputs.append(
              mx.sym.Pooling(
                  y, pool_type="avg", global_pool=True, kernel=(1, 1)
              )
          )
      super(FeatureExpander, self).__init__(outputs, inputs, params)
  
file_path: gluon-cv/gluoncv/nn/feature.py
imports: from __future__ import absolute_import
  import mxnet
  from mxnet.base import string_types
  from mxnet.gluon import HybridBlock, SymbolBlock
  from mxnet.symbol import Symbol
  from mxnet.symbol.contrib import SyncBatchNorm
label_desc: Use image node_id 1 to create a new FeatureExpander object from inherited base classes: SymbolBlock with example: obj = FeatureExpander(network, outputs, num_filters, use_1x1_transition, use_bn, reduce_ratio, min_depth, global_pool, pretrained, ctx, inputs)