Torchgeometry dice loss unexpected result

username: paulyoung
cooked: <p>Good afternoon, I am trying to understand dice loss better to correct some saturation issues in my segmentation code, but even a simple example like below returns unexpected results.</p>
<p>from torchgeometry.losses.dice import dice_loss<br>
pred = torch.tensor([[[0,1],[2,3]]])<br>
pred = torch.nn.functional.one_hot(pred, num_classes= 4).permute(0,3,1,2).float()<br>
targ = torch.tensor([[[0,1],[2,3]]])<br>
print(dice_loss(pred, targ))</p>
<blockquote>
<blockquote>
<blockquote>
<p>tensor(0.5246)</p>
</blockquote>
</blockquote>
</blockquote>
<p>It is my understanding that dice loss is supposed to return 1.0 upon perfect class overlap, but as you can see above, it does not. I set the dtypes as specified (float32 and int64) and input the predictions as 1-hot (N,C,H,W), and input the targets as (N,H,W) as shown above. Is there a reason this should not return 1?</p>

username: ptrblck
cooked: <aside class="quote no-group" data-username="paulyoung" data-post="1" data-topic="181753">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/p/6bbea6/48.png" class="avatar"> paulyoung:</div>
<blockquote>
<p>It is my understanding that dice loss is supposed to return 1.0 upon perfect class overlap</p>
</blockquote>
</aside>
<p>That’s not the case as the <a href="https://kornia.readthedocs.io/en/v0.1.2/losses.html#torchgeometry.losses.DiceLoss">docs</a> explain the inputs as:</p>
<blockquote>
<p>X expects to be the scores of each class.<br>
Y expects to be the one-hot tensor with the class labels.</p>
</blockquote>
<p>where the <code>scores</code> will be passed to <code>F.softmax(input, dim=1)</code> before the dice loss is calculated.</p>

username: paulyoung
cooked: <p>Thank you, the softmax appears to be creating the unexpected results. However, the doc you quoted is still quite confusing:</p>
<aside class="quote no-group" data-username="ptrblck" data-post="2" data-topic="181753">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<p>X expects to be the scores of each class.<br>
Y expects to be the one-hot tensor with the class labels.</p>
</blockquote>
</aside>
<p>However three lines down the docs state:</p>
<blockquote>
<p>Shape:</p>
<ul>
<li>Input: (N,C,H,W) where C = number of classes.</li>
<li>Target: (N,H,W) where each value is 0≤targets[i]≤C−1</li>
</ul>
</blockquote>
<p>(N, H, W) is not a one-hot tensor. In fact when I try to pass Y as a one-hot tensor,  dice_loss tells me “Invalid depth shape, we expect BxHxW. Got: torch.Size([1, 4, 2, 2])”</p>

username: ptrblck
cooked: <p>The text is indeed confusing as internally:</p>
<pre><code class="lang-python"># create the labels one hot tensor
target_one_hot = one_hot(target, num_classes=input.shape[1],
                         device=input.device, dtype=input.dtype)
</code></pre>
<p>will be used.<br>
I guess the authors try to tell <code>Y</code> is expected to contain class labels as it <em>will represent</em> the one-hot tensor?</p>
<p>I also don’t know if <code>torchgeometry</code> is still supported or if it was replaced by <code>kornia</code> which uses the <a href="https://kornia.readthedocs.io/en/latest/losses.html#kornia.losses.DiceLoss">same docs</a>.</p>
<p>CC <a class="mention" href="/u/edgarriba">@edgarriba</a></p>

username: edgarriba
cooked: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> you are right in both of your comments. Y is expected to be the tensors with the labels ids so that Internally creates for you the one hot. And yeah, torchgeometry doesn’t exist anymore (for more than 3/4 years) since evolved to what’s kornia today.</p>
<p><a class="mention" href="/u/paulyoung">@paulyoung</a> feel free to send a PR to adjust any documentation miss understanding.</p>