AttributeError: 'Subset' object has no attribute 'targets'

username: kowshik_thopalli
cooked: <p>Lets say I load ia dataset using <code>ImageFolder</code> because my data is structured that way.<br>
Now I pick <code>k</code> indices of my choice and use <code>torch.utils.data.Subset</code> to create a subset dataset.<br>
Now, for these images I want to modify the <code>targets</code> and give my own <code>labels</code>.<br>
How do I do it?<br>
Currently, the error is this <code>AttributeError: 'Subset' object has no attribute 'targets'</code></p>

username: kowshik_thopalli
cooked: <p>ok.  I solved this issue with the following.<br>
Leaving it here for others</p>
<pre><code class="lang-auto">
from torch.utils.data import Dataset
class my_subset(Dataset):
    r"""
    Subset of a dataset at specified indices.

    Arguments:
        dataset (Dataset): The whole Dataset
        indices (sequence): Indices in the whole set selected for subset
        labels(sequence) : targets as required for the indices. will be the same length as indices
    """
    def __init__(self, dataset, indices,labels):
        self.dataset = dataset
        self.indices = indices
        labels_hold = torch.ones(len(dataset)).type(torch.long) *300 #( some number not present in the #labels just to make sure
        labels_hold[self.indices] = labels 
        self.labels = labels_hold
    def __getitem__(self, idx):
        image = self.dataset[self.indices[idx]][0]
        label = self.labels[self.indices[idx]]
        return (image, label)

    def __len__(self):
        return len(self.indices)
</code></pre>

username: theairbend3r
cooked: <p>Hey, could you explain what how you solved it?<br>
I currently face this issue : I Read an image dataset using ImageFolder =&gt; Created train+val set using <code>random_split()</code> =&gt; tried to do <code>train_set.classes</code> and got the same attribute error you got.</p>
<p>What does it mean?</p>

username: Shahid_Siddiqui
cooked: <p>Thank you so much for sharing, worked like a charm.</p>

username: surajkothawade
cooked: <p>Keeping the same terminology as pytorch and avoiding two level indexing one could instead use:</p>
<pre><code class="lang-auto">from torch.utils.data import Dataset
class custom_subset(Dataset):
    r"""
    Subset of a dataset at specified indices.

    Arguments:
        dataset (Dataset): The whole Dataset
        indices (sequence): Indices in the whole set selected for subset
        labels(sequence) : targets as required for the indices. will be the same length as indices
    """
    def __init__(self, dataset, indices, labels):
        self.dataset = torch.utils.data.Subset(dataset, indices)
        self.targets = labels
    def __getitem__(self, idx):
        image = self.dataset[idx][0]
        target = self.targets[idx]
        return (image, target)

    def __len__(self):
        return len(self.targets)
</code></pre>

username: 111500
cooked: <p>Oh my goodness!<br>
Thank you!<br>
I’ve working with the problem for about 40 hours LOL!</p>

username: Minqi_Jiang
cooked: <p>Maybe simply replacing the original attribute by the new attribute can be an effective way:</p>
<pre><code class="lang-auto">#load dataset
train_set = MyMNIST(root=self.root, train=True, transform=transform, download=False)

# subset training set
index_sub = np.random.choice(np.arange(len(train_set)), 10000, replace=False)

#replacing attribute
train_set.data = train_set.data[index_sub]
train_set.targets = train_set.targets[index_sub]
train_set.semi_targets = train_set.semi_targets[index_sub]
</code></pre>