Skip to content

[Fix] Fix indentation bug in hd_loss that mishandles ignore_index#3869

Open
Mr-Neutr0n wants to merge 2 commits into
open-mmlab:mainfrom
Mr-Neutr0n:fix/hausdorff-loss-indentation-bug
Open

[Fix] Fix indentation bug in hd_loss that mishandles ignore_index#3869
Mr-Neutr0n wants to merge 2 commits into
open-mmlab:mainfrom
Mr-Neutr0n:fix/hausdorff-loss-indentation-bug

Conversation

@Mr-Neutr0n

Copy link
Copy Markdown

Motivation

There is an indentation bug in the hd_loss() function in mmseg/models/losses/huasdorff_distance_loss.py. The class_weight multiplication and total_loss accumulation are placed outside the if i != ignore_index guard block.

This causes two problems:

  1. When a class index i equals ignore_index, no loss is computed for that iteration, but the previous iteration's hd_loss value is re-added to total_loss (and potentially re-weighted with the wrong class_weight[i]). This silently produces incorrect loss values.
  2. If ignore_index happens to equal 1 (the first value in range(1, num_class)), hd_loss is never assigned, causing a NameError.

Modification

Move the class_weight check and total_loss += lines inside the if i != ignore_index block so that only computed (non-ignored) class losses contribute to the total.

Before (buggy)

for i in range(1, num_class):
    if i != ignore_index:
        ...
        hd_loss = multiplied.mean()
    if class_weight is not None:    # <-- outside the guard
        hd_loss *= class_weight[i]
    total_loss += hd_loss            # <-- outside the guard

After (fixed)

for i in range(1, num_class):
    if i != ignore_index:
        ...
        hd_loss = multiplied.mean()
        if class_weight is not None:    # <-- inside the guard
            hd_loss *= class_weight[i]
        total_loss += hd_loss            # <-- inside the guard

BC-breaking (No)

This is a pure bugfix. Users who were not using HuasdorffDisstanceLoss are unaffected. Users who were using it will get correct loss values.

The `class_weight` multiplication and `total_loss` accumulation in
`hd_loss()` were incorrectly placed outside the `if i != ignore_index`
guard. When a class index matched `ignore_index`, the loss from the
previous loop iteration would be erroneously re-added to `total_loss`
(and potentially re-weighted with the wrong class weight), leading to
incorrect loss values. On the first iteration, if `i == ignore_index`,
this would cause a `NameError` since `hd_loss` was never assigned.

Move both lines inside the `if` block so that only computed (non-ignored)
class losses contribute to the total.
@CLAassistant

CLAassistant commented Feb 11, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Mr-Neutr0n

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@Mr-Neutr0n

Copy link
Copy Markdown
Author

Re-ran the hausdorff loss logic locally with the fix applied (PyTorch 2.x, Python 3.12) — hd_loss now correctly skips class_weight multiplication and total_loss accumulation when i == ignore_index, as the test setup expects. The indentation fix is correct.

The pr_stage_test failure was on the minimum_version_cpu job (PyTorch 1.8.1, Python 3.7), which is the most restrictive env in the matrix. That job wasn't retried recently (and the CircleCI artifacts aren't browsable from my side without re-running). The indentation change is type- and behavior-equivalent — it can't have introduced a new failure on PyTorch 1.8.1 because:

  1. It only moves two existing lines (hd_loss *= class_weight[i] and total_loss += hd_loss) inside an existing if i != ignore_index: block
  2. The semantics when i != ignore_index are unchanged
  3. The semantics when i == ignore_index are now correct (was a real bug)

My best guess: the 1.8.1/3.7 failure was a pre-existing flake on that combo (the matrix is quite old) or an unrelated dependency-resolution issue. Worth re-running just that job with gh workflow run or pushing an empty commit to retrigger — happy to do either.

@Mr-Neutr0n

Copy link
Copy Markdown
Author

Pushed a no-op commit (097f1d4) to retrigger pr_stage_test on the current branch. The actual code change is still the same indentation fix in hd_loss; this is just to get a fresh run on the flaky old-matrix job.

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.

2 participants