Dataset class with multiple Inputs/Outputs images

FiReTiTi: <p>I’ve to create a Dataset class that can read/generate batches for problems with  <code>Nin</code> images as inputs and  <code>Nout</code>  images as outputs.<br>
I know how to do such class, but I don’t know how to format such inputs / outputs in order to be supported by the DataLoader.</p>

ptrblck: <p>Could you explain a bit more about the use case?<br>
I don’t understand how you are passing some images into a <code>Dataset</code> and get another number as the output.</p>

FiReTiTi: <p>It’s a segmentation problem with multiple classes: 1 to 3 images as input depending on the experiment, and up to 10 classes to segment.<br>
We could simplify the problem in single class segmentation, but we also would like to try to detect them all at once.</p>

ptrblck: <p>The number of input images changes for every sample?<br>
I.e. sometimes the current sample has only 1 input image and other times it has 3?</p>
<p>Usually all classes of a segmentation are saved in one segmentation map (similar to an image), so that we could possibly return just one segmentation target containing all 10 classes.</p>

FiReTiTi: <ul>
<li>No, the number of input images will be fixed, so we’ll develop one model per number of input.</li>
<li>We would like to keep them separated. Is that doable? I used to work with Keras and it’s doable.</li>
</ul>

ptrblck: <p>What would be the advantage of having 10 different targets?<br>
Could you explain, how you’ve processed the targets using Keras?</p>

FiReTiTi: <ul>
<li>Some outputs might have overlaps</li>
<li>Keras considers multiple inputs/outputs as a list, so it’s easy to develop such models.</li>
</ul>

ptrblck: <p>If the outputs have overlaps, you’re dealing with a multi-label classification use case, i.e. each pixel might belong to more than one class?<br>
If so, you could still use a single segmentation map and just return multi-label predictions.</p>
<p>I’m still not understanding, how Keras deals with this problem.<br>
For example, if one pixel belongs to class1 and class2 at the same time. You would force your model to learn it as class1 in one iteration and class2 in another one?<br>
Would your model be able to predict more than one class for each pixel then?</p>
<p>I’m digging a bit deeper, as your use case is most likely possible to implement, I just have my doubts about the correctness.</p>

Kartik_Chopra: <p>What happens in the case if the classes overlap ? Multi-label for each pixel. How do you prepare the mask for that ? I have 4 separate masks corresponding to same input image. How should I combine them as each pixel can belong to 1 or more classes ?</p>

ptrblck: <p>In this case, each channel would correspond to a specific class.<br>
A <code>1</code> at a particular pixel position would represent the occurrence of the corresponding class, while a <code>0</code> would be used for its absence.<br>
Also, for this use case you could use <code>nn.BCE(WithLogits)Loss</code> as your criterion.</p>

Kartik_Chopra: <p>Thats exactly what I did. So my labels are now <code>[batch, 4, 224, 224]</code>. The training is fine but I’m not able to calculate IoU having 4 separate masks. Any help how that can be achieved so that I can get per class IoU ?</p>

ptrblck: <p><a href="https://discuss.pytorch.org/t/iou-pytorch-implementation/21473/3">This post</a> with <a class="mention" href="/u/tom">@tom</a>’s implementation might be useful.</p>

Kartik_Chopra: <p>Thanks, I’ll go through that. However, will i need to calculate IoU per class by splitting the labels into separate classes ?</p>

ptrblck: <p>You would most likely have to process each class channel separately with its corresponding output channel.</p>

Kartik_Chopra: <p>Does that mean my predictions will also have dimension like <code>[batch, 4, 224, 224]</code> ? How would I turn my logits into predictions ? If I use argmax along the channel dimension, I will only get 1 prediction. Do I run the logits through a Sigmoid layer and then threshold using <code>pred = logits &gt; 0.5</code> ?</p>

ptrblck: <p>Yes, the output shape of your model would be the same as the targets in this use case.<br>
To get the predictions you could apply <code>preds = logits &gt; 0.</code> or alternatively <code>preds = torch.sigmoid(logits) &gt; 0.5</code>, which would yield the same result.</p>

anujd9: <p>Hi <a class="mention" href="/u/ptrblck">@ptrblck</a>, thanks for your explanation above. I am also working on training an image segmentation model with 5 classes where a part of 1-2 classes overlap with each other. See this image for example: <img src="https://discuss.pytorch.org/uploads/default/original/3X/6/6/66c94e76c667999c6ccb2762c3a647f1a0fad202.jpeg" alt="image" data-base62-sha1="eFhZWOOCWYcg2YVzIEcVoPN8Yts" width="374" height="135"><br>
Here the left is the original Grayscale image and right is the segmentation map. The green portion remains the same across different structures, but at some places, the green segment might be overlapped a bit with the blue one. For example, see the middle bottom segmentation. In terms of annotation, the green annotation is done for an area first and then the blue annotation is done on top of that i.e. the pixels at that location belong to two classes.<br>
So, how do I represent the dataset and train the model for this scenario ? Any suggestions ? I am able to stack the segmentation belonging to different classes across channels at the input but how to deal with the overlap during training ? Will the model be able to learn that overlap ?<br>
Thanks <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>

ptrblck: <p>You can stack the one-hot encoded segmentation maps to create a target in the shape <code>[batch_size, nb_classes, height, width]</code>, where the <code>nb_classes</code> channel indicates if the current class is active or not by using ones and zeros, repsectively.<br>
E.g. assuming the blue class represents class0 while the green represents class1, the target would have ones in channel0 and channel1 for these pixel locations.</p>
<p>To train such a multi-label segmentation you could use <code>nn.BCEWithLogtisLoss</code> as the criterion.</p>

anujd9: <p>Thanks a lot <a class="mention" href="/u/ptrblck">@ptrblck</a>. How does this work when two encodings overlap over a small area ? Will the model be able to differentiate between those overlapping labels if they are one hot encoded ? Btw I am using a DeepLab v3 model for this task. Also looking at the UNet as well. Thanks <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

ptrblck: <p>Since each class channel contains a separate one-hot encoded target map, these particular pixel will have multiple active classes in the class dimension.<br>
The complete target is multi-hot encoded.</p>