Transforms Random Crop Class

Hi,
I am fairly new to python and Pytorch.

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:

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}

This is called with the Dataset and DataLoader class as follows:

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)

When I attempt this I get this error message:

Traceback (most recent call last):
  File "<input>", line 27, in <module>
TypeError: __init__() missing 2 required positional arguments: 'size' and 'scale'

Why do I get this error? Is there a better way to do it?

Thanks in advance

I cannot reproduce this error, but ran into other issues.
While your custom transformation returns a dict with the image and label, the standard torchvision.transforms do not accept this kind of input.
You could unwrap the dict, transform the image to a tensor separately and recreate the dict again:

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))