예제 #1
0
def precision(prediction: torch.Tensor,
              target: torch.Tensor, epsilon: float = 1e-6) -> torch.Tensor:
    """
    Compute the precision score
    Args:
        prediction: Network output.
            Dimensions - (Batch, Class, Depth, Height, Width)
        target: Target values. The classes should be one-hot encoded.
            Dimensions - (Batch, Class, Depth, Height, Width)
        epsilon: Smooth factor to prevent division by 0.
    Returns:
        torch.Tensor: Precision score calculated for each class
            averaged across the whole batch
    """
    assert utils.is_binary(prediction), "Predictions must be binary"
    assert utils.is_binary(target), "Target must be binary"
    volume_dims = list(range(2, target.dim()))
    true_positives = utils.calculate_intersection(prediction, target,
                                                  dim=volume_dims)
    false_positive = utils.calculate_false_positives(prediction, target,
                                                     dim=volume_dims)
    score = true_positives / (
            true_positives + false_positive + epsilon)
    score = torch.mean(score, dim=BATCH_DIM)
    return score
예제 #2
0
def hausdorff95(prediction: torch.Tensor, target: torch.Tensor,
                merge_operation: Callable[
                    [torch.Tensor], float] = torch.max) -> torch.Tensor:
    """
    95th percentile of the Hausdorff Distance.

    Computes the 95th percentile of the (symmetric) Hausdorff Distance (HD)
    between the binary objects in two images.
    Heavily depends on medpy.metric.binary.hd95, so check it out for more
    details.
    Args:
        prediction: Network output.
            Dimensions - (Batch, Class, Depth, Height, Width)
        target: Target values.
            Dimensions - (Batch, Class, Depth, Height, Width)
        merge_operation: Operation to merge results from all the slices in
            the batch into a single value. Should be a function that accepts
            two dimensional tensors (Batch, Depth).
            Good examples are: torch.mean, torch.max, torch.min.
    Returns:
        torch.Tensor: Hausdorff distance for the provided volume
    """
    assert utils.is_binary(prediction), "Predictions must be binary"
    assert utils.is_binary(target), "Target must be binary"
    prediction = prediction.cpu().detach().numpy()
    target = target.cpu().detach().numpy()
    volumes_count, _, slices_count, _, _ = prediction.shape
    results = np.zeros((volumes_count, slices_count))
    for volume_idx in range(volumes_count):
        for slice_idx in range(slices_count):
            prediction_slice = prediction[
                volume_idx, FIRST_CLASS, slice_idx, ...]
            target_slice = target[volume_idx, FIRST_CLASS, slice_idx, ...]
            if utils.has_only_zeros(prediction_slice) or \
                    utils.has_only_zeros(target_slice):
                results[volume_idx, slice_idx] = 0
            else:
                results[volume_idx, slice_idx] = mp.hd95(prediction_slice,
                                                         target_slice)
    return merge_operation(torch.from_numpy(results))
예제 #3
0
 def test_if_returns_true_for_only_0s(self):
     assert utils.is_binary(torch.zeros(VOLUME_DIMS))
예제 #4
0
 def test_if_returns_false_for_one_non_binary_value(self):
     input = torch.ones(VOLUME_DIMS)
     input[0, 0, 0] = 0.2
     assert not utils.is_binary(input)
예제 #5
0
 def test_if_returns_false_for_all_non_binary_values(self):
     input = torch.ones(VOLUME_DIMS) * 0.5
     assert not utils.is_binary(input)