In multi-classes segmentation,should the output channel be C or C+1?

Alex_Luya: <p>For example,in a dataset which contains cats and dogs,<br>
In C==1 case,the requirements is:<br>
<code>    Just segmenting out cats,treating all others as background(of course target will just label cats as 1,set all other pixels to 0)</code><br>
In this case,should the output channel be 1 or 2?<br>
In my opinion,it can be either 1 or 2,if setting output channel to 1,just use BCELossWithLogits,and if set it to 2,we must one-hot encoding targets firstly,then use BCELossWithLogits,<br>
am I right about this first case?</p>
<p>In C&gt;1 case,requirement is:<br>
<code>Segmenting out cats And Dogs</code><br>
I this case should the output channel be 2 or 2+1(background),in other words,should be C or C+1(background) if C&gt;1?<br>
In my opinion,it must 3(C+1) that the background must be treated as a class,am I right about this second case?</p>

ptrblck: <p>For a binary classification use case, you can use either one or two output channels.<br>
For a single channel output, you could use <code>nn.BCEWithLogitsLoss</code>.<br>
If you are using two output channels, you could treat your use case as a</p>
<ul>
<li>multi-class classification (only one valid class per pixel) and use <code>nn.CrossEntropyLoss</code>
</li>
<li>or as a multi-label classfication (zero, one or more classes valid per pixel), in which case you would again use <code>nn.BCEWithLogitsLoss</code>
</li>
</ul>
<p>The background would also represent a class as answered in <a href="https://discuss.pytorch.org/t/when-using-crossentropyloss-for-segmentation-how-to-encode-labels-into-single-channel-target-image-if-value-c-is-a-must-be/65862/2">your other topic</a>.</p>

krioux5: <aside class="quote no-group" data-username="ptrblck" data-post="2" data-topic="65861">
<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>ification (only one valid class per pixel) and use <code>nn.CrossEntropyLoss</code></p>
</blockquote>
</aside>
<p>I got a binary segmentation problem working but am now modifying to be multi-class, labels[0,1,2…8]. I changed my loss function to crossentropyloss (previously BCEwithlogicloss), however I am now seeing error:</p>
<p>File “/home/user/miniconda3/envs/3dunet/lib/python3.7/site-packages/torch/nn/functional.py”, line 1848, in nll_loss<br>
out_size, target.size()))<br>
ValueError: Expected target size (2, 80, 160, 160), got torch.Size([2, 1, 80, 160, 160])</p>
<p>I am not sure where this extra dimension would be coming from, I also had to change the output of my network to 9 channels (C+1) as it was only 1 for the binary seg.</p>
<p>Any ideas? Thanks,</p>
<p>Kyle</p>

ptrblck: <p>Based on the expected target shape I assume you are dealing with outputs as volumes, where each voxel would be classifies into one of the 9 classes?<br>
If that’s correct, you would have to remove <code>dim1</code> via <code>target = target.squeeze(1)</code>.<br>
I don’t know where it’s coming from, but feel free to post the <code>Dataset</code> code (including shape information) so that we could have a look at it.</p>