class_docstr: Double Head RCNN network.
  
  Parameters
  ----------
  features : gluon.HybridBlock
      Base feature extractor before feature pooling layer.
  top_features : gluon.HybridBlock
      Tail feature extractor after feature pooling layer.
  classes : iterable of str
      Names of categories, its length is ``num_class``.
  box_features : gluon.HybridBlock, default is None
      feature head for transforming shared ROI output (top_features) for box prediction.
      If set to None, global average pooling will be used.
  short : int, default is 600.
      Input image short side size.
  max_size : int, default is 1000.
      Maximum size of input image long side.
  min_stage : int, default is 4
      Minimum stage NO. for FPN stages.
  max_stage : int, default is 4
      Maximum stage NO. for FPN stages.
  train_patterns : str, default is None.
      Matching pattern for trainable parameters.
  nms_thresh : float, default is 0.3.
      Non-maximum suppression threshold. You can specify < 0 or > 1 to disable NMS.
  nms_topk : int, default is 400
      Apply NMS to top k detection results, use -1 to disable so that every Detection
      result is used in NMS.
  roi_mode : str, default is align
      ROI pooling mode. Currently support 'pool' and 'align'.
  roi_size : tuple of int, length 2, default is (14, 14)
      (height, width) of the ROI region.
  strides : int/tuple of ints, default is 16
      Feature map stride with respect to original image.
      This is usually the ratio between original image size and feature map size.
      For FPN, use a tuple of ints.
  clip : float, default is None
      Clip bounding box prediction to to prevent exponentiation from overflowing.
  rpn_channel : int, default is 1024
      number of channels used in RPN convolutional layers.
  base_size : int
      The width(and height) of reference anchor box.
  scales : iterable of float, default is (8, 16, 32)
      The areas of anchor boxes.
      We use the following form to compute the shapes of anchors:
  
      .. math::
  
          width_{anchor} = size_{base} \times scale \times \sqrt{ 1 / ratio}
          height_{anchor} = size_{base} \times scale \times \sqrt{ratio}
  
  ratios : iterable of float, default is (0.5, 1, 2)
      The aspect ratios of anchor boxes. We expect it to be a list or tuple.
  alloc_size : tuple of int
      Allocate size for the anchor boxes as (H, W).
      Usually we generate enough anchors for large feature map, e.g. 128x128.
      Later in inference we can have variable input sizes,
      at which time we can crop corresponding anchors from this large
      anchor map so we can skip re-generating anchors for each input.
  rpn_train_pre_nms : int, default is 12000
      Filter top proposals before NMS in training of RPN.
  rpn_train_post_nms : int, default is 2000
      Return top proposal results after NMS in training of RPN.
      Will be set to rpn_train_pre_nms if it is larger than rpn_train_pre_nms.
  rpn_test_pre_nms : int, default is 6000
      Filter top proposals before NMS in testing of RPN.
  rpn_test_post_nms : int, default is 300
      Return top proposal results after NMS in testing of RPN.
      Will be set to rpn_test_pre_nms if it is larger than rpn_test_pre_nms.
  rpn_nms_thresh : float, default is 0.7
      IOU threshold for NMS. It is used to remove overlapping proposals.
  rpn_num_sample : int, default is 256
      Number of samples for RPN targets.
  rpn_pos_iou_thresh : float, default is 0.7
      Anchor with IOU larger than ``pos_iou_thresh`` is regarded as positive samples.
  rpn_neg_iou_thresh : float, default is 0.3
      Anchor with IOU smaller than ``neg_iou_thresh`` is regarded as negative samples.
      Anchors with IOU in between ``pos_iou_thresh`` and ``neg_iou_thresh`` are
      ignored.
  rpn_pos_ratio : float, default is 0.5
      ``pos_ratio`` defines how many positive samples (``pos_ratio * num_sample``) is
      to be sampled.
  rpn_box_norm : array-like of size 4, default is (1., 1., 1., 1.)
      Std value to be divided from encoded values.
  rpn_min_size : int, default is 16
      Proposals whose size is smaller than ``min_size`` will be discarded.
  per_device_batch_size : int, default is 1
      Batch size for each device during training.
  num_sample : int, default is 128
      Number of samples for RCNN targets.
  pos_iou_thresh : float, default is 0.5
      Proposal whose IOU larger than ``pos_iou_thresh`` is regarded as positive samples.
  pos_ratio : float, default is 0.25
      ``pos_ratio`` defines how many positive samples (``pos_ratio * num_sample``) is
      to be sampled.
  max_num_gt : int, default is 300
      Maximum ground-truth number for each example. This is only an upper bound, not
      necessarily very precise. However, using a very big number may impact the training speed.
  additional_output : boolean, default is False
      ``additional_output`` is only used for Mask R-CNN to get internal outputs.
  force_nms : bool, default is False
      Appy NMS to all categories, this is to avoid overlapping detection results from different
      categories.
  minimal_opset : bool, default is `False`
      We sometimes add special operators to accelerate training/inference, however, for exporting
      to third party compilers we want to utilize most widely used operators.
      If `minimal_opset` is `True`, the network will use a minimal set of operators good
      for e.g., `TVM`.
  
  Attributes
  ----------
  classes : iterable of str
      Names of categories, its length is ``num_class``.
  num_class : int
      Number of positive categories.
  short : int
      Input image short side size.
  max_size : int
      Maximum size of input image long side.
  train_patterns : str
      Matching pattern for trainable parameters.
  nms_thresh : float
      Non-maximum suppression threshold. You can specify < 0 or > 1 to disable NMS.
  nms_topk : int
      Apply NMS to top k detection results, use -1 to disable so that every Detection
       result is used in NMS.
  force_nms : bool
      Appy NMS to all categories, this is to avoid overlapping detection results
      from different categories.
  rpn_target_generator : gluon.Block
      Generate training targets with cls_target, box_target, and box_mask.
  target_generator : gluon.Block
      Generate training targets with boxes, samples, matches, gt_label and gt_box.
