Simoultaneous data augmentation and class balancing?

username: Berta_Biescas
cooked: <p>Hi all,<br>
I want to enlarge my dataset and balance classes at the same time. I’m using random transforms to ensure new images at each batch and WeightedRandomSampler  to try to balance the classes.<br>
However, I don’t know how to check if classes are balance or not over the entire data set, since the sampler is acting over each batch. Does anyone have dealt with this problem? I’m new in pytorch. Thanks!<br>
This is my code, I check the number of instances for each class, before the sampler and after the sampler, and didn’t get the balance. Any suggestion? What I’m doing wrong?<br>
transform = {‘train’:transforms.Compose([transforms.Resize((32,32)),<br>
transforms.RandomHorizontalFlip(),<br>
transforms.RandomRotation(10),<br>
transforms.RandomAffine(0,shear = 10, scale = (0.8, 1.2)),<br>
transforms.ColorJitter(brightness = 0.2, contrast = 0.2, saturation = 0.2),<br>
transforms.ToTensor(),<br>
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]),<br>
‘val’: transforms.Compose([transforms.Resize((32,32)),<br>
transforms.ToTensor(),<br>
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])<br>
}</p>
<p>image_data = torchvision.datasets.ImageFolder(data_path,transform[‘train’])</p>
<p>image_loader=torch.utils.data.DataLoader(image_data, batch_size=batch_size_t, shuffle=True)</p>
<h1>Data set with tranforms</h1>
<p>labels = []<br>
for image, label in image_loader:<br>
for item in label.numpy():<br>
labels.append(class_names[item])</p>
<p>labels=np.array(labels)</p>
<h1>Check the number of instances for each class</h1>
<p>for i in range(0,len(class_names)):<br>
print('Instances in class ‘+ str(class_names[i])+’: ’ + str(len(np.where(labels == class_names[i])[0])))</p>
<h1>Calculate the samples weights for the WeightedRandomSampler</h1>
<p>weight = np.arange(0,len(class_names)).astype(np.float32)</p>
<p>for j in range(0,len(class_names)):<br>
weight[j] = 1/len(np.where(labels == class_names[j])[0])</p>
<p>samples_weight = []</p>
<p>for image,label in image_loader :<br>
for item in label.numpy():<br>
samples_weight.append(weight[item])</p>
<p>samples_weight = np.array(samples_weight)</p>
<p>samples_weight = torch.from_numpy(samples_weight)<br>
samples_weigth = samples_weight.double()<br>
sampler = WeightedRandomSampler(samples_weight, len(samples_weight))</p>
<p>image_data = torchvision.datasets.ImageFolder(data_path,transform[‘train’])<br>
image_loader = DataLoader(image_data, batch_size=batch_size_t, num_workers=4, sampler=sampler)</p>
<p>labels = []<br>
for image, label in image_loader:<br>
for item in label.numpy():<br>
labels.append(class_names[item])</p>
<p>labels=np.array(labels)</p>
<h1>Check the number of instances for each class after sampler</h1>
<p>print(’---------------------------------------------------’)<br>
for i in range(0,len(class_names)):<br>
print('Instances in class ‘+ str(class_names[i])+’: ’ + str(len(np.where(labels == class_names[i])[0])))</p>

username: tom
cooked: <aside class="quote no-group" data-username="Berta_Biescas" data-post="1" data-topic="97243">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/berta_biescas/48/29040_2.png" class="avatar"> Berta_Biescas:</div>
<blockquote>
<p>I want to enlarge my dataset and balance classes at the same time. I’m using random transforms to ensure new images at each batch and WeightedRandomSampler to try to balance the classes.<br>
However, I don’t know how to check if classes are balance or not over the entire data set, since the sampler is acting over each batch. Does anyone have dealt with this problem?</p>
</blockquote>
</aside>
<p>I think the check you implemented should work (though using np.unique probably would be more efficient than handling each class with np.where). Where are you experiencing difficulties with it?</p>
<p>Best regards</p>
<p>Thomas</p>
<p>P.S.: If you enclose your code in triple backticks ``` , it’ll keep the formatting.</p>

username: Berta_Biescas
cooked: <p>Hi Tom, thanks for your suggestion. My main problem is that I don’t know how to check the number of instances for each class is balanced. I’ve tried to follow some approaches of this forum, but I think, classes are still unbalanced. Thanks.</p>

username: tom
cooked: <p>But what do you get as output when you run your code?</p>

username: Berta_Biescas
cooked: <p>The output consists on the number of instances that I have for each class before and after the sampler. Numbers are almost the same, I just get slightly differences. Am I wrongly counting  the instances?</p>
<p>Output:</p>
<p>Instances in class 0: 127<br>
Instances in class 1: 131<br>
Instances in class 2: 38<br>
Instances in class 3: 154<br>
Instances in class 4: 49<br>
Instances in class 5: 130<br>
Instances in class 6: 264<br>
Instances in class 7: 44<br>
Instances in class 8: 68<br>
Instances in class 9: 242<br>
Instances in class 10: 64<br>
Instances in class 11: 40</p>
<hr>
<p>Instances in class 0: 120<br>
Instances in class 1: 132<br>
Instances in class 2: 35<br>
Instances in class 3: 174<br>
Instances in class 4: 50<br>
Instances in class 5: 133<br>
Instances in class 6: 285<br>
Instances in class 7: 29<br>
Instances in class 8: 66<br>
Instances in class 9: 213<br>
Instances in class 10: 71<br>
Instances in class 11: 43</p>

username: tom
cooked: <p>Ah, sorry. I think you want replacement=True (and set some numberof samples) in the sampler.</p>

username: Berta_Biescas
cooked: <p>Thanks Tom, I followed your suggestion, but apparently classes remain unbalanced. I can’t understand well how weights work in sampler, because I’ve tried with different approaches and I can’t control the resulting number of instances.</p>