One hot for unequal class batch in semantic segmentation

username: talhaanwarch
cooked: <p>Let suppose i have 60 classes and not all images have 60 classes.<br>
So let say my first batch has 40 classes, so it will encoded it up to 40 classes and my second batch has 50 classes, so it encode it up to 50 classes. Shouldnot it be 60 class encoding in all batches?</p>

username: KFrank
cooked: <p>Hi Talha!</p>
<aside class="quote no-group" data-username="talhaanwarch" data-post="1" data-topic="127676" data-full="true">
<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/talhaanwarch/48/26568_2.png" class="avatar"> talhaanwarch:</div>
<blockquote>
<p>Shouldnot it be 60 class encoding in all batches?</p>
</blockquote>
</aside>
<p>Yes, you should encode all 60 classes for all of your batches even<br>
if some batches don’t <em>happen to have</em> all 60 classes in them.</p>
<p>To expand on this a little:  Your network architecture will have the<br>
60 classes built into it (at least in standard approaches).  Let’s say<br>
that we label your 60 classes with the integers 0, …, 59.  Now let’s<br>
say that a particular batch happens to have only three classes in it,<br>
specifically 3, 27, and 45.  If you were to label this batch with, say, 0,<br>
1, and 2, so that you gave class-27 the label 1, your network wouldn’t<br>
know what that meant.</p>
<p>As an aside, whether you use one-hot encoding or something else<br>
to label your classes is irrelevant to this question – you need all 60<br>
either way.  Having said that, you shouldn’t be using one-hot encoding.<br>
Semantic segmentation is a classification problem (You classify<br>
individual pixels.), so you would most typically use some version<br>
of a cross-entropy-like loss function.  Pytorch’s  cross-entropy loss<br>
functions use integer categorical class labels (like I alluded to, above),<br>
and don’t work with one-hot encoding.</p>
<p>(You should also be aware that people sometimes – mistakenly – use<br>
the term “one hot” to refer class labels of any sort, even if they are<br>
not actually one-hot encoded.  This, of course, can be confusing.)</p>
<p>Best.</p>
<p>K. Frank</p>

username: talhaanwarch
cooked: <p>I am using pytorch one hot function for this, in each batch I applied this function. do I need to some thing extra or this function internally manage that.<br>
what other way is that find those images which have all 60 labels, use sklean one hot encoder and fit on it  then on all rest of images, just transform it</p>

username: KFrank
cooked: <p>Hi Talha!</p>
<aside class="quote no-group" data-username="talhaanwarch" data-post="3" data-topic="127676" data-full="true">
<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/talhaanwarch/48/26568_2.png" class="avatar"> talhaanwarch:</div>
<blockquote>
<p>I am using pytorch one hot function</p>
</blockquote>
</aside>
<p>Why are you using <a href="https://pytorch.org/docs/1.9.0/generated/torch.nn.functional.one_hot.html" rel="noopener nofollow ugc">torch.nn.functional.one_hot()</a>?  I noted in my<br>
previous that you probably <em>don’t</em> want to use <code>one_hot()</code>.  What<br>
is your specific goal?</p>
<aside class="quote no-group">
<blockquote>
<p>what other way is that find those images which have all 60 labels</p>
</blockquote>
</aside>
<p>Why do you want to find those images that have all 60 labels?<br>
(It’s at least a possibility that <em>no</em> single image has <em>all</em> of the labels.)</p>
<p>What is your actual use case?  What is your larger goal here?</p>
<p>Best.</p>
<p>K. Frank</p>

username: talhaanwarch
cooked: <p>I am trying to calculate dice coefficient for that purpose I need to average each class. for that I need one hot encoded vector. here is code</p>
<pre><code class="lang-auto">from einops import rearrange
def dice_coef_multilabel(mask_pred,mask_gt  ):
    def compute_dice_coefficient(mask_pred,mask_gt, smooth = 0.0001):
      """Compute soerensen-dice coefficient.
      compute the soerensen-dice coefficient between the ground truth mask `mask_gt`
      and the predicted mask `mask_pred`. 

      Args:
        mask_gt: 4-dim Numpy array of type bool. The ground truth mask. [B, 1, H, W]
        mask_pred: 4-dim Numpy array of type bool. The predicted mask. [B, C, H, W]
      Returns:
        the dice coeffcient as float. If both masks are empty, the result is NaN
      """
      volume_sum = mask_gt.sum() + mask_pred.sum()
      
      volume_intersect = (mask_gt * mask_pred).sum()
      return (2*volume_intersect+smooth) / (volume_sum+smooth)
    dice=0
    n_pred_ch = mask_pred.shape[1]
    mask_pred=torch.softmax(mask_pred, 1)
    mask_gt=F.one_hot(mask_gt.long(), num_classes=n_pred_ch) #create one hot vector
    mask_gt=rearrange(mask_gt, 'd0 d1 d2 d3 d4 -&gt; d0 (d1 d4) d2 d3 ')  #reshape one hot vector

    for ind in range(1,n_pred_ch):
        dice += compute_dice_coefficient(mask_gt[:,ind,:,:], mask_pred[:,ind,:,:])
    return dice/n_pred_ch # taking average
</code></pre>

username: KFrank
cooked: <p>Hi Talha!</p>
<aside class="quote no-group" data-username="talhaanwarch" data-post="5" data-topic="127676" data-full="true">
<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/talhaanwarch/48/26568_2.png" class="avatar"> talhaanwarch:</div>
<blockquote>
<p>I am trying to calculate dice coefficient</p>
</blockquote>
</aside>
<p>Okay, for Dice loss, <code>one_hot()</code> makes sense.</p>
<aside class="quote no-group">
<blockquote>
<pre><code class="lang-auto">    mask_gt=F.one_hot(mask_gt.long(), num_classes=n_pred_ch) #create one hot vector
</code></pre>
</blockquote>
</aside>
<p>This line from the code you’ve posted seems to indicate that you’ve<br>
answered your own question.</p>
<p>To repeat my question from my previous post:  Why do you want to<br>
find those images that have all 60 labels?</p>
<p>As an aside, some people find that for semantic segmentation using<br>
Dice loss to augment <code>CrossEntropyLoss</code> works better than using<br>
Dice loss in isolation.  You might want to explore that after you get<br>
your Dice loss working.</p>
<p>Best.</p>
<p>K. Frank</p>