Transforms Random Crop Class

username: quornmd
cooked: <p>Hi,<br>
I am fairly new to python and Pytorch.</p>
<p>I am trying to use the Dataset and Dataloader classes with transformations. In particular, I wrote my own class simply applying torchvision.transforms.RandomResizedCrop to the images while passing in the size and scale parameter of RrandomResizedCrop in:</p>
<pre><code class="lang-auto">class ThisDataset(Dataset): #shortened here
    def __init__(transform=None):
        ....
    def __len__(self):
        ....
    def __getitem__(self, idx):
        ....
        image = Image.open(img_name)
        ....
        sample = {'image': image, 'labels': labels}
        if self.transform:
            sample = self.transform(sample)
        return sample


class RandCrop(object):
     def __init__(self, size, scale):
         self.crop = torchvision.transforms.RandomResizedCrop(size=size, scale=scale)

     def __call__(self, sample):
         image, labels = sample['image'], sample['labels']
         image = self.crop(image)
         return {'image': image,
                 'labels': labels}

</code></pre>
<p>This is called with the Dataset and DataLoader class as follows:</p>
<pre><code class="lang-auto">crop_size = 224
crop_range = (0.8,1)

dataset = ThisDataset('data_small/train.csv', transform=torchvision.transforms.Compose([RandCrop(size = crop_size, scale = crop_range), ToTensor()]))
dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True, num_workers=2)

</code></pre>
<p>When I attempt this I get this error message:</p>
<pre><code class="lang-auto">Traceback (most recent call last):
  File "&lt;input&gt;", line 27, in &lt;module&gt;
TypeError: __init__() missing 2 required positional arguments: 'size' and 'scale'

</code></pre>
<p>Why do I get this error? Is there a better way to do it?</p>
<p>Thanks in advance</p>

username: ptrblck
cooked: <p>I cannot reproduce this error, but ran into other issues.<br>
While your custom transformation returns a <code>dict</code> with the image and label, the standard <code>torchvision.transforms</code> do not accept this kind of input.<br>
You could unwrap the <code>dict</code>, transform the <code>image</code> to a tensor separately and recreate the <code>dict</code> again:</p>
<pre><code class="lang-python">class ThisDataset(Dataset): #shortened here
    def __init__(self, transform=None):
        self.transform = transform
        self.data = torch.randn(10, 3, 224, 224)
        
    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, idx):
    
        image = transforms.ToPILImage()(self.data[idx])
        
        sample = {'image': image, 'labels': torch.randint(0, 2, (1,))}
        if self.transform:
            sample = self.transform(sample)
        image, labels = sample['image'], sample['labels']
        x = transforms.ToTensor()(image)
        y = labels
        sample = {'image': x, 'labels': y}
        return sample


class RandCrop(object):
     def __init__(self, size, scale):
         self.crop = transforms.RandomResizedCrop(size=size, scale=scale)

     def __call__(self, sample):
         image, labels = sample['image'], sample['labels']
         image = self.crop(image)
         return {'image': image,
                 'labels': labels}


crop_size = 224
crop_range = (0.8,1)

dataset = ThisDataset(transform=transforms.Compose([RandCrop(size = crop_size, scale = crop_range)]))
dataloader = DataLoader(dataset=dataset, batch_size=1, shuffle=True, num_workers=0)

batch = next(iter(dataloader))
</code></pre>