How to create a balancing cycling iterator in PyTourch?
Say I have 2 classes. And for one I have only 17 samples and for another 83. I want to always have equal amount of data from each class per epoch (meaning 17 by 17 in this case). Also, I want to slide sampling a window across the class where I have more data each epoch (first 17, next 17, ...).
Currently I have a looping sampling iterator like this:
class CyclicIterator:
    def __init__(self, loader, sampler):
        self.loader = loader
        self.sampler = sampler
        self.epoch = 0
        self._next_epoch()

    def _next_epoch(self):
        self.iterator = iter(self.loader)
        self.epoch += 1

    def __len__(self):
        return len(self.loader)

    def __iter__(self):
        return self

    def __next__(self):
        try:
            return next(self.iterator)
        except StopIteration:
            self._next_epoch()
            return next(self.iterator)

I wonder how to force all samples from each class to be of equal count per epoch?

For a balanced batch, which means equal (or close to equal) number of samples per category in each batch, there are some approaches:
-Oversampling (make minor sized classes oversample until reach highest number of samples). In this approach you can use following code:
https://github.com/galatolofederico/pytorch-balanced-batch
-Undersampling (delivers number of samples for all categories based in smallest category number). In my experience, below function does like that using PyTorch library:
torch.utils.data.sampler.WeightedRandomSampler(weights, len(weights))

Where weights is the probability of each sample, it depends in how many samples per category you have, for instance, if you data is simple as that data = [0, 1, 0, 0, 1], class '0' count is 3, and class '1' count is 2 So weights vector is [1/3, 1/2, 1/3, 1/3, 1/2]. With that you can call WeightedRamdomSampler and it will make it for you.
You need to call it in Dataloader. The code to setup it is:
sampler = torch.utils.data.sampler.WeightedRandomSampler(weights, len(weights))
train_dataloader = DataLoader(dataset_train, batch_size=mini_batch,
                              sampler=sampler, shuffle=False,
                              num_workers=1)

