code: # encoding: utf-8
  from libs.configs import cfgs
  from libs.box_utils import bbox_transform
  from libs.box_utils import nms_rotate
  import tensorflow as tf
  import numpy as np
  
  from libs.box_utils.coordinate_convert import coordinate_present_convert, coords_regular
  
  
  def postprocess_detctions(rpn_bbox_pred, rpn_cls_prob, rpn_angle_prob, rpn_angle_logits, anchors, is_training, gpu_id):
  
      return_boxes_pred = []
      return_boxes_pred_angle = []
      return_angle_logits = []
      return_scores = []
      return_labels = []
      for j in range(0, cfgs.CLASS_NUM):
          scores = rpn_cls_prob[:, j]
          if is_training:
              indices = tf.reshape(tf.where(tf.greater(scores, cfgs.VIS_SCORE)), [-1, ])
          else:
              indices = tf.reshape(tf.where(tf.greater(scores, cfgs.FILTERED_SCORE)), [-1, ])
  
          anchors_ = tf.gather(anchors, indices)
          rpn_bbox_pred_ = tf.gather(rpn_bbox_pred, indices)
          scores = tf.gather(scores, indices)
          rpn_angle_prob_ = tf.gather(rpn_angle_prob, indices)
          rpn_angle_logits_ = tf.gather(rpn_angle_logits, indices)
  
          angle_cls = tf.cast(tf.argmax(rpn_angle_prob_, axis=1), tf.float32)
  
          if cfgs.METHOD == 'H':
              x_c = (anchors_[:, 2] + anchors_[:, 0]) / 2
              y_c = (anchors_[:, 3] + anchors_[:, 1]) / 2
              h = anchors_[:, 2] - anchors_[:, 0] + 1
              w = anchors_[:, 3] - anchors_[:, 1] + 1
              theta = -90 * tf.ones_like(x_c)
              anchors_ = tf.transpose(tf.stack([x_c, y_c, w, h, theta]))
  
          if cfgs.ANGLE_RANGE == 180:
              anchors_ = tf.py_func(coordinate_present_convert,
                                    inp=[anchors_, -1],
                                    Tout=[tf.float32])
              anchors_ = tf.reshape(anchors_, [-1, 5])
  
          boxes_pred = bbox_transform.rbbox_transform_inv(boxes=anchors_, deltas=rpn_bbox_pred_)
  
          boxes_pred = tf.reshape(boxes_pred, [-1, 5])
          angle_cls = (tf.reshape(angle_cls, [-1, ]) * -1 - 0.5) * cfgs.OMEGA
  
          x, y, w, h, theta = tf.unstack(boxes_pred, axis=1)
          boxes_pred_angle = tf.transpose(tf.stack([x, y, w, h, angle_cls]))
  
          if cfgs.ANGLE_RANGE == 180:
  
              # _, _, _, _, theta = tf.unstack(boxes_pred, axis=1)
              # indx = tf.reshape(tf.where(tf.logical_and(tf.less(theta, 0), tf.greater_equal(theta, -180))), [-1, ])
              # boxes_pred = tf.gather(boxes_pred, indx)
              # scores = tf.gather(scores, indx)
  
              boxes_pred = tf.py_func(coordinate_present_convert,
                                      inp=[boxes_pred, 1],
                                      Tout=[tf.float32])
              boxes_pred = tf.reshape(boxes_pred, [-1, 5])
  
              boxes_pred_angle = tf.py_func(coordinate_present_convert,
                                            inp=[boxes_pred_angle, 1],
                                            Tout=[tf.float32])
              boxes_pred_angle = tf.reshape(boxes_pred_angle, [-1, 5])
  
          max_output_size = 4000 if 'DOTA' in cfgs.NET_NAME else 200
          nms_indices = nms_rotate.nms_rotate(decode_boxes=boxes_pred_angle,
                                              scores=scores,
                                              iou_threshold=cfgs.NMS_IOU_THRESHOLD,
                                              max_output_size=100 if is_training else max_output_size,
                                              use_angle_condition=False,
                                              angle_threshold=15,
                                              use_gpu=True,
                                              gpu_id=gpu_id)
  
          tmp_boxes_pred = tf.reshape(tf.gather(boxes_pred, nms_indices), [-1, 5])
          tmp_boxes_pred_angle = tf.reshape(tf.gather(boxes_pred_angle, nms_indices), [-1, 5])
          tmp_scores = tf.reshape(tf.gather(scores, nms_indices), [-1, ])
          tmp_rpn_angle_logits = tf.gather(rpn_angle_logits_, nms_indices)
  
          return_boxes_pred.append(tmp_boxes_pred)
          return_boxes_pred_angle.append(tmp_boxes_pred_angle)
          return_scores.append(tmp_scores)
          return_labels.append(tf.ones_like(tmp_scores)*(j+1))
          return_angle_logits.append(tmp_rpn_angle_logits)
  
      return_boxes_pred = tf.concat(return_boxes_pred, axis=0)
      return_boxes_pred_angle = tf.concat(return_boxes_pred_angle, axis=0)
      return_scores = tf.concat(return_scores, axis=0)
      return_labels = tf.concat(return_labels, axis=0)
      return_angle_logits = tf.concat(return_angle_logits, axis=0)
  
      return return_boxes_pred, return_scores, return_labels, return_boxes_pred_angle, return_angle_logits
   # -*- coding: utf-8 -*-
  from __future__ import division, print_function, absolute_import
  import os
  import tensorflow as tf
  import math
  
  """
  BCL + OMEGA = 180 / 32. + data aug + ms
  FLOPs: 1321979063;    Trainable params: 52136440
  
  This is your result for task 1:
  
      mAP: 0.7197849386403127
      ap of each class:
      plane:0.888767706661227,
      baseball-diamond:0.828813250009659,
      bridge:0.4680099872101205,
      ground-track-field:0.6901660404277621,
      small-vehicle:0.7395262726408154,
      large-vehicle:0.5667009043812319,
      ship:0.7347841545028257,
      tennis-court:0.9071577005837769,
      basketball-court:0.8229722946512178,
      storage-tank:0.8448119293093586,
      soccer-ball-field:0.6186025857112213,
      roundabout:0.6441106031308795,
      harbor:0.628617739475033,
      swimming-pool:0.7122314212831211,
      helicopter:0.7015014896264388
  
  The submitted information is :
  
  Description: RetinaNet_DOTA_DCL_B_3x_20200923_145.8w
  
  
  This is your result for task 1:
  
      mAP: 0.7301021435398962
      ap of each class:
      plane:0.8770187842801944,
      baseball-diamond:0.8267941412496465,
      bridge:0.5127762497195772,
      ground-track-field:0.7429087472658292,
      small-vehicle:0.7430367724213736,
      large-vehicle:0.5717593529976157,
      ship:0.7535736625119606,
      tennis-court:0.9066598303041958,
      basketball-court:0.8420467411496289,
      storage-tank:0.85672175425764,
      soccer-ball-field:0.6380583684613818,
      roundabout:0.653533415863242,
      harbor:0.6392204165860068,
      swimming-pool:0.7104658633500178,
      helicopter:0.676958052680133
  
  The submitted information is :
  
  Description: RetinaNet_DOTA_DCL_B_3x_20200923_ms_145.8w
  
  """
  
  # ------------------------------------------------
  VERSION = 'RetinaNet_DOTA_DCL_B_3x_20200923'
  NET_NAME = 'resnet101_v1d'  # 'MobilenetV2'
  ADD_BOX_IN_TENSORBOARD = True
  
  # ---------------------------------------- System_config
  ROOT_PATH = os.path.abspath('../')
  print(20*"++--")
  print(ROOT_PATH)
  GPU_GROUP = "0,1,2"
  NUM_GPU = len(GPU_GROUP.strip().split(','))
  SHOW_TRAIN_INFO_INTE = 20
  SMRY_ITER = 2000
  SAVE_WEIGHTS_INTE = 27000 * 3
  
  SUMMARY_PATH = ROOT_PATH + '/output/summary'
  TEST_SAVE_PATH = ROOT_PATH + '/tools/test_result'
  
  if NET_NAME.startswith("resnet"):
      weights_name = NET_NAME
  elif NET_NAME.startswith("MobilenetV2"):
      weights_name = "mobilenet/mobilenet_v2_1.0_224"
  else:
      raise Exception('net name must in [resnet_v1_101, resnet_v1_50, MobilenetV2]')
  
  PRETRAINED_CKPT = ROOT_PATH + '/data/pretrained_weights/' + weights_name + '.ckpt'
  TRAINED_CKPT = os.path.join(ROOT_PATH, 'output/trained_weights')
  EVALUATE_DIR = ROOT_PATH + '/output/evaluate_result_pickle/'
  
  # ------------------------------------------ Train config
  RESTORE_FROM_RPN = False
  FIXED_BLOCKS = 1  # allow 0~3
  FREEZE_BLOCKS = [True, False, False, False, False]  # for gluoncv backbone
  USE_07_METRIC = True
  
  MUTILPY_BIAS_GRADIENT = 2.0  # if None, will not multipy
  GRADIENT_CLIPPING_BY_NORM = 10.0  # if None, will not clip
  
  CLS_WEIGHT = 1.0
  REG_WEIGHT = 1.0
  ANGLE_WEIGHT = 0.5
  REG_LOSS_MODE = None
  ALPHA = 1.0
  BETA = 1.0
  
  BATCH_SIZE = 1
  EPSILON = 1e-5
  MOMENTUM = 0.9
  LR = 5e-4
  DECAY_STEP = [SAVE_WEIGHTS_INTE*12, SAVE_WEIGHTS_INTE*16, SAVE_WEIGHTS_INTE*20]
  MAX_ITERATION = SAVE_WEIGHTS_INTE*20
  WARM_SETP = int(1.0 / 4.0 * SAVE_WEIGHTS_INTE)
  
  # -------------------------------------------- Data_preprocess_config
  DATASET_NAME = 'DOTA'  # 'pascal', 'coco'
  PIXEL_MEAN = [123.68, 116.779, 103.939]  # R, G, B. In tf, channel is RGB. In openCV, channel is BGR
  PIXEL_MEAN_ = [0.485, 0.456, 0.406]
  PIXEL_STD = [0.229, 0.224, 0.225]  # R, G, B. In tf, channel is RGB. In openCV, channel is BGR
  IMG_SHORT_SIDE_LEN = [800, 400, 600, 1000, 1200]
  IMG_MAX_LENGTH = 1200
  CLASS_NUM = 15
  OMEGA = 180 / 32.
  ANGLE_MODE = 0
  
  IMG_ROTATE = True
  RGB2GRAY = True
  VERTICAL_FLIP = True
  HORIZONTAL_FLIP = True
  IMAGE_PYRAMID = True
  
  # --------------------------------------------- Network_config
  SUBNETS_WEIGHTS_INITIALIZER = tf.random_normal_initializer(mean=0.0, stddev=0.01, seed=None)
  SUBNETS_BIAS_INITIALIZER = tf.constant_initializer(value=0.0)
  PROBABILITY = 0.01
  FINAL_CONV_BIAS_INITIALIZER = tf.constant_initializer(value=-math.log((1.0 - PROBABILITY) / PROBABILITY))
  WEIGHT_DECAY = 1e-4
  USE_GN = False
  FPN_CHANNEL = 256
  
  # ---------------------------------------------Anchor config
  LEVEL = ['P3', 'P4', 'P5', 'P6', 'P7']
  BASE_ANCHOR_SIZE_LIST = [32, 64, 128, 256, 512]
  ANCHOR_STRIDE = [8, 16, 32, 64, 128]
  ANCHOR_SCALES = [2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)]
  ANCHOR_RATIOS = [1, 1 / 2, 2., 1 / 3., 3., 5., 1 / 5.]
  ANCHOR_ANGLES = [-90, -75, -60, -45, -30, -15]
  ANCHOR_SCALE_FACTORS = None
  USE_CENTER_OFFSET = True
  METHOD = 'H'
  USE_ANGLE_COND = False
  ANGLE_RANGE = 180  # 90 or 180
  
  # --------------------------------------------RPN config
  SHARE_NET = True
  USE_P5 = True
  IOU_POSITIVE_THRESHOLD = 0.5
  IOU_NEGATIVE_THRESHOLD = 0.4
  
  NMS = True
  NMS_IOU_THRESHOLD = 0.1
  MAXIMUM_DETECTIONS = 100
  FILTERED_SCORE = 0.05
  VIS_SCORE = 0.4
  
  
  
apis: tensorflow.stack tensorflow.reshape tensorflow.unstack tensorflow.ones_like tensorflow.greater tensorflow.argmax tensorflow.concat tensorflow.gather tensorflow.py_func
apis: tensorflow.random_normal_initializer tensorflow.constant_initializer