def test_queue_enumerate(self): f = poutine.trace(poutine.queue(self.model, queue=self.queue)) trs = [] while not self.queue.empty(): trs.append(f.get_trace()) assert len(trs) == 2 values = [ { name: tr.nodes[name]["value"].view(-1).item() for name in tr.nodes.keys() if tr.nodes[name]["type"] == "sample" } for tr in trs ] expected_ys = set([0, 1]) actual_ys = set([value["y"] for value in values]) assert actual_ys == expected_ys # Check that x was sampled the same on all each paths. assert values[0]["x"] == values[1]["x"] # Check that y was sampled differently on each path. assert values[0]["z"] != values[1]["z"] # Almost surely true.
def _get_traces(self, model, guide, args, kwargs): """ Runs the guide and runs the model against the guide with the result packaged as a trace generator. """ if self.max_plate_nesting == float('inf'): self._guess_max_plate_nesting(model, guide, args, kwargs) if self.vectorize_particles: guide = self._vectorized_num_particles(guide) model = self._vectorized_num_particles(model) # Enable parallel enumeration over the vectorized guide and model. # The model allocates enumeration dimensions after (to the left of) the guide, # accomplished by preserving the _ENUM_ALLOCATOR state after the guide call. guide_enum = EnumMessenger(first_available_dim=-1 - self.max_plate_nesting) model_enum = EnumMessenger() # preserve _ENUM_ALLOCATOR state guide = guide_enum(guide) model = model_enum(model) q = queue.LifoQueue() guide = poutine.queue(guide, q, escape_fn=iter_discrete_escape, extend_fn=iter_discrete_extend) for i in range(1 if self.vectorize_particles else self.num_particles): q.put(poutine.Trace()) while not q.empty(): yield self._get_trace(model, guide, args, kwargs)
def test_queue_enumerate(self): f = poutine.trace(poutine.queue(self.model, queue=self.queue)) trs = [] while not self.queue.empty(): trs.append(f.get_trace()) assert len(trs) == 2**3 true_latents = set() for i1 in range(2): for i2 in range(2): for i3 in range(2): true_latents.add((i1, i2, i3)) tr_latents = [] for tr in trs: tr_latents.append( tuple( [ int(tr.nodes[name]["value"].view(-1).item()) for name in tr if tr.nodes[name]["type"] == "sample" and not tr.nodes[name]["is_observed"] ] ) ) assert true_latents == set(tr_latents)
def _traces(self, *args, **kwargs): q = queue.Queue() q.put(poutine.Trace()) p = poutine.trace(poutine.queue(self.model, queue=q, max_tries=self.max_tries)) while not q.empty(): tr = p.get_trace(*args, **kwargs) yield tr, tr.log_prob_sum()
def test_queue_max_tries(self): f = poutine.queue(self.model, queue=self.queue, max_tries=3) try: f() assert False except ValueError: self.assertTrue(True)
def _traces(self, *args, **kwargs): """ algorithm entered here Running until the queue is empty and collecting the marginal histogram is performing exact inference :returns: Iterator of traces from the posterior. :rtype: Generator[:class:`pyro.Trace`] """ # currently only using the standard library queue self.queue = Queue() self.queue.put(poutine.Trace()) p = poutine.trace( poutine.queue(self.model, queue=self.queue, max_tries=self.max_tries)) while not self.queue.empty(): tr = p.get_trace(*args, **kwargs) yield (tr, tr.log_pdf())
def test_queue_enumerate(self): f = poutine.trace(poutine.queue(self.model, queue=self.queue)) trs = [] while not self.queue.empty(): trs.append(f.get_trace()) assert len(trs) == 2 ** 3 true_latents = set() for i1 in range(2): for i2 in range(2): for i3 in range(2): true_latents.add((i1, i2, i3)) tr_latents = [] for tr in trs: tr_latents.append(tuple([int(tr.nodes[name]["value"].view(-1).item()) for name in tr if tr.nodes[name]["type"] == "sample" and not tr.nodes[name]["is_observed"]])) assert true_latents == set(tr_latents)
def iter_discrete_traces(graph_type, fn, *args, **kwargs): """ Iterate over all discrete choices of a stochastic function. When sampling continuous random variables, this behaves like `fn`. When sampling discrete random variables, this iterates over all choices. This yields traces scaled by the probability of the discrete choices made in the `trace`. :param str graph_type: The type of the graph, e.g. "flat" or "dense". :param callable fn: A stochastic function. :returns: An iterator over traces pairs. """ queue = LifoQueue() queue.put(Trace()) traced_fn = poutine.trace( poutine.queue(fn, queue, escape_fn=_iter_discrete_escape, extend_fn=_iter_discrete_extend), graph_type=graph_type) while not queue.empty(): yield traced_fn.get_trace(*args, **kwargs)
def iter_discrete_traces(graph_type, fn, *args, **kwargs): """ Iterate over all discrete choices of a stochastic function. When sampling continuous random variables, this behaves like `fn`. When sampling discrete random variables, this iterates over all choices. This yields traces scaled by the probability of the discrete choices made in the `trace`. :param str graph_type: The type of the graph, e.g. "flat" or "dense". :param callable fn: A stochastic function. :returns: An iterator over traces pairs. """ queue = LifoQueue() queue.put(Trace()) traced_fn = poutine.trace( poutine.queue(fn, queue, escape_fn=iter_discrete_escape, extend_fn=iter_discrete_extend), graph_type=graph_type) while not queue.empty(): yield traced_fn.get_trace(*args, **kwargs)
def test_queue_enumerate(self): f = poutine.trace(poutine.queue(self.model, queue=self.queue)) trs = [] while not self.queue.empty(): trs.append(f.get_trace()) assert len(trs) == 2 values = [ {name: tr.nodes[name]['value'].view(-1).item() for name in tr.nodes.keys() if tr.nodes[name]['type'] == 'sample'} for tr in trs ] expected_ys = set([0, 1]) actual_ys = set([value["y"] for value in values]) assert actual_ys == expected_ys # Check that x was sampled the same on all each paths. assert values[0]["x"] == values[1]["x"] # Check that y was sampled differently on each path. assert values[0]["z"] != values[1]["z"] # Almost surely true.
def test_queue_single(self): f = poutine.trace(poutine.queue(self.model, queue=self.queue)) tr = f.get_trace() for name in self.sites: assert name in tr
def test_queue_max_tries(self): f = poutine.queue(self.model, queue=self.queue, max_tries=3) with pytest.raises(ValueError): f()