class_docstr: A sampler implementing Online Hard-negative mining.
  As described in paper https://arxiv.org/abs/1604.03540.
  
  Parameters
  ----------
  ratio : float
      Ratio of negative vs. positive samples. Values >= 1.0 is recommended.
  min_samples : int, default 0
      Minimum samples to be selected regardless of positive samples.
      For example, if positive samples is 0, we sometimes still want some num_negative
      samples to be selected.
  thresh : float, default 0.5
      IOU overlap threshold of selected negative samples. IOU must not exceed
      this threshold such that good matching anchors won't be selected as
      negative samples.
class_docstr_tok: ["A","sampler","implementing","Online","Hard-negative","mining",".","As","described","in","paper","https",":","\/\/arxiv.org\/abs\/1604.03540",".","Parameters","--","--","--","--","--","ratio",":","float","Ratio","of","negative","vs.","positive","samples",".","Values",">","=","1.0","is","recommended",".","min_samples",":","int",",","default","0","Minimum","samples","to","be","selected","regardless","of","positive","samples",".","For","example",",","if","positive","samples","is","0",",","we","sometimes","still","want","some","num_negative","samples","to","be","selected",".","thresh",":","float",",","default","0.5","IOU","overlap","threshold","of","selected","negative","samples",".","IOU","must","not","exceed","this","threshold","such","that","good","matching","anchors","wo","n't","be","selected","as","negative","samples","."]
docstr: Forward
docstr_tok: ["Forward"]
code: def forward(self, x, logits, ious):
      """Forward"""
      F = nd
      num_positive = F.sum(x > -1, axis=1)
      num_negative = self._ratio * num_positive
      num_total = x.shape[1]  # scalar
      num_negative = F.minimum(
          F.maximum(self._min_samples, num_negative),
          num_total - num_positive,
      )
      positive = logits.slice_axis(axis=2, begin=1, end=None)
      background = logits.slice_axis(axis=2, begin=0, end=1).reshape(
          (0, -1)
      )
      maxval = positive.max(axis=2)
      esum = F.exp(logits - maxval.reshape((0, 0, 1))).sum(axis=2)
      score = -F.log(F.exp(background - maxval) / esum)
      mask = F.ones_like(score) * -1
      score = F.where(x < 0, score, mask)  # mask out positive samples
      if len(ious.shape) == 3:
          ious = F.max(ious, axis=2)
      score = F.where(
          ious < self._thresh, score, mask
      )  # mask out if iou is large
      argmaxs = F.argsort(score, axis=1, is_ascend=False)
  
      # neg number is different in each batch, using dynamic numpy operations.
      y = np.zeros(x.shape)
      y[np.where(x.asnumpy() >= 0)] = 1  # assign positive samples
      argmaxs = argmaxs.asnumpy()
      for i, num_neg in zip(
          range(x.shape[0]), num_negative.asnumpy().astype(np.int32)
      ):
          indices = argmaxs[i, :num_neg]
          y[i, indices.astype(np.int32)] = -1  # assign negative samples
      return F.array(y, ctx=x.context)
  
imports: from __future__ import absolute_import
  import numpy
  import mxnet
  from mxnet import gluon, nd
label_desc: Use image node_id 2 for calling the OHEMSampler obj's underlying member method code with example usage: obj.forward(x, logits, ious) and returns: F