Download model/src/mrl_te_optimization/models/bucket_sampler.py from OneScience-Group/UTRGAN: direct link, hf CLI and curl.
- Browser
- Download file 3.85 kB
-
https://huggingface.co/OneScience-Group/UTRGAN/resolve/main/model/src/mrl_te_optimization/models/bucket_sampler.py
- Command line
-
hf download hf://OneScience-Group/UTRGAN/model/src/mrl_te_optimization/models/bucket_sampler.py
-
curl -L -o bucket_sampler.py https://huggingface.co/OneScience-Group/UTRGAN/resolve/main/model/src/mrl_te_optimization/models/bucket_sampler.py
3.85 kB
| import torch | |
| import numpy as np | |
| import pandas as pd | |
| from torch.utils.data.sampler import Sampler,BatchSampler,SubsetRandomSampler | |
| class Basic_sampler(Sampler): | |
| def __init__(self, data): | |
| super().__init__(data) | |
| self.data= data | |
| def __len__(self): | |
| return self.data.shape[0] | |
| def __iter__(self): | |
| return (i for i in range(self.data.shape[0])) | |
| class sort_sampler(Sampler): | |
| def __init__(self, data, sort_key="utr_len"): | |
| super().__init__(data) | |
| self.data = data | |
| self.sort_key = sort_key | |
| zip_ = [(i, seq_len) for i, seq_len in enumerate(data[sort_key].values)] | |
| zip_ = sorted(zip_, key=lambda r: r[1]) | |
| self.sorted_indexes = [item[0] for item in zip_] | |
| def __iter__(self): | |
| return iter(self.sorted_indexes) | |
| def __len__(self): | |
| return len(self.data) | |
| class Bucket_Sampler(BatchSampler): | |
| """ `BucketBatchSampler` toggles between `sampler` batches and sorted batches. | |
| Typically, the `sampler` will be a `RandomSampler` allowing the user to toggle between | |
| random batches and sorted batches. A larger `bucket_size_multiplier` is more sorted and vice | |
| versa. | |
| Background: | |
| ``BucketBatchSampler`` is similar to a ``BucketIterator`` found in popular libraries like | |
| ``AllenNLP`` and ``torchtext``. A ``BucketIterator`` pools together examples with a similar | |
| size length to reduce the padding required for each batch while maintaining some noise | |
| through bucketing. | |
| **AllenNLP Implementation:** | |
| https://github.com/allenai/allennlp/blob/master/allennlp/data/iterators/bucket_iterator.py | |
| **torchtext Implementation:** | |
| https://github.com/pytorch/text/blob/master/torchtext/data/iterator.py#L225 | |
| Args: | |
| sampler (torch.data.utils.sampler.Sampler): | |
| batch_size (int): Size of mini-batch. | |
| drop_last (bool): If `True` the sampler will drop the last batch if its size would be less | |
| than `batch_size`. | |
| sort_key (callable, optional): Callable to specify a comparison key for sorting. | |
| bucket_size_multiplier (int, optional): Buckets are of size | |
| `batch_size * bucket_size_multiplier`. | |
| Example: | |
| >>> from torchnlp.random import set_seed | |
| >>> set_seed(123) | |
| >>> | |
| >>> from torch.utils.data.sampler import SequentialSampler | |
| >>> sampler = SequentialSampler(list(range(10))) | |
| >>> list(BucketBatchSampler(sampler, batch_size=3, drop_last=False)) | |
| [[6, 7, 8], [0, 1, 2], [3, 4, 5], [9]] | |
| >>> list(BucketBatchSampler(sampler, batch_size=3, drop_last=True)) | |
| [[0, 1, 2], [3, 4, 5], [6, 7, 8]] | |
| """ | |
| def __init__(self, | |
| data, | |
| batch_size, | |
| drop_last=False, | |
| sort_key='utr_len', | |
| bucket_size_multiplier=100): | |
| self.data = data | |
| self.sampler = Basic_sampler(data) | |
| super().__init__(self.sampler, batch_size, drop_last) | |
| self.sort_key = sort_key | |
| _bucket_size = batch_size * bucket_size_multiplier | |
| if hasattr(self.sampler, "__len__"): | |
| _bucket_size = min(_bucket_size, len(self.sampler)) | |
| self.bucket_sampler = BatchSampler(self.sampler, _bucket_size, False) | |
| def __iter__(self): | |
| for bucket in self.bucket_sampler: | |
| sorted_sampler = sort_sampler(self.data.iloc[bucket], self.sort_key) | |
| for batch in SubsetRandomSampler( | |
| list(BatchSampler(sorted_sampler, self.batch_size, self.drop_last))): | |
| yield [bucket[i] for i in batch] | |
| def __len__(self): | |
| if self.drop_last: | |
| return len(self.sampler) // self.batch_size | |
| else: | |
| return np.ceil(len(self.sampler) / self.batch_size) | |