class_docstr_tok: ["Double","Head","RCNN","network",".","Parameters","--","--","--","--","--","features",":","gluon.HybridBlock","Base","feature","extractor","before","feature","pooling","layer",".","top_features",":","gluon.HybridBlock","Tail","feature","extractor","after","feature","pooling","layer",".","classes",":","iterable","of","str","Names","of","categories",",","its","length","is","``","num_class","``",".","box_features",":","gluon.HybridBlock",",","default","is","None","feature","head","for","transforming","shared","ROI","output","(","top_features",")","for","box","prediction",".","If","set","to","None",",","global","average","pooling","will","be","used",".","short",":","int",",","default","is","600",".","Input","image","short","side","size",".","max_size",":","int",",","default","is","1000",".","Maximum","size","of","input","image","long","side",".","min_stage",":","int",",","default","is","4","Minimum","stage","NO",".","for","FPN","stages",".","max_stage",":","int",",","default","is","4","Maximum","stage","NO",".","for","FPN","stages",".","train_patterns",":","str",",","default","is","None",".","Matching","pattern","for","trainable","parameters",".","nms_thresh",":","float",",","default","is","0.3",".","Non-maximum","suppression","threshold",".","You","can","specify","<","0","or",">","1","to","disable","NMS",".","nms_topk",":","int",",","default","is","400","Apply","NMS","to","top","k","detection","results",",","use","-1","to","disable","so","that","every","Detection","result","is","used","in","NMS",".","roi_mode",":","str",",","default","is","align","ROI","pooling","mode",".","Currently","support","'pool","'","and","'align","'",".","roi_size",":","tuple","of","int",",","length","2",",","default","is","(","14",",","14",")","(","height",",","width",")","of","the","ROI","region",".","strides",":","int\/tuple","of","ints",",","default","is","16","Feature","map","stride","with","respect","to","original","image",".","This","is","usually","the","ratio","between","original","image","size","and","feature","map","size",".","For","FPN",",","use","a","tuple","of","ints",".","clip",":","float",",","default","is","None","Clip","bounding","box","prediction","to","to","prevent","exponentiation","from","overflowing",".","rpn_channel",":","int",",","default","is","1024","number","of","channels","used","in","RPN","convolutional","layers",".","base_size",":","int","The","width","(","and","height",")","of","reference","anchor","box",".","scales",":","iterable","of","float",",","default","is","(","8",",","16",",","32",")","The","areas","of","anchor","boxes",".","We","use","the","following","form","to","compute","the","shapes","of","anchors",":","..","math",":",":","width_","{","anchor","}","=","size_","{","base","}","\\times","scale","\\times","\\sqrt","{","1","\/","ratio","}","height_","{","anchor","}","=","size_","{","base","}","\\times","scale","\\times","\\sqrt","{","ratio","}","ratios",":","iterable","of","float",",","default","is","(","0.5",",","1",",","2",")","The","aspect","ratios","of","anchor","boxes",".","We","expect","it","to","be","a","list","or","tuple",".","alloc_size",":","tuple","of","int","Allocate","size","for","the","anchor","boxes","as","(","H",",","W",")",".","Usually","we","generate","enough","anchors","for","large","feature","map",",","e.g",".","128x128",".","Later","in","inference","we","can","have","variable","input","sizes",",","at","which","time","we","can","crop","corresponding","anchors","from","this","large","anchor","map","so","we","can","skip","re-generating","anchors","for","each","input",".","rpn_train_pre_nms",":","int",",","default","is","12000","Filter","top","proposals","before","NMS","in","training","of","RPN",".","rpn_train_post_nms",":","int",",","default","is","2000","Return","top","proposal","results","after","NMS","in","training","of","RPN",".","Will","be","set","to","rpn_train_pre_nms","if","it","is","larger","than","rpn_train_pre_nms",".","rpn_test_pre_nms",":","int",",","default","is","6000","Filter","top","proposals","before","NMS","in","testing","of","RPN",".","rpn_test_post_nms",":","int",",","default","is","300","Return","top","proposal","results","after","NMS","in","testing","of","RPN",".","Will","be","set","to","rpn_test_pre_nms","if","it","is","larger","than","rpn_test_pre_nms",".","rpn_nms_thresh",":","float",",","default","is","0.7","IOU","threshold","for","NMS",".","It","is","used","to","remove","overlapping","proposals",".","rpn_num_sample",":","int",",","default","is","256","Number","of","samples","for","RPN","targets",".","rpn_pos_iou_thresh",":","float",",","default","is","0.7","Anchor","with","IOU","larger","than","``","pos_iou_thresh","``","is","regarded","as","positive","samples",".","rpn_neg_iou_thresh",":","float",",","default","is","0.3","Anchor","with","IOU","smaller","than","``","neg_iou_thresh","``","is","regarded","as","negative","samples",".","Anchors","with","IOU","in","between","``","pos_iou_thresh","``","and","``","neg_iou_thresh","``","are","ignored",".","rpn_pos_ratio",":","float",",","default","is","0.5","``","pos_ratio","``","defines","how","many","positive","samples","(","``","pos_ratio","*","num_sample","``",")","is","to","be","sampled",".","rpn_box_norm",":","array-like","of","size","4",",","default","is","(","1.",",","1.",",","1.",",","1",".",")","Std","value","to","be","divided","from","encoded","values",".","rpn_min_size",":","int",",","default","is","16","Proposals","whose","size","is","smaller","than","``","min_size","``","will","be","discarded",".","per_device_batch_size",":","int",",","default","is","1","Batch","size","for","each","device","during","training",".","num_sample",":","int",",","default","is","128","Number","of","samples","for","RCNN","targets",".","pos_iou_thresh",":","float",",","default","is","0.5","Proposal","whose","IOU","larger","than","``","pos_iou_thresh","``","is","regarded","as","positive","samples",".","pos_ratio",":","float",",","default","is","0.25","``","pos_ratio","``","defines","how","many","positive","samples","(","``","pos_ratio","*","num_sample","``",")","is","to","be","sampled",".","max_num_gt",":","int",",","default","is","300","Maximum","ground-truth","number","for","each","example",".","This","is","only","an","upper","bound",",","not","necessarily","very","precise",".","However",",","using","a","very","big","number","may","impact","the","training","speed",".","additional_output",":","boolean",",","default","is","False","``","additional_output","``","is","only","used","for","Mask","R-CNN","to","get","internal","outputs",".","force_nms",":","bool",",","default","is","False","Appy","NMS","to","all","categories",",","this","is","to","avoid","overlapping","detection","results","from","different","categories",".","minimal_opset",":","bool",",","default","is","`","False","`","We","sometimes","add","special","operators","to","accelerate","training\/inference",",","however",",","for","exporting","to","third","party","compilers","we","want","to","utilize","most","widely","used","operators",".","If","`","minimal_opset","`","is","`","True","`",",","the","network","will","use","a","minimal","set","of","operators","good","for","e.g.",",","`","TVM","`",".","Attributes","--","--","--","--","--","classes",":","iterable","of","str","Names","of","categories",",","its","length","is","``","num_class","``",".","num_class",":","int","Number","of","positive","categories",".","short",":","int","Input","image","short","side","size",".","max_size",":","int","Maximum","size","of","input","image","long","side",".","train_patterns",":","str","Matching","pattern","for","trainable","parameters",".","nms_thresh",":","float","Non-maximum","suppression","threshold",".","You","can","specify","<","0","or",">","1","to","disable","NMS",".","nms_topk",":","int","Apply","NMS","to","top","k","detection","results",",","use","-1","to","disable","so","that","every","Detection","result","is","used","in","NMS",".","force_nms",":","bool","Appy","NMS","to","all","categories",",","this","is","to","avoid","overlapping","detection","results","from","different","categories",".","rpn_target_generator",":","gluon.Block","Generate","training","targets","with","cls_target",",","box_target",",","and","box_mask",".","target_generator",":","gluon.Block","Generate","training","targets","with","boxes",",","samples",",","matches",",","gt_label","and","gt_box","."]
code: def __init__(
      self,
      features,
      top_features,
      classes,
      box_features=None,
      short=600,
      max_size=1000,
      min_stage=4,
      max_stage=4,
      train_patterns=None,
      nms_thresh=0.3,
      nms_topk=400,
      post_nms=100,
      roi_mode="align",
      roi_size=(14, 14),
      strides=16,
      clip=None,
      rpn_channel=1024,
      base_size=16,
      scales=(8, 16, 32),
      ratios=(0.5, 1, 2),
      alloc_size=(128, 128),
      rpn_nms_thresh=0.7,
      rpn_train_pre_nms=12000,
      rpn_train_post_nms=2000,
      rpn_test_pre_nms=6000,
      rpn_test_post_nms=300,
      rpn_min_size=16,
      per_device_batch_size=1,
      num_sample=128,
      pos_iou_thresh=0.5,
      pos_ratio=0.25,
      max_num_gt=300,
      additional_output=False,
      force_nms=False,
      minimal_opset=False,
      **kwargs,
  ):
      super(DoubleHeadRCNN, self).__init__(
          features=features,
          top_features=top_features,
          classes=classes,
          box_features=box_features,
          short=short,
          max_size=max_size,
          train_patterns=train_patterns,
          nms_thresh=nms_thresh,
          nms_topk=nms_topk,
          post_nms=post_nms,
          roi_mode=roi_mode,
          roi_size=roi_size,
          strides=strides,
          clip=clip,
          force_nms=force_nms,
          minimal_opset=minimal_opset,
          **kwargs,
      )
      if max_stage - min_stage > 1 and isinstance(
          strides, (int, float)
      ):
          raise ValueError(
              "Multi level detected but strides is of a single number:",
              strides,
          )
  
      if rpn_train_post_nms > rpn_train_pre_nms:
          rpn_train_post_nms = rpn_train_pre_nms
      if rpn_test_post_nms > rpn_test_pre_nms:
          rpn_test_post_nms = rpn_test_pre_nms
  
      self.ashape = alloc_size[0]
      self._min_stage = min_stage
      self._max_stage = max_stage
      self.num_stages = max_stage - min_stage + 1
      if self.num_stages > 1:
          assert len(scales) == len(strides) == self.num_stages, (
              "The num_stages (%d) must match number of scales (%d) and strides (%d)"
              % (self.num_stages, len(scales), len(strides))
          )
      self._batch_size = per_device_batch_size
      self._num_sample = num_sample
      self._rpn_test_post_nms = rpn_test_post_nms
      if minimal_opset:
          self._target_generator = None
      else:
          self._target_generator = lambda: RCNNTargetGenerator(
              self.num_class,
              int(num_sample * pos_ratio),
              self._batch_size,
          )
  
      self._additional_output = additional_output
      with self.name_scope():
          self.rpn = RPN(
              channels=rpn_channel,
              strides=strides,
              base_size=base_size,
              scales=scales,
              ratios=ratios,
              alloc_size=alloc_size,
              clip=clip,
              nms_thresh=rpn_nms_thresh,
              train_pre_nms=rpn_train_pre_nms,
              train_post_nms=rpn_train_post_nms,
              test_pre_nms=rpn_test_pre_nms,
              test_post_nms=rpn_test_post_nms,
              min_size=rpn_min_size,
              multi_level=self.num_stages > 1,
              per_level_nms=False,
              minimal_opset=minimal_opset,
          )
          self.sampler = RCNNTargetSampler(
              num_image=self._batch_size,
              num_proposal=rpn_train_post_nms,
              num_sample=num_sample,
              pos_iou_thresh=pos_iou_thresh,
              pos_ratio=pos_ratio,
              max_num_gt=max_num_gt,
          )
          # double head branch with class and box
          self.class_features = nn.HybridSequential(prefix="double_fc_")
          with self.class_features.name_scope():
              for _ in range(2):
                  self.class_features.add(
                      nn.Dense(
                          1024, weight_initializer=mx.init.Normal(0.01)
                      )
                  )
                  self.class_features.add(nn.Activation("relu"))
  
          self.newbox_features = nn.HybridSequential(prefix="double_")
          with self.newbox_features.name_scope():
              for _ in range(2):
                  self.newbox_features.add(
                      BottleneckV1(channels=1024, stride=1)
                  )
  
imports: from __future__ import absolute_import
  import os
  import mxnet
  from mxnet import autograd
  from mxnet.gluon import nn
  from mxnet.gluon.contrib.nn import SyncBatchNorm
  from mxnet.gluon.nn import BatchNorm
  from mxnet.gluon.block import HybridBlock
  from .rcnn_target import RCNNTargetSampler, RCNNTargetGenerator
  from ..rcnn import custom_rcnn_fpn
  from ....model_zoo.rcnn import RCNN
  from ....model_zoo.rcnn.rpn import RPN
label_desc: Use image node_id 1 to create a new DoubleHeadRCNN object from inherited base classes: RCNN with example: obj = DoubleHeadRCNN(features, top_features, classes, box_features, short, max_size, min_stage, max_stage, train_patterns, nms_thresh, nms_topk, post_nms, roi_mode, roi_size, strides, clip, rpn_channel, base_size, scales, ratios, alloc_size, rpn_nms_thresh, rpn_train_pre_nms, rpn_train_post_nms, rpn_test_pre_nms, rpn_test_post_nms, rpn_min_size, per_device_batch_size, num_sample, pos_iou_thresh, pos_ratio, max_num_gt, additional_output, force_nms, minimal_opset)