import torch


def dice_loss(yhat, ytrue, epsilon=1e-6):
    """
    Computes a soft Dice Loss

    Args:
        yhat (Tensor): predicted masks
        ytrue (Tensor): targets masks
        epsilon (Float): smoothing value to avoid division by 0
    output:
        DL value with `mean` reduction
    """
    # compute Dice components
    intersection = torch.sum(yhat * ytrue, (1,2,3))
    cardinal = torch.sum(yhat + ytrue, (1,2,3))

    return torch.mean(1. - (2 * intersection / (cardinal + epsilon)))