예제 #1
0
    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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #7
0
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