def sigmoid_focal_loss(
    outputs: torch.Tensor,
    targets: torch.Tensor,
    gamma: float = 2.0,
    alpha: float = 0.25,
    reduction: str = "mean",
):
    """
    Compute binary focal loss between target and output logits.

    Args:
        outputs: tensor of arbitrary shape
        targets: tensor of the same shape as input
        gamma: gamma for focal loss
        alpha: alpha for focal loss
        reduction (string, optional):
            specifies the reduction to apply to the output:
            ``"none"`` | ``"mean"`` | ``"sum"`` | ``"batchwise_mean"``.
            ``"none"``: no reduction will be applied,
            ``"mean"``: the sum of the output will be divided by the number of
            elements in the output,
            ``"sum"``: the output will be summed.

    Returns:
        computed loss

    Source: https://github.com/BloodAxe/pytorch-toolbelt
    """
    targets = targets.type(outputs.type())

    logpt = -F.binary_cross_entropy_with_logits(outputs, targets, reduction="none")
    pt = torch.exp(logpt)

    # compute the loss
    loss = -((1 - pt).pow(gamma)) * logpt

    if alpha is not None:
        loss = loss * (alpha * targets + (1 - alpha) * (1 - targets))

    if reduction == "mean":
        loss = loss.mean()
    if reduction == "sum":
        loss = loss.sum()
    if reduction == "batchwise_mean":
        loss = loss.sum(0)

    return loss

    Compute binary focal loss between target and output logits.

    Args:
        outputs: tensor of arbitrary shape
        targets: tensor of the same shape as input
        gamma: gamma for focal loss
        alpha: alpha for focal loss
        reduction (string, optional):
            specifies the reduction to apply to the output:
            ``"none"`` | ``"mean"`` | ``"sum"`` | ``"batchwise_mean"``.
            ``"none"``: no reduction will be applied,
            ``"mean"``: the sum of the output will be divided by the number of
            elements in the output,
            ``"sum"``: the output will be summed.

    Returns:
        computed loss

    Source: https://github.com/BloodAxe/pytorch-toolbelt
    
catalyst/metrics/functional/_focal.py