How to apply another transform to an existing Dataset?

username: swim_airport
cooked: <p>This is a code example:</p>
<pre><code class="lang-python">dataset = datasets.MNIST(root=root, train=istrain, transform=None)  #preserve raw img

print(type(dataset[0][0]))
# &lt;class 'PIL.Image.Image'&gt;

dataset = torch.utils.data.Subset(dataset, indices=SAMPLED_INDEX) # for resample

for ind in range(len(dataset)):
    img, label = dataset[ind] # &lt;class 'PIL.Image.Image'&gt; &lt;class 'int'&gt;/&lt;class 'numpy.int64'&gt;
    img.save(fp=os.path.join(saverawdir, f'{ind:02d}-{int(label):02d}.png'))

dataset.transform = transforms.Compose([
                transforms.RandomResizedCrop(image_size),
                transforms.ToTensor(),
                transforms.Normalize((0.1307,), (0.3081,))
            ])
#transform for net forwarding

print(type(dataset[0][0]))
# expected &lt;class 'torch.Tensor'&gt;, however it's still &lt;class 'PIL.Image.Image'&gt;
</code></pre>
<p>Since dataset is randomly resampled, I don’t want to reload a new dataset with <code>transform</code>, but just apply <code>transform</code> to the already existing dataset.</p>
<p>Thanks for your help <img src="https://discuss.pytorch.org/images/emoji/apple/smiley.png?v=9" title=":smiley:" class="emoji" alt=":smiley:"></p>

username: ptrblck
cooked: <p><code>Subset</code> will wrap the passed <code>Dataset</code> in the <code>.dataset</code> attribute, so you would have to add the transformation via:</p>
<pre><code class="lang-python">dataset.dataset.transform = transforms.Compose([
                transforms.RandomResizedCrop(28),
                transforms.ToTensor(),
                transforms.Normalize((0.1307,), (0.3081,))
            ])
</code></pre>
<p>Your code should work without the usage of <code>Subset</code>.</p>

username: Zain_Ahmad
cooked: <p>I using the same code but its not working for me…<br>
I have initially created a dataset from ImageFolder and than used random_split to get the train and val sets and than I am trying to apply transformations with the method above but its not working</p>

username: fibikong
cooked: <p>I met same problem. I think transformation can’t be applied to dataset.Subset. If you solved this problem, please let me know.</p>

username: ptrblck
cooked: <p>Transformations work with <code>Subset</code>s as seen here:</p>
<pre><code class="lang-python"># not recommended approach of setting the transform attribute late
dataset = datasets.MNIST(root='/home/pbialecki/python/data', train=True, transform=None, download=False)

print(type(dataset[0][0]))
# &gt; &lt;class 'PIL.Image.Image'&gt;

dataset = torch.utils.data.Subset(dataset, indices=torch.arange(10))
print(type(dataset[0][0]))
# &gt; &lt;class 'PIL.Image.Image'&gt;

dataset.dataset.transform = transforms.Compose([
                transforms.RandomResizedCrop(20),
                transforms.ToTensor(),
                transforms.Normalize((0.1307,), (0.3081,))
            ])


print(type(dataset[0][0]))
# &gt; &lt;class 'torch.Tensor'&gt;

# recommended approach
transform = transforms.Compose([
    transforms.RandomResizedCrop(20),
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
dataset = datasets.MNIST(root='/home/pbialecki/python/data', train=True, transform=transform, download=False)

print(type(dataset[0][0]))
# &gt; &lt;class 'torch.Tensor'&gt;

dataset = torch.utils.data.Subset(dataset, indices=torch.arange(10))
print(type(dataset[0][0]))
# &gt; &lt;class 'torch.Tensor'&gt;
</code></pre>
<p>As previously described: if you want to add the transformation to the internal <code>.transform</code> attribute late (I would not recommend to use this approach) you would have to index the internal <code>dataset</code> via <code>dataset.dataset.transform</code>.</p>

username: fibikong
cooked: <p>Thanks for your more detailed explanation.<br>
and can I know why you don’t recommend the first approach?</p>

username: ptrblck
cooked: <p>Manipulating the internal <code>.transform</code> attribute assumes that <code>self.transform</code> is indeed used to apply the transformations.<br>
While this might be the case for e.g. <code>MNIST</code> other datasets could use other attributes (e.g. <code>self.image_fransform</code>) and you would need to add this manipulation according to the real implementation (which could of course also change between releases).<br>
The right approach is thus to set the transformations once during the initialization of the <code>Dataset</code> and allow the <code>Dataset</code> to handle the transformations internally without depending on its actual implementation.</p>