def reassign_loss_single(self, cls_loss, reg_loss, pos_assigned_gt_inds, labels, level, min_levels): """Reassign loss values at each level by masking those where the pre- calculated loss is too large. Args: cls_loss (Tensor): With shape (num_anchors, num_classes) classification loss reg_loss (Tensor): With shape (num_anchors) regression loss pos_assigned_gt_inds (Tensor): With shape (num_anchors), the gt indices that each positive anchor corresponds to. (-1 if it is a negative one) labels (Tensor): With shape (num_anchors). Label assigned to each pixel level (int): the current level index in the pyramid (0-4 for RetinaNet) min_levels (Tensor): shape (num_gts), the best-matching level for each gt Returns: cls_loss (Tensor): With shape (num_anchors, num_classes). Corrected classification loss reg_loss (Tensor): With shape (num_anchors). Corrected regression loss keep_indices (Tensor): With shape (num_anchors). Indicating final postive anchors """ unmatch_gt_inds = torch.nonzero( min_levels != level) # gts indices that unmatch with the current level match_gt_inds = torch.nonzero(min_levels == level) loc_weight = cls_loss.new_ones(cls_loss.size(0)) cls_weight = cls_loss.new_ones(cls_loss.size(0), cls_loss.size(1)) zeroing_indices = (pos_assigned_gt_inds.view( -1, 1) == unmatch_gt_inds.view(1, -1)).any(dim=-1) keep_indices = (pos_assigned_gt_inds.view(-1, 1) == match_gt_inds.view( 1, -1)).any(dim=-1) loc_weight[zeroing_indices] = 0 # only the weight corresponding to the label is # zeroed out if not selected zeroing_labels = labels[zeroing_indices] - 1 assert (zeroing_labels >= 0).all() cls_weight[zeroing_indices, zeroing_labels] = 0 # weighted loss for both cls and reg loss cls_loss = weight_reduce_loss(cls_loss, cls_weight, reduction='sum') reg_loss = weight_reduce_loss(reg_loss, loc_weight, reduction='sum') return cls_loss, reg_loss, keep_indices
def label_smooth_cross_entropy(pred, label, weight=None, reduction="mean", avg_factor=None, class_weight=None, label_smooth=None): # element-wise losses if label_smooth is None: loss = F.cross_entropy(pred, label, reduction="none") else: num_classes = pred.size(1) target = F.one_hot(label, num_classes).type_as(pred) target = target.sub_(label_smooth).clamp_(0).add_(label_smooth / num_classes) loss = F.kl_div(pred.log_softmax(1), target, reduction="none").sum(1) # apply weights and do the reduction if weight is not None: weight = weight.float() loss = weight_reduce_loss(loss, weight=weight, reduction=reduction, avg_factor=avg_factor) return loss
def binary_cls_loss(func, cls_pred, cls_label, pos_ious=None, weight=None, alpha=0.25, reduction="mean", avg_factor=None): bg_class_ind = cls_pred.shape[-1] # pos_inds for pos sample index pos_inds = ((cls_label >= 0) & (cls_label < bg_class_ind)).nonzero().reshape(-1) # label for binary target y, value is 1 for pos sample groundtruth class, others 0 label = torch.zeros_like(cls_pred) label[pos_inds, cls_label[pos_inds]] = 1.0 # value is IoU for pos sample groundtruth class, others 0 iou = torch.zeros_like(cls_pred) if pos_ious is not None: pos_ious = pos_ious.detach() iou[pos_inds, cls_label[pos_inds]] = pos_ious loss = func(cls_pred, iou, label, 1 - label) if alpha >= 0: alpha_t = alpha * label + (1 - alpha) * (1 - label) loss = alpha_t * loss if weight is not None and len(loss.size()) > 1: weight = weight.view(-1, 1) loss = weight_reduce_loss(loss, weight, reduction, avg_factor) return loss
def reg_loss(func, bbox_pred, bbox_targets, weight=None, linear=False, reduction='mean', avg_factor=None, eps=1e-7, **kwargs): # overlap lt = torch.max(bbox_pred[:, :2], bbox_targets[:, :2]) rb = torch.min(bbox_pred[:, 2:], bbox_targets[:, 2:]) wh = (rb - lt).clamp(min=0) overlap = wh[:, 0] * wh[:, 1] # area / enclose ap = (bbox_pred[:, 2] - bbox_pred[:, 0]) * (bbox_pred[:, 3] - bbox_pred[:, 1]) ag = (bbox_targets[:, 2] - bbox_targets[:, 0]) * (bbox_targets[:, 3] - bbox_targets[:, 1]) enclose_x1y1 = torch.min(bbox_pred[:, :2], bbox_targets[:, :2]) enclose_x2y2 = torch.max(bbox_pred[:, 2:], bbox_targets[:, 2:]) enclose_wh = (enclose_x2y2 - enclose_x1y1).clamp(min=0) enclose = enclose_wh[:, 0] * enclose_wh[:, 1] + eps # union union = ap + ag - overlap + eps loss = func(union, overlap, enclose) loss = weight_reduce_loss(loss, weight, reduction, avg_factor) return loss
def multi_cls_loss(func, cls_pred, cls_label, pos_ious=None, weight=None, class_weight=None, reduction='mean', avg_factor=None): bg_class_ind = cls_pred.shape[-1] - 1 # 0 ~ self.num_classses-1 are FG, self.num_classses is BG num_class = cls_pred.shape[-1] # pos_inds for pos sample index pos_inds = (cls_label >= 0) & (cls_label < bg_class_ind) onehot_label = F.one_hot(cls_label, num_class) # value is IoU for pos sample groundtruth class, others 1 iou = torch.ones_like(onehot_label).type(torch.cuda.FloatTensor) if pos_ious is not None: pos_ious = pos_ious.detach() iou[pos_inds.type(torch.bool), :] = pos_ious.unsqueeze(dim=1) loss = func(cls_pred, onehot_label, iou) # apply weights and do the reduction if weight is not None: weight = weight.float() loss = weight_reduce_loss(loss, weight, reduction, avg_factor) return loss
def binary_cross_entropy(pred, label, weight=None, reduction='mean', avg_factor=None): if pred.dim() != label.dim(): label, weight = _expand_binary_labels(label, weight, pred.size(-1)) # weighted element-wise losses if weight is not None: weight = weight.float() loss = F.binary_cross_entropy_with_logits(pred, label.float(), weight, reduction='none') # do the reduction for the weighted loss loss = weight_reduce_loss(loss, reduction=reduction, avg_factor=avg_factor) return loss
def paconv_regularization_loss(modules, reduction): """Computes correlation loss of PAConv weight kernels as regularization. Args: modules (List[nn.Module] | :obj:`generator`): A list or a python generator of torch.nn.Modules. reduction (str): Method to reduce losses among PAConv modules. The valid reduction method are none, sum or mean. Returns: torch.Tensor: Correlation loss of kernel weights. """ corr_loss = [] for module in modules: if isinstance(module, (PAConv, PAConvCUDA)): corr_loss.append(weight_correlation(module)) corr_loss = torch.stack(corr_loss) # perform reduction corr_loss = weight_reduce_loss(corr_loss, reduction=reduction) return corr_loss
def cross_entropy(pred, label, weight=None, reduction='mean', avg_factor=None): # load word embedding d300 a = [] with open("data/coco_bg.emb") as f: for line in f: l = ast.literal_eval(line) a.append(l) # [1024,300] * [300, 81] pred_new = torch.mm(pred, torch.from_numpy(np.array(a).T).cuda().float()) # element-wise losses loss = F.cross_entropy(pred_new, label, reduction='none') # apply weights and do the reduction if weight is not None: weight = weight.float() loss = weight_reduce_loss(loss, weight=weight, reduction=reduction, avg_factor=avg_factor) return loss
def label_smooth(pred, label, label_smooth_val, avg_smooth_val, weight=None, reduction='mean', avg_factor=None): # # element-wise losses one_hot = torch.zeros_like(pred) one_hot.fill_(avg_smooth_val) label = label.view(-1, 1) one_hot.scatter_(1, label, 1 - label_smooth_val + avg_smooth_val) loss = -torch.sum(F.log_softmax(pred, 1) * (one_hot.detach())) # apply weights and do the reduction if weight is not None: weight = weight.float() loss = weight_reduce_loss(loss, weight=weight, reduction=reduction, avg_factor=avg_factor) return loss