Skip to content

Add BoundaryLoss#8916

Open
txmed82 wants to merge 1 commit into
Project-MONAI:devfrom
txmed82:boundary-loss
Open

Add BoundaryLoss#8916
txmed82 wants to merge 1 commit into
Project-MONAI:devfrom
txmed82:boundary-loss

Conversation

@txmed82

@txmed82 txmed82 commented Jun 12, 2026

Copy link
Copy Markdown

Added BoundaryLoss. - Handles 2D/3D seg - Supports sigmoid, softmax, other_act, include_background, batch - Does empty masks without producing arbitrary distance ramps - Added tests for shape handling, reductions, gradient flow, single channel warnings, degenerative mask & channel free targets Verified with tests including run tests.sh

Closes #8884

Signed-off-by: Colin Son <txmed82@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces BoundaryLoss, a new loss function for boundary-aware segmentation. It computes a signed distance map for each target class using scipy's distance_transform_edt, weights predicted probabilities by these distance maps to emphasize boundary regions, and normalizes by pixel count. The implementation supports configurable activation (sigmoid/softmax/custom), one-hot target conversion, background exclusion, and standard reduction modes. Full package integration includes init re-export and documentation entry. Tests cover parameterized configurations, shape validation, edge cases, error handling, and gradient propagation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly and concisely summarizes the main change: adding a new BoundaryLoss class to the codebase.
Description check ✅ Passed Description covers key implementation details and references the linked issue, but doesn't fully follow the template structure with explicit checkbox markings for all required sections.
Linked Issues check ✅ Passed PR successfully implements all core objectives from #8884: BoundaryLoss class with 2D/3D support, activation options, distance-map weighting, standard reduction parameter, and comprehensive tests.
Out of Scope Changes check ✅ Passed All changes directly support BoundaryLoss implementation: new loss class, module exports, documentation, and tests. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 95.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/losses/test_boundary_loss.py`:
- Around line 151-154: Add a Google-style docstring to the helper function
_describe_test_case that documents the parameters and return value: describe the
arguments (test_func, test_number, params) and that params.args unpacks to
(input_param, input_data, _), explain the expected structure of input_data (a
dict with 'input' Tensor including shape and device), and state that the
function returns a formatted string describing the params, shape, and device;
place the docstring immediately under the def line in Google style with Args:
and Returns: sections.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8cc5f9a0-8eb4-430a-bb9e-4ca7e4e8938d

📥 Commits

Reviewing files that changed from the base of the PR and between eccefc5 and 9c26ae6.

📒 Files selected for processing (4)
  • docs/source/losses.rst
  • monai/losses/__init__.py
  • monai/losses/boundary_loss.py
  • tests/losses/test_boundary_loss.py

Comment on lines +151 to +154
def _describe_test_case(test_func, test_number, params):
input_param, input_data, _ = params.args
return f"params:{input_param}, shape:{input_data['input'].shape}, device:{input_data['input'].device}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a Google-style docstring to _describe_test_case.

This helper definition is missing a docstring describing parameters and return value.

Proposed fix
 def _describe_test_case(test_func, test_number, params):
+    """Build a readable label for a parameterized test case.
+
+    Args:
+        test_func: The parameterized test function.
+        test_number: The generated case index.
+        params: Parameter bundle containing test args.
+
+    Returns:
+        A string describing params, tensor shape, and device.
+    """
     input_param, input_data, _ = params.args
     return f"params:{input_param}, shape:{input_data['input'].shape}, device:{input_data['input'].device}"

As per coding guidelines, "Docstrings should be present for all definition which describe each variable, return value, and raised exception in the appropriate section of the Google-style of docstrings."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def _describe_test_case(test_func, test_number, params):
input_param, input_data, _ = params.args
return f"params:{input_param}, shape:{input_data['input'].shape}, device:{input_data['input'].device}"
def _describe_test_case(test_func, test_number, params):
"""Build a readable label for a parameterized test case.
Args:
test_func: The parameterized test function.
test_number: The generated case index.
params: Parameter bundle containing test args.
Returns:
A string describing params, tensor shape, and device.
"""
input_param, input_data, _ = params.args
return f"params:{input_param}, shape:{input_data['input'].shape}, device:{input_data['input'].device}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/losses/test_boundary_loss.py` around lines 151 - 154, Add a
Google-style docstring to the helper function _describe_test_case that documents
the parameters and return value: describe the arguments (test_func, test_number,
params) and that params.args unpacks to (input_param, input_data, _), explain
the expected structure of input_data (a dict with 'input' Tensor including shape
and device), and state that the function returns a formatted string describing
the params, shape, and device; place the docstring immediately under the def
line in Google style with Args: and Returns: sections.

Source: Coding guidelines

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Add BoundaryLoss for highly imbalanced segmentation

1 participant