FocalLoss mean reduction is multiplied by the number of channels when ignore_index is set
Maintainer thường phản hồi trong vòng 3 ngày
Đá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
- 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
- Có Dockerfile hoặc tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Project-MONAI/MONAI
-
partition_dataset with ratios leaves some items out of every partitionCó thể đã có người làm @mottopanikeiku đã nhận 1 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Project-MONAI/MONAI#9216 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
DiNTS: missing graph-break regression test (follow-up to #9145)Có thể đã có người làm @nilapate đã nhận 15 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Project-MONAI/MONAI#9159 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
ProbMapProducer raises IndexError on numpy 2.x: SlidingPatchWSIDataset emits float locationsCó thể đã có người làm @nilapate đã nhận 25 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Project-MONAI/MONAI#9135 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
RandGridPatch crashes for documented 0 or None patch_size entriesCó thể đã có người làm @Rajioba1 đã nhận 82 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Project-MONAI/MONAI#9046 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Incorrect type hint in `pad_func`Có thể đã có người làm @Harshal875 đã nhận 87 ngày trước. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
Project-MONAI/MONAI#9026 ·
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của Project-MONAI/MONAI
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
AstrBotDevs/AstrBot#10720 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
fix(xiaomi): curated picker list still offers six ids that return 400 (plan-limited vs retired)Đang mởcause/upstream comp/cli P2 provider/other tool/file type/bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
NousResearch/hermes-agent#143900 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 85/100
WLAN-Pi/wlanpi-profiler#341 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
Maintainer thường phản hồi trong vòng 1 ngày