Dataloader for semantic segmentation

username: Nishanth_Sasankan
cooked: <p>Hi Everyone,</p>
<p>I am very new to Pytorch and deep learning in general. I am having 2 folders one with images and another with the pixel labels of the corresponding images. I would like to know how to use the dataloader to make a train_loader and validation_loader if the only thing I know is the path to these folders. I am trying to do something similar to</p>
<p><a href="https://pytorch.org/tutorials/beginner/data_loading_tutorial.html" class="onebox" target="_blank" rel="nofollow noopener">https://pytorch.org/tutorials/beginner/data_loading_tutorial.html</a><br>
but instead of the csv file in the tutorial I have a png pixellabel map for every images. All or Any help is appreciated.<br>
Thanks<br>
Nishanth</p>

username: Balamurali_M
cooked: <p>I am assuming there is a folder which contains sub-folders image and mask. The filenames are same. This is a template you can modify it and use. All the best.</p>
<pre><code class="lang-auto">import torch.utils.data as data

class DataLoaderSegmentation(data.Dataset):
    def __init__(self, folder_path):
        super(DataLoaderSegmentation, self).__init__()
        self.img_files = glob.glob(os.path.join(folder_path,'image','*.png')
        self.mask_files = []
        for img_path in img_files:
             self.mask_files.append(os.path.join(folder_path,'mask',os.path.basename(img_path)) 

    def __getitem__(self, index):
            img_path = self.img_files[index]
            mask_path = self.mask_files[index]
            data = use opencv or pil read image using img_path
            label =use opencv or pil read label  using mask_path
            return torch.from_numpy(data).float(), torch.from_numpy(label).float()

    def __len__(self):
        return len(self.img_files)

</code></pre>

username: Nishanth_Sasankan
cooked: <p><a class="mention" href="/u/balamurali_m">@Balamurali_M</a>  Thank you very much, I will try this</p>

username: Nishanth_Sasankan
cooked: <p>This helped me a lot, I have a question regarding one of the lines in your code. Why do this</p>
<pre><code class="lang-auto">for img_path in img_files:
             self.mask_files.append(os.path.join(folder_path,'mask',os.path.basename(img_path)) 
</code></pre>
<p>and not use the glob.glob method for img_files? Wouldn’t the label files be in the same order as the img_files if they both have the same name?</p>

username: Balamurali_M
cooked: <p>I was assuming two separate folder with same filenames. You can use it accordingly.</p>

username: Rishav_Sapahia
cooked: <p>I applied a similar approach but I am getting error <code>TypeError: expected np.ndarray (got Tensor)</code>. What I am doing wrong?</p>

username: Nishanth_Sasankan
cooked: <p>You need to be more specific in your error. Maybe paste the line in the code to which the error is associated. All I know from looking from your error is that some variable in your code is expecting a numpy variable and your code is  providing it with a torch tensor variable. It would be very hard to say what you are doing wrong. It would be like my code gives the error (expected character got integer).</p>

username: Rishav_Sapahia
cooked: <p>I resolved it, though I am encountering some other error. Did you applied same transformations to both images and mask. i have the following transformations-</p>
<pre><code class="lang-auto">data_transforms = transforms.Compose([transforms.RandomCrop((512,512)),
                                 transforms.Lambda(gaussian_blur),
                                 transforms.Lambda(elastic_transform),
                                 transforms.RandomRotation([+90,+180]),
                                 transforms.RandomRotation([+180,+270]),
                                 transforms.RandomHorizontalFlip(),
                                 transforms.ToTensor(),
                                 transforms.Normalize(mean=train_mean, std=train_std)
                               ])
</code></pre>
<p>Here, rotation, flips are to be applied to both images and mask and rest of the transforms only to the images, I followed  <a href="https://discuss.pytorch.org/t/torchvision-transfors-how-to-perform-identical-transform-on-both-image-and-target/10606/7">this</a> post but I can’t use <code>lambda transforms</code> using this way.So I am just thinking of a workaround it?</p>

username: Nishanth_Sasankan
cooked: <p>I have not used transforms for my  image , as I have a very large dataset. But if I am using transforms, the same transforms have to be applied to image and mask. Since you are using random rotations and flip, make sure your image mask pair g through the same random transforms.</p>
<p>i:e if ImageA is randomly rotated by 10 degrees, make sure MaskA is also rotated by 10 degrees.</p>

username: Balamurali_M
cooked: <p>Did you figure out a way to augment both image and mask together ?</p>

username: Rishav_Sapahia
cooked: <p>Yes, Thanks.<br>
I did it by customizing the data-loader class.Something like this-</p>
<pre><code class="lang-auto">class customdataloader():
       def transform(self,image,mask):
             image = TF.rotate(image,90)
             mask = TF.rotate(mask,90)

</code></pre>

username: Balamurali_M
cooked: <p>Perfect. I did something similar recently.</p>