Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

FocalLoss mean reduction is multiplied by the number of channels when ignore_index is set

Đang mở Phù hợp với người mới
#9,214 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 3 ngày

@mottopanikeiku đang làm issue này rồi.

Từ ngày 22/10/2026.

  • #9215 của @mottopanikeiku — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
82/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python, pytorch
Lĩnh vực
machine-learning

Hướng nghiên cứu

Bắt đầu bằng cách đọc monai/losses/focal_loss.py quanh phần mean reduction của FocalLoss và so sánh số lượng phần tử trong mask với reduction của AsymmetricFocalLoss. Thêm regression test cho ignore_index với nhiều kênh loss, bao gồm một nhãn ignore không được dùng. Hoàn thành khi các voxel bị bỏ qua cho ra cùng giá trị trung bình như khi xóa chúng, và một nhãn ignore không được dùng không làm thay đổi loss.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug
The text below was written with AI assistance (Claude and GPT-6 Astra).

With ignore_index set, FocalLoss(reduction="mean") divides the summed loss by mask.sum() (https://github.com/Project-MONAI/MONAI/blob/6920610c310200d683a3b00987a05893ccf1ca5f/monai/losses/focal_loss.py#L240-L245). The mask has one channel, but the loss has one value per voxel and channel, so the result is the masked mean times the number of loss channels. Just setting ignore_index to a label that never occurs changes the loss from x to C * x, and the gradients scale with it. The "sum" reduction and AsymmetricFocalLoss (mask.expand_as(loss).sum()) are not affected.

I found this by reading and testing the code.

To Reproduce

import torch
from monai.losses import FocalLoss

torch.manual_seed(0)
logits = torch.randn(2, 4, 16, 16, 8)
labels = torch.randint(0, 4, (2, 1, 16, 16, 8))
plain = FocalLoss(to_onehot_y=True, use_softmax=True)(logits, labels)
masked = FocalLoss(to_onehot_y=True, use_softmax=True, ignore_index=255)(logits, labels)  # no voxel is 255
print(plain.item(), masked.item(), (masked / plain).item())

Output on dev (6920610):

0.30678269267082214 1.2271307706832886 4.0

On MONAI's MNI152 2 mm T1 test volume with its 6-label structural segmentation (small UNet logits), the ratio is 6.0. With the top 40% of axial slices set to 255, FocalLoss(ignore_index=255) gives 1.795147, while the same loss on only the labelled slices gives 0.299191.

Expected behavior
Ignoring voxels should give the same mean as removing them, and an unused ignore_index should not change the loss.

Environment
MONAI 1.6.1rc0+50.g6920610c (dev), PyTorch 2.14.1+cpu, NumPy 2.5.4, Python 3.12.13, Linux.

Additional context
I have a one-line fix that counts the mask once per loss channel, as AsymmetricFocalLoss already does, plus a regression test, and can open a PR.

I made this report and directed the investigation, with AI assistance from Claude and GPT-6 Astra.

Ngôn ngữ chính
Python
Star
8.8k
Fork
1.7k
Merge trung bình
5 ngày 4 giờ
Pull request đã merge (30 ngày)
12

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của Project-MONAI/MONAI

Tất cả issue của Project-MONAI/MONAI

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.