88
99class LogUniformSampler (nn .Module ):
1010 def __init__ (
11- self , num_classes : int , * , distribution_clamp_min : float = 1e-10 , device : Optional [torch .device ] = None
11+ self ,
12+ num_classes : int ,
13+ * ,
14+ with_replacement : bool = True ,
15+ distribution_clamp_min : float = 1e-10 ,
16+ device : Optional [torch .device ] = None ,
1217 ):
1318 """
14- Samples from a log uniform distribution from classes. Sampling is performed with replacement, i.e. sampled
15- indices can appear more than once in sampled set. This can be implemented with
16- `torch.distributions.multinomial.Multinomial` or `torch.multinomial`.
19+ Samples from a log uniform distribution from classes. This assumes that the vocabulary is sorted according to
20+ word count descending.
1721
1822 :param num_classes: number of classes from which the distribution is sampled. The class indices are sorted in
1923 descending order according to their frequency.
24+ :param with_replacement: wether to sample with replacement or not.
25+ :param distribution_clamp_min: minimum probability mass.
2026 :param device: device on which the distribution is sampled.
2127 """
2228 super ().__init__ ()
2329
2430 # assumes count-sorted vocabulary, descending
2531 self .num_classes = num_classes
32+ self .with_replacement = with_replacement
2633
2734 # approximately zipf distribution
2835 ws = torch .arange (self .num_classes , dtype = torch .get_default_dtype (), device = device )
2936 self ._distribution = (torch .log1p (ws + 1 ) - torch .log1p (ws )) / torch .log1p (torch .tensor (self .num_classes ))
3037 self ._distribution .clamp_ (min = distribution_clamp_min )
3138 self ._distribution /= self ._distribution .sum ()
3239
33- self ._cat_sampler = torch .distributions .categorical .Categorical (probs = self ._distribution )
34-
3540 def sample (self , num_samples : int ) -> torch .Tensor :
3641 """
3742 Returns a random tensor in the size of [num_samples].
3843
3944 :param num_samples: number of samples.
4045 :return: [num_samples]
4146 """
42- return self . _cat_sampler . sample ( torch .Size ([ num_samples ]) )
47+ return torch .multinomial ( self . _distribution , num_samples , replacement = self . with_replacement )
4348
4449 def log_prob (self , indices : torch .Tensor ) -> torch .Tensor :
4550 """
@@ -48,4 +53,4 @@ def log_prob(self, indices: torch.Tensor) -> torch.Tensor:
4853 :param indices: the ground truth target labels as indices.
4954 :return: [B x T]
5055 """
51- return self . _cat_sampler . log_prob ( indices )
56+ return torch . log ( self . _distribution [ indices ] )
0 commit comments