Package: unique-randomizer
UniqueRandomizerOverviewUniqueRandomizer is a data structure for sampling outputs of a randomized
program, such as a neural sequence model,incrementallyandwithout
replacement.Incrementalsampling: Instead of sampling a large batch of outputs all at
once, as with beam search, UniqueRandomizer provides samples one at a time.
This enables flexibility in stopping criteria, such as stopping the sampling
process as soon as a satisfactory output is found.Samplingwithout replacement: In many applications, a neural model is used
to produce candidate solutions to some search or optimization problem. In
such applications it is usually desirable to consideruniquecandidate
solutions, since duplicates are typically not useful.For more details, refer to our paper,Incremental Sampling Without Replacement for Sequence Models,
published at ICML 2020.BibTeX entry:@article{shi2020uniquerandomizer,
  title = {Incremental Sampling Without Replacement for Sequence Models},
  author = {Kensen Shi and David Bieber and Charles Sutton},
  booktitle = {Proceedings of the 37th International Conference on Machine Learning},
  year = {2020}
}Installationpython3 -m pip install --user unique-randomizerThis package requires Python 3. The above command automatically installs the
following dependencies as well:absl-py >= 0.6.1numpy >= 1.15.4scipy >= 1.1.0UsageTo use UniqueRandomizer, first identify the program or function that you wish to
draw unique samples from, such as thedraw_samplefunction in the following
example:def draw_sample(sequence_model, state):
  """Draws a sample (a sequence of token indices) from the sequence model."""
  tokens = []
  token = BOS
  for i in range(MAX_LEN):
    probs, state = sequence_model(token, state)
    token = np.random.choice(np.arange(len(probs)), p=probs)
    if token == EOS:
      break
    tokens.append(token)
  return tokensNote thatdraw_samplecan take inputs and can use control flow such as loops,
conditionals, and recursion. There are only two constraints on thedraw_samplefunction:It must be deterministic given the inputs, except for random choices
provided bynp.random.choice(or some other method of selecting a random
index given a discrete probability distribution).Two different sequences of random choices must lead todraw_samplereturning different outputs.Next, add aUniqueRandomizerobject as an input todraw_sample, and use itssample_distributionfunction to replacenp.random.choice:- def draw_sample(sequence_model, state):+ def draw_sample(sequence_model, state, randomizer):"""Draws a sample (a sequence of token indices) from the sequence model."""tokens = []token = BOSfor i in range(MAX_LEN):probs, state = sequence_model(token, state)-     token = np.random.choice(np.arange(len(probs)), p=probs)+     token = randomizer.sample_distribution(probs)if token == EOS:breaktokens.append(token)return tokensFinally, a simple loop arounddraw_samplecan collect unique samples, as
follows:def draw_unique_samples(model, state, num_samples):
  """Draws multiple unique samples from the sequence model."""
  samples = []
  randomizer = unique_randomizer.UniqueRandomizer()
  for _ in range(num_samples):
    samples.append(draw_sample(model, state, randomizer))
    randomizer.mark_sequence_complete()
  return samplesCode SamplesWe include a few code samples that demonstrate how to use UniqueRandomizer:examples/weighted_coin_flips.py: This provides a very simple example of
using UniqueRandomizer. The functionflip_two_weighted_coinssimulates
flipping a pair of weighted coins. Thesample_flips_without_replacementfunction then uses UniqueRandomizer to efficiently sample outputs offlip_two_weighted_coinswithout replacement.examples/expand_grammar.py: This defines a Probabilistic Context-Free
Grammar (PCFG), as well as methods to sample elements of the grammar without
replacement by using UniqueRandomizer, rejection sampling, and Stochastic
Beam Search (SBS). The scriptexamples/expand_grammar_main.pyenables easy
comparison between the different sampling methods under different scenarios.examples/sequence_example.py: This implements sampling without replacement
from a sequence model, using UniqueRandomizer, Batched UniqueRandomizer,
rejection sampling, and SBS. The scriptexamples/sequence_example_main.pyenables easy comparison between the different sampling methods under
different scenarios.DisclaimerThis is not an officially supported Google product.