Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of boundary-aware ShapeLoss #4205

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

arnauddhaene
Copy link

@arnauddhaene arnauddhaene commented Apr 29, 2022

Signed off by: Arnaud Dhaene arnaud.dhaene@epfl.ch

Fixes #4204

Description

An implementation of a slight variation of the boundary-aware ShapeLoss described in Huang et al., 2021.

Status

Work in progress: the feature has been implemented, but unit testing needs to be added.

Types of changes

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • Breaking change (fix or new feature that would cause existing functionality to change).
  • New tests added to cover the changes.
  • Integration tests passed locally by running ./runtests.sh -f -u --net --coverage.
  • Quick tests passed locally by running ./runtests.sh --quick --unittests --disttests.
  • In-line docstrings updated.
  • Documentation updated, tested make html command in the docs/ folder.

arnauddhaene and others added 2 commits April 29, 2022 19:10
Signed-off-by: Arnaud Dhaene <arnaud.dhaene@epfl.ch>
Copy link
Contributor

@wyli wyli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the PR, I put some initial comments inline, please ignore them if you are already working on these aspects...

monai/losses/shape.py Outdated Show resolved Hide resolved
monai/losses/shape.py Outdated Show resolved Hide resolved
>>> target = one_hot(target_idx[:, None, ...], num_classes=C)
>>> self = ShapeLoss(reduction='none')
>>> loss = self(input, target)
>>> assert np.broadcast_shapes(loss.shape, input.shape) == input.shape
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be great to create a test case for this class, you can follow this one https://github.com/Project-MONAI/MONAI/blob/dev/tests/test_local_normalized_cross_correlation_loss.py

you can run a single test case within the codebase:

pip install -U -r requirements-dev.txt  # install testing tools
python -m tests.test_local_normalized_cross_correlation_loss

monai/losses/shape.py Outdated Show resolved Hide resolved
* more specific class name
* data conversion using `monai.utils`
* distance transform import using `optional_import`
* TODO: test case
@Bala93
Copy link
Contributor

Bala93 commented May 6, 2022

Hi @arnauddhaene, thanks for this PR. It will be very useful for the community, as distance transform losses do generally improve HD and Dice. I have a doubt though, I see in code there is distance tranform being calculated in numpy. If that is the case, how will the backpropagation work in the training?

@arnauddhaene
Copy link
Author

Hi @Bala93, thank you!

We do not need to backprop on the distance transform. We are in essence transforming the ground truth to a non-binary mask that will penalize the network for boundary misclassification.

The result of the transform is compared to the logits produced by the network, and the difference is used as loss to update the network's weights via backprop.

In fact, the distance_maps for each example could be computed once before training as auxiliary ground truth mask to prevent duplicate computations and speed up training. However, doing this doesn't fit as nicely in the MONAI framework and also is not robust to train-time augmentations that can modify the ground truth mask (elastic transform, rotation, etc.).

I hope this answers your question.

* updated scikit-image morphology module deprecation
* updated reception of converted numpy array
@KumoLiu
Copy link
Contributor

KumoLiu commented Nov 9, 2023

Hi @arnauddhaene, is there any more progress on this PR so far, do you plan to finish this one?
Thanks!

@dimka11
Copy link

dimka11 commented Apr 3, 2024

Why no use distance_transform_edt from monai.transforms that use cupy/cucim with GPU instead slow CPU scipy? Can add PR if someone want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implementation of boundary-aware shape loss
5 participants