def match_box_with_gt(self, boxes, iou_threshold): """ Args: boxes: Nx4 Returns: BoxProposals """ if self.is_training: with tf.name_scope('match_box_with_gt_{}'.format(iou_threshold)): iou = pairwise_iou( boxes, self.gt_boxes) # NxM # gt_boxes from datasets max_iou_per_box = tf.reduce_max( iou, axis=1) # N # contain many zeros best_iou_ind = tf.argmax( iou, axis=1 ) # N # if all value is zeros,return the first indices labels_per_box = tf.gather(self.gt_labels, best_iou_ind) fg_mask = max_iou_per_box >= iou_threshold fg_inds_wrt_gt = tf.boolean_mask( best_iou_ind, fg_mask) # fg_boxes but not gt_boxes labels_per_box = tf.stop_gradient(labels_per_box * tf.to_int64(fg_mask)) return BoxProposals(boxes, labels_per_box, fg_inds_wrt_gt, self.gt_boxes, self.gt_labels) else: return BoxProposals(boxes)
def match_box_with_gt(self, boxes, iou_threshold): """ Args: boxes: Nx4 Returns: BoxProposals """ if self.is_training: with tf.name_scope('match_box_with_gt_{}'.format(iou_threshold)): iou = pairwise_iou(boxes, self.gt_boxes) # NxM max_iou_per_box = tf.reduce_max(iou, axis=1) # N best_iou_ind = tf.argmax(iou, axis=1) # N labels_per_box = tf.gather(self.gt_labels, best_iou_ind) fg_mask = max_iou_per_box >= iou_threshold fg_inds_wrt_gt = tf.boolean_mask(best_iou_ind, fg_mask) labels_per_box = tf.stop_gradient(labels_per_box * tf.to_int64(fg_mask)) return BoxProposals(boxes, labels_per_box, fg_inds_wrt_gt, self.gt_boxes, self.gt_labels) else: return BoxProposals(boxes)
def sample_fast_rcnn_targets(boxes, gt_boxes, gt_labels): """ Sample some ROIs from all proposals for training. #fg is guaranteed to be > 0, because grount truth boxes are added as RoIs. Args: boxes: nx4 region proposals, floatbox gt_boxes: mx4, floatbox ,from datasets gt_labels: m, int32 ,from datasets Returns: A BoxProposals instance. sampled_boxes: tx4 floatbox, the rois sampled_labels: t int64 labels, in [0, #class). Positive means foreground. fg_inds_wrt_gt: #fg indices, each in range [0, m-1]. It contains the matching GT of each foreground roi. """ iou = pairwise_iou(boxes, gt_boxes) # nxm proposal_metrics(iou) # add ground truth as proposals as well boxes = tf.concat([boxes, gt_boxes], axis=0) # (n+m) x 4 iou = tf.concat([iou, tf.eye(tf.shape(gt_boxes)[0])], axis=0) # (n x m + m x m) # OK # #proposal=n+m from now on def sample_fg_bg(iou): fg_mask = tf.reduce_max(iou, axis=1) >= cfg.FRCNN.FG_THRESH fg_inds = tf.reshape(tf.where(fg_mask), [-1]) # 2-D call mask,1-D call indices num_fg = tf.minimum(int(cfg.FRCNN.BATCH_PER_IM * cfg.FRCNN.FG_RATIO), tf.size(fg_inds), name='num_fg') fg_inds = tf.random_shuffle(fg_inds)[:num_fg] bg_inds = tf.reshape(tf.where(tf.logical_not(fg_mask)), [-1]) num_bg = tf.minimum(cfg.FRCNN.BATCH_PER_IM - num_fg, tf.size(bg_inds), name='num_bg') bg_inds = tf.random_shuffle(bg_inds)[:num_bg] add_moving_summary(num_fg, num_bg) # ?? return fg_inds, bg_inds # len_fg + len_bg = m + n fg_inds, bg_inds = sample_fg_bg(iou) # fg,bg indices w.r.t proposals best_iou_ind = tf.argmax( iou, axis=1) # #proposal, each in 0~m-1 because after shuffle # OK fg_inds_wrt_gt = tf.gather(best_iou_ind, fg_inds) # best_fg_indices m all_indices = tf.concat([fg_inds, bg_inds], axis=0) # indices w.r.t all n+m proposal boxes ret_boxes = tf.gather(boxes, all_indices) ret_labels = tf.concat([ tf.gather(gt_labels, fg_inds_wrt_gt), tf.zeros_like(bg_inds, dtype=tf.int64) ], axis=0) # OK # stop the gradient -- they are meant to be training targets return BoxProposals( tf.stop_gradient(ret_boxes, name='sampled_proposal_boxes'), tf.stop_gradient(ret_labels, name='sampled_labels'), tf.stop_gradient(fg_inds_wrt_gt), gt_boxes, gt_labels)