def _loss_mask(self, proto_output, pred_mask_coef, gt_bbox_norm, gt_masks, positiveness, max_id_for_anchors, max_masks_for_train): shape_proto = tf.shape(proto_output) num_batch = shape_proto[0] loss_mask = 0. total_pos = 0 for idx in tf.range(num_batch): # extract randomly postive sample in pred_mask_coef, gt_cls, gt_offset according to positive_indices proto = proto_output[idx] mask_coef = pred_mask_coef[idx] mask_gt = gt_masks[idx] bbox_norm = gt_bbox_norm[idx] pos = positiveness[idx] max_id = max_id_for_anchors[idx] pos_indices = tf.squeeze(tf.where(pos == 1)) # tf.print("num_pos", tf.shape(pos_indices)) """ if tf.size(pos_indices) == 0: tf.print("detect no positive") continue """ # Todo decrease the number pf positive to be 100 # [num_pos, k] pos_mask_coef = tf.gather(mask_coef, pos_indices) pos_max_id = tf.gather(max_id, pos_indices) if tf.size(pos_indices) == 1: # tf.print("detect only one dim") pos_mask_coef = tf.expand_dims(pos_mask_coef, axis=0) pos_max_id = tf.expand_dims(pos_max_id, axis=0) total_pos += tf.size(pos_indices) # proto = [80, 80, num_mask] # pos_mask_coef = [num_pos, num_mask] # pred_mask = proto x pos_mask_coef = [80, 80, num_pos] # pred_mask transpose = [num_pos, 80, 80] pred_mask = tf.linalg.matmul(proto, pos_mask_coef, transpose_a=False, transpose_b=True) pred_mask = tf.transpose(pred_mask, perm=(2, 0, 1)) # calculating loss for each mask coef correspond to each postitive anchor # pos_max_id = [num_pos] gt = tf.gather(mask_gt, pos_max_id) # [num_pos, 80, 80] bbox = tf.gather(bbox_norm, pos_max_id) # [num_pos, 4] bbox_center = utils.map_to_center_form(bbox) # [num_pos, 4] area = bbox_center[:, -1] * bbox_center[:, -2] # crop the pred (not real crop, zero out the area outside the gt box) s = tf.nn.sigmoid_cross_entropy_with_logits(gt, pred_mask) # [num_pos, 80, 80] s = utils.crop(s, bbox, origin_w=80, origin_h=80) # [num_pos, 80, 80] loss = tf.reduce_sum(s, axis=[1, 2]) / area # [num_pos] loss_mask += tf.reduce_sum(loss) loss_mask /= tf.cast(total_pos, tf.float32) return loss_mask
def _loss_mask(self, protonet_output, pred_mask_coef, gt_bbox_norm, gt_masks, positiveness, max_id_for_anchors, max_masks_for_train): shape_proto = tf.shape(protonet_output) batch_size = shape_proto[0] loss_mask = 0. total_pos = 0 for idx in tf.range(batch_size): # extract randomly postive sample in pred_mask_coef, gt_cls, gt_offset according to positive_indices proto = protonet_output[idx] mask_coef = pred_mask_coef[idx] mask_gt = gt_masks[idx] bbox_norm = gt_bbox_norm[idx] pos = positiveness[idx] max_id = max_id_for_anchors[idx] pos_indices = tf.squeeze(tf.where(pos == 1)) # tf.print("num_pos", tf.shape(pos_indices)) # TODO: Limit number of positive to be less than max_masks_for_train pos_mask_coef = tf.gather(mask_coef, pos_indices) pos_max_id = tf.gather(max_id, pos_indices) if tf.size(pos_indices) == 1: # tf.print("detect only one dim") pos_mask_coef = tf.expand_dims(pos_mask_coef, axis=0) pos_max_id = tf.expand_dims(pos_max_id, axis=0) total_pos += tf.size(pos_indices) pred_mask = tf.linalg.matmul(proto, pos_mask_coef, transpose_a=False, transpose_b=True) pred_mask = tf.transpose(pred_mask, perm=(2, 0, 1)) # calculating loss for each mask coef correspond to each postitive anchor gt = tf.gather(mask_gt, pos_max_id) bbox = tf.gather(bbox_norm, pos_max_id) bbox_center = utils.map_to_center_form(bbox) area = bbox_center[:, -1] * bbox_center[:, -2] # crop the pred (not real crop, zero out the area outside the gt box) s = tf.nn.sigmoid_cross_entropy_with_logits(gt, pred_mask) s = utils.crop(s, bbox) loss = tf.reduce_sum(s, axis=[1, 2]) / area loss_mask += tf.reduce_sum(loss) loss_mask /= tf.cast(total_pos, tf.float32) return loss_mask
def _loss_mask(self, proto_output, pred_mask_coef, gt_bbox_norm, gt_masks, positiveness, max_id_for_anchors, max_masks_for_train): shape_proto = tf.shape(proto_output) num_batch = shape_proto[0] proto_h = shape_proto[1] proto_w = shape_proto[2] loss_mask = 0. total_pos = 0 for idx in tf.range(num_batch): # extract randomly postive sample in prejd_mask_coef, gt_cls, gt_offset according to positive_indices proto = proto_output[idx] mask_coef = pred_mask_coef[idx] mask_gt = gt_masks[idx] bbox_norm = gt_bbox_norm[idx] # [100, 4] -> [num_obj, 4] pos = positiveness[idx] max_id = max_id_for_anchors[idx] pos_indices = tf.squeeze(tf.where(pos == 1)) # If exceeds the number of masks for training, select a random subset old_num_pos = tf.size(pos_indices) # print("pos indices", pos_indices.shape) if old_num_pos > max_masks_for_train: perm = tf.random.shuffle(pos_indices) pos_indices = perm[:max_masks_for_train] pos_mask_coef = tf.gather(mask_coef, pos_indices) pos_max_id = tf.gather(max_id, pos_indices) # if only 1 positive or no positive if tf.size(pos_indices) == 1: pos_mask_coef = tf.expand_dims(pos_mask_coef, axis=0) pos_max_id = tf.expand_dims(pos_max_id, axis=0) elif tf.size(pos_indices) == 0: continue else: ... # [num_pos, k] gt = tf.gather(mask_gt, pos_max_id) bbox = tf.gather(bbox_norm, pos_max_id) # print(bbox[:5]) num_pos = tf.size(pos_indices) # print('gt_me', gt.shape) total_pos += num_pos # [138, 138, num_pos] pred_mask = tf.linalg.matmul(proto, pos_mask_coef, transpose_a=False, transpose_b=True) pred_mask = tf.transpose(pred_mask, perm=(2, 0, 1)) s = tf.nn.sigmoid_cross_entropy_with_logits(gt, pred_mask) s = utils.crop(s, bbox) # calculating loss for each mask coef correspond to each postitive anchor bbox_center = utils.map_to_center_form(tf.cast(bbox, tf.float32)) area = bbox_center[:, -1] * bbox_center[:, -2] mask_loss = tf.reduce_sum(s, axis=[1, 2]) / area if old_num_pos > num_pos: mask_loss = mask_loss * tf.cast( (old_num_pos / num_pos), mask_loss.dtype) loss_mask += tf.reduce_sum(mask_loss) return loss_mask / tf.cast(total_pos, loss_mask.dtype)