-
Notifications
You must be signed in to change notification settings - Fork 405
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
Cannot use average="none"
in v0.11?
#1425
Comments
Hi! thanks for your contribution!, great first issue! |
Hey, Is there any progress on this? :) I stumbled upon the same problem and needed a quick fix, so I dug a bit deeper. It seems more complicated than removing this if statement. For TLDR, I wrote a quick and dirty fix which allows to instantiate the Furthermore, I don't understand some changes made by #1252 in Please let me know if I'm missing something. |
Update: When updating the metric state, I ran into a new error regarding shape mismatch of |
Hi everyone, thanks for reporting this issue. |
I cannot get the expected Dice result using MulticlassF1Score. See below this toy example where I calculate the Dice for class 1 and 2 (ignoring 0). My implementation and the MONAI implementation agree, but the F1 score does not (and also still returns a tensor with length of classes including 0). from monai.metrics import DiceMetric as dice
from torchmetrics.classification import MulticlassF1Score as F1_score
import torch
from torch.nn.functional import one_hot
calc = dice(include_background=False, reduction='mean_batch')
F1 = F1_score(num_classes=3, multidim_average='global', average='none', ignore_index=0)
def with_monai(pred, gt, calc):
pred = one_hot(pred, num_classes=3)
gt = one_hot(gt, num_classes=3)
pred = torch.permute(pred, (0,3,1,2))
gt = torch.permute(gt, (0,3,1,2))
return calc(pred, gt)
def my_dice(pred, gt):
pred1map = (pred==1).type(torch.int64)
pred2map = (pred==2).type(torch.int64)
gt1map = (gt==1).type(torch.int64)
gt2map = (gt==2).type(torch.int64)
c1 = 2*torch.sum(pred1map * gt1map)/ (torch.sum(pred1map) + torch.sum(gt1map))
c2 = 2*torch.sum(pred2map * gt2map)/ (torch.sum(pred2map) + torch.sum(gt2map))
return torch.tensor([c1, c2])
test_pred = torch.tensor([[[1, 1], [2, 0]]]).type(torch.int64)
test_gt = torch.tensor([[[1, 0], [2, 1]]]).type(torch.int64)
print(test_pred.shape)
# torch.Size([1, 2, 2])
print(test_pred)
# tensor([[[1, 1],
[2, 0]]])
print(test_gt)
# tensor([[[1, 0],
[2, 1]]])
print(F1(test_pred, test_gt))
# tensor([0.0000, 0.6667, 1.0000])
print(with_monai(test_pred, test_gt, calc))
# tensor([[0.5000, 1.0000]])
print(my_dice(test_pred, test_gt))
# tensor([0.5000, 1.0000]) |
Okay, I have figured it out!
The issue is due to my misunderstanding of the ignore_index argument.
Ignoring index 0 actually changes the results for index 1 and 2, because the interpretation is "if pred OR gt is 0, do not consider this voxel", so false positive in the background and false negatives where we predict background do not get considered in dice score. I would have expected the ignore_index option to simply not calculate metrics for the ignored index (and maybe output a tensor with one fewer elements e.g. [index=x1, index2=y] not [index0=0, index1=x, index2=y]).
…On Fri, Jul 28, 2023 at 8:46 AM Jan Karwowski ***@***.***> wrote:
I think that you should set multidim_average="samplewise" to achieve the
same results.
—
Reply to this email directly, view it on GitHub
<#1425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AZWRUXD2D547DWTQ6N3N7MTXSNU4FANCNFSM6AAAAAATQF45XI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
average="none"
in v0.11?
Would you think that some rewording is needed? |
Personally, I can't think of any situations where the current behaviour is
useful (but perhaps this is just biases from my own field of work). I think
that this behaviour would not be the expected behaviour for most people and
unless they were to carefully test the function, they wouldn't notice what
is actually happening and would have inflated metrics.
My vote would be to change the computation, but if not, then yes, rewording
would be helpful I think.
…On Thu, 14 Sept 2023, 15:55 Jirka Borovec, ***@***.***> wrote:
The issue is due to my misunderstanding of the ignore_index argument.
Would you think that some rewording is needed?
—
Reply to this email directly, view it on GitHub
<#1425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AZWRUXDUIZ3A7KECBXTFWZTX2MLGFANCNFSM6AAAAAATQF45XI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I can confirm same behaviour of When using the When calculating with The I agree with @Jesse-Phitidis, the current implementation either accounts for all classes (bias towards class imbalance) or doesn't account for false-positives (promotes trivial classifiers). The parameter My suggestion is to keep the current |
🐛 Bug
Using version 0.11 and trying to use Dice with average="none", I get the following error:
Additional context
There is a check for the allowed
average
values in the Dice class. This permits "none".However, comparing v0.11 and v0.10.3, it looks like a second check was added further down in the class during this PR.
Since that doesn't check for average of "none", and since average isn't redefined above it, I think that secondary check added in #1252 causes the bug.
The text was updated successfully, but these errors were encountered: