def match_anchor_to_bbox(ground_truth, anchors, device, iou_threshold=0.5): """Assign ground-truth bounding boxes to anchor boxes similar to them.""" num_anchors, num_gt_boxes = anchors.shape[0], ground_truth.shape[0] # Element `x_ij` in the `i^th` row and `j^th` column is the IoU # of the anchor box `anc_i` to the ground-truth bounding box `box_j` jaccard = box_iou(anchors, ground_truth) # Initialize the tensor to hold assigned ground truth bbox for each anchor anchors_bbox_map = np.full((num_anchors, ), fill_value=-1, dtype=np.int32, ctx=device) # Assign ground truth bounding box according to the threshold max_ious, indices = np.max(jaccard, axis=1), np.argmax(jaccard, axis=1) anc_i = np.nonzero(max_ious >= iou_threshold)[0] box_j = indices[max_ious >= iou_threshold] anchors_bbox_map[anc_i] = box_j # Find the largest iou for each bbox col_discard = np.full((num_anchors, ), -1) row_discard = np.full((num_gt_boxes, ), -1) for _ in range(num_gt_boxes): max_idx = np.argmax(jaccard) box_idx = (max_idx % num_gt_boxes).astype('int32') anc_idx = (max_idx / num_gt_boxes).astype('int32') anchors_bbox_map[anc_idx] = box_idx jaccard[:, box_idx] = col_discard jaccard[anc_idx, :] = row_discard return anchors_bbox_map
def gumbel_softmax(logits, temperature: float = 1.0, eps: float = 1E-10, hard=True, use_np_gumbel: bool = True): r"""Perform the gumbel-softmax trick to generate differentiable one-hot vectors from the input logits. Here, the gumbel distribution is Gumbel(\alpha) = -log (-log U) + \log \alpha, in which U is the uniform(0, 1) distribution. A nice property of Gumbel is: \argmax({Gumbel(\alpha_i)}) \sim multinomial(\alpha_i) The Gumbel-Softmax trick is to use the softmax + straight-through estimator to produce one-hot vectors that represent the sampling result. References: 1. https://en.wikipedia.org/wiki/Gumbel_distribution 2. [ICLR2017] Categorical Reparameterization with Gumbel-Softmax Parameters ---------- logits Logits. Shape (..., V) temperature The temperature that controls the eps The eps for stability of gradient hard Whether to use the straight-through estimator to produce one-hot vectors. use_np_gumbel Whether to use the random.gumble operator Returns ------- ret The returned output. Shape (..., V) """ # TODO(sxjscience) Investigate the impact of random.gumbel: # Actually, random.gumble has no eps and may have problem in calculating the gradient. if use_np_gumbel: gumbels = np.random.gumbel(np.zeros_like(logits)) else: u = np.random.uniform(np.zeros_like(logits), 1) gumbels = -np.log(-np.log(u + eps) + eps) y = npx.softmax((gumbels + logits) / temperature, axis=-1) if hard: y_hard = np.max(y, axis=-1, keepdims=True) == y y_hard = npx.stop_gradient(y_hard - y) + y return y_hard else: return y
def pool2d(X, pool, mode): p_h, p_w = pool.shape Y = np.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1)) for i in range(Y.shape[0]): for j in range(Y.shape[1]): if mode == 'max': Y[i, j] = np.max(X[i:i + p_h, j:j + p_w]) elif mode == 'avg': Y[i, j] = X[i:i + p_h, j:j + p_w].mean() return Y
def test_contrib_intgemm_maxabsolute(shape): if "intgemm_maxabsolute" not in dir(mx.nd.contrib): return # mx.nd API m = mx.nd.random_uniform(low=-100.0, high=100.0, shape=shape) fast = mx.nd.contrib.intgemm_maxabsolute(m) slow = mx.nd.max(mx.nd.abs(m)) assert same(fast, slow) # np API m = np.random.uniform(low=-100.0, high=100.0, size=shape) fast = npx.intgemm_maxabsolute(m).reshape(()) slow = np.max(np.abs(m)) assert same(fast, slow)
def multibox_detection(cls_probs, offset_preds, anchors, nms_threshold=0.5, pos_threshold=0.00999999978): device, batch_size = cls_probs.ctx, cls_probs.shape[0] anchors = np.squeeze(anchors, axis=0) num_classes, num_anchors = cls_probs.shape[1], cls_probs.shape[2] out = [] # print(offset_preds) for i in range(batch_size): cls_prob, offset_pred = cls_probs[i], offset_preds[i].reshape(-1, 4) conf, class_id = np.max(cls_prob[1:], 0), np.argmax(cls_prob[1:], 0) predicted_bb = offset_inverse(anchors, offset_pred) keep = nms(predicted_bb, conf, 0.5) print(keep) # Find all non_keep indices and set the class_id to background all_idx = np.arange(num_anchors, dtype=np.int32, ctx=device) combined = np.concatenate((keep, all_idx)) unique, counts = np.unique(combined, return_counts=True) print(unique, " . ", counts) non_keep = unique[counts == 1] all_id_sorted = np.concatenate((keep, non_keep)) class_id[non_keep] = -1 print(class_id) class_id = class_id[all_id_sorted].astype('float32') print(class_id) conf, predicted_bb = conf[all_id_sorted], predicted_bb[all_id_sorted] print(conf) print(predicted_bb) # threshold to be a positive prediction below_min_idx = (conf < pos_threshold) class_id[below_min_idx] = -1 conf[below_min_idx] = 1 - conf[below_min_idx] pred_info = np.concatenate((np.expand_dims( class_id, axis=1), np.expand_dims(conf, axis=1), predicted_bb), axis=1) out.append(pred_info) return np.stack(out)
def softmax(y_hat): exps = np.exp(y_hat - np.max(y_hat, axis=1, keepdims=True)) return exps / np.sum(exps, axis=1, keepdims=True)