Beispiel #1
0
def nll_loss(input,
             target,
             weight=None,
             size_average=None,
             ignore_index=-100,
             reduce=None,
             reduction='mean'):
    # type: (Tensor, Tensor, Optional[Tensor], Optional[bool], int, Optional[bool], str) -> Tensor

    if size_average is not None or reduce is not None:
        reduction = _Reduction.legacy_get_string(size_average, reduce)
    dim = input.dim()
    if dim < 2:
        raise ValueError('Expected 2 or more dimensions (got {})'.format(dim))

    if input.size(0) != target.size(0):
        raise ValueError(
            'Expected input batch_size ({}) to match target batch_size ({}).'.
            format(input.size(0), target.size(0)))
    if dim == 2:
        ret = torch._C._nn.nll_loss(input, target, weight,
                                    _Reduction.get_enum(reduction),
                                    ignore_index)
    elif dim == 4:
        ret = torch._C._nn.nll_loss2d(input, target, weight,
                                      _Reduction.get_enum(reduction),
                                      ignore_index)
    else:
        # dim == 3 or dim > 4
        n = input.size(0)
        c = input.size(1)
        out_size = (n, ) + input.size()[2:]
        if target.size()[1:] != input.size()[2:]:
            raise ValueError('Expected target size {}, got {}'.format(
                out_size, target.size()))
        input = input.contiguous()
        target = target.contiguous()
        # support empty batches, see #15870
        if input.numel() > 0:
            input = input.view(n, c, 1, -1)
        else:
            input = input.view(n, c, 0, 0)
        if target.numel() > 0:
            target = target.view(n, 1, -1)
        else:
            target = target.view(n, 0, 0)
        reduction_enum = _Reduction.get_enum(reduction)
        if reduction != 'none':
            ret = torch._C._nn.nll_loss2d(input, target, weight,
                                          reduction_enum, ignore_index)
        else:
            out = torch._C._nn.nll_loss2d(input, target, weight,
                                          reduction_enum, ignore_index)
            ret = out.view(out_size)
    return ret
Beispiel #2
0
def weighted_smooth_l1_loss(input, target, weights, size_average=None, reduce=None, reduction="mean"):
    # type: (Tensor, Tensor, Optional[bool], Optional[bool], str) -> Tensor
    r"""Function that uses a squared term if the absolute
    element-wise error falls below 1 and an L1 term otherwise.

    See :class:`~torch.nn.SmoothL1Loss` for details.
    """
    if not (target.size() == input.size()):
        warnings.warn(
            "Using a target size ({}) that is different to the input size ({}). "
            "This will likely lead to incorrect results due to broadcasting. "
            "Please ensure they have the same size.".format(target.size(), input.size()),
            stacklevel=2,
        )
    if size_average is not None or reduce is not None:
        reduction = _Reduction.legacy_get_string(size_average, reduce)
    if target.requires_grad:
        ret = _weighted_smooth_l1_loss(input, target, weights)
        if reduction != "none":
            ret = torch.mean(ret) if reduction == "mean" else torch.sum(ret)
    else:
        raise (ValueError("haven't thought this through"))
        expanded_input, expanded_target = torch.broadcast_tensors(input, target)
        ret = torch._C._nn.smooth_l1_loss(expanded_input, expanded_target, _Reduction.get_enum(reduction))
    return ret
Beispiel #3
0
    def SmoothL1Loss_custom(input,
                            target,
                            sigma=3.0,
                            size_average=None,
                            reduce=True,
                            reduction='mean'):
        # type: (Tensor, Tensor, Optional[bool], Optional[bool], str) -> Tensor
        def _smooth_l1_loss(input, target, sigma=3.0):
            # type: (Tensor, Tensor) -> Tensor
            t = torch.abs(input - target)
            return torch.where(t < 1, 0.5 * t**2, t - 0.5)

        if not (target.size() == input.size()):
            warnings.warn(
                "Using a target size ({}) that is different to the input size ({}). "
                "This will likely lead to incorrect results due to broadcasting. "
                "Please ensure they have the same size.".format(
                    target.size(), input.size()),
                stacklevel=2)
        if size_average is not None or reduce is not None:
            reduction = _Reduction.legacy_get_string(size_average, reduce)
        if target.requires_grad:
            ret = _smooth_l1_loss(input, target)
            if reduction != 'none':
                ret = torch.mean(ret) if reduction == 'mean' else torch.sum(
                    ret)
        else:
            expanded_input, expanded_target = torch.broadcast_tensors(
                input, target)
            ret = torch._C._nn.smooth_l1_loss(expanded_input, expanded_target,
                                              _Reduction.get_enum(reduction))
        return ret