| 4 | |
| 5 | |
| 6 | class CategoriesSampler(): |
| 7 | |
| 8 | def __init__(self, label, n_batch, n_cls, n_per, ): |
| 9 | self.n_batch = n_batch # the number of iterations in the dataloader |
| 10 | self.n_cls = n_cls |
| 11 | self.n_per = n_per |
| 12 | |
| 13 | label = np.array(label) # all data label |
| 14 | self.m_ind = [] # the data index of each class |
| 15 | for i in range(max(label) + 1): |
| 16 | ind = np.argwhere(label == i).reshape(-1) # all data index of this class |
| 17 | ind = torch.from_numpy(ind) |
| 18 | self.m_ind.append(ind) |
| 19 | |
| 20 | def __len__(self): |
| 21 | return self.n_batch |
| 22 | |
| 23 | def __iter__(self): |
| 24 | |
| 25 | for i_batch in range(self.n_batch): |
| 26 | batch = [] |
| 27 | classes = torch.randperm(len(self.m_ind))[:self.n_cls] # sample n_cls classes from total classes. |
| 28 | for c in classes: |
| 29 | l = self.m_ind[c] # all data indexs of this class |
| 30 | pos = torch.randperm(len(l))[:self.n_per] # sample n_per data index of this class |
| 31 | batch.append(l[pos]) |
| 32 | batch = torch.stack(batch).t().reshape(-1) |
| 33 | # .t() transpose, |
| 34 | # due to it, the label is in the sequence of abcdabcdabcd form after reshape, |
| 35 | # instead of aaaabbbbccccdddd |
| 36 | yield batch |
| 37 | # finally sample n_batch* n_cls(way)* n_per(shot) instances. per bacth. |
| 38 | |
| 39 | |
| 40 |
no outgoing calls
no test coverage detected