def test_inverse_sampler(self, proposal_size, evidence_index): evidence = sprinkler_net.evidence(evidence_index) evidence_nodes = [self.net.nodes_by_index[index] for index in evidence.keys()] inverse_map = invert.compute_inverse_map( self.net, evidence_nodes, self.rng) # 2. Initialize inverses with uniform distributions trainer = train.Trainer(self.net, inverse_map, precompute_gibbs=False) # 3. Generate random data for _ in xrange(3): world = random_world.RandomWorld( range(self.net.node_count), [self.rng.choice(node.support) for node in self.net.nodes_by_index] ) trainer.observe(world) trainer.finalize() # 4. Compute true answer enumerator = exact_inference.Enumerator(self.net, evidence) true_marginals = enumerator.marginals() # 5. Compute answer using inverse sampling num_samples = 50000 test_sampler = mcmc.InverseChain( self.net, inverse_map, self.rng, evidence, proposal_size) test_sampler.initialize_state() inverse_marginals = test_sampler.marginals(num_samples) assert true_marginals - inverse_marginals < .02
def test_rejection(self, evidence_index): """Compare enumeration results with rejection results.""" evidence = sprinkler_net.evidence(evidence_index) enumerator = exact_inference.Enumerator(self.net, evidence) enum_marginals = enumerator.marginals() rejection_chain = mcmc.RejectionChain(self.net, self.rng, evidence) rej_marginals = rejection_chain.marginals(20000) for p_diff in (enum_marginals - rej_marginals).values(): assert p_diff < .01
def test_broad(self, evidence_index): """Test inversion across different evidence settings.""" evidence = sprinkler_net.evidence(evidence_index) evidence_nodes = [ self.net.nodes_by_index[index] for index in evidence.keys() ] inverse_map = invert.compute_inverse_map(self.net, evidence_nodes, self.rng) assert len(inverse_map) == 2 for (final_node, inverse_net) in inverse_map.items(): assert final_node.index not in evidence inv_final_node = inverse_net.nodes_by_index[final_node.index] assert len(inv_final_node.parents) == 2 for evidence_node in evidence_nodes: inv_evidence_node = inverse_net.nodes_by_index[ evidence_node.index] assert len(inv_evidence_node.parents) == 0
def test(self, evidence_index, precompute_gibbs): evidence = sprinkler_net.evidence(evidence_index) evidence_nodes = [self.net.nodes_by_index[index] for index in evidence.keys()] inverse_map = invert.compute_inverse_map( self.net, evidence_nodes, self.rng) assert len(inverse_map) == 2 trainer = train.Trainer(self.net, inverse_map, precompute_gibbs) num_samples = 30000 for _ in xrange(num_samples): sample = self.net.sample() trainer.observe(sample) trainer.finalize() # Compare marginal log probability for evidence node with prior marginals. empty_world = random_world.RandomWorld() enumerator = exact_inference.Enumerator(self.net, empty_world) exact_marginals = enumerator.marginals() for evidence_node in evidence_nodes: for value in [0, 1]: log_prob_true = math.log(exact_marginals[evidence_node.index][value]) for inverse_net in inverse_map.values(): log_prob_empirical = inverse_net.nodes_by_index[ evidence_node.index].log_probability(empty_world, value) print abs(log_prob_true - log_prob_empirical) assert abs(log_prob_true - log_prob_empirical) < .02 # For each inverse network, take unconditional samples, compare # marginals to prior network. num_samples = 30000 for inverse_net in inverse_map.values(): counts = [[0, 0], [0, 0], [0, 0]] for _ in xrange(num_samples): world = inverse_net.sample() for (index, value) in world.items(): counts[index][value] += 1 for index in [0, 1, 2]: true_dist = enumerator.marginalize_node( self.net.nodes_by_index[index]) empirical_dist = utils.normalize(counts[index]) for (p_true, p_empirical) in zip(true_dist, empirical_dist): print abs(p_true - p_empirical) assert abs(p_true - p_empirical) < .02
def test_evidence(self): with pytest.raises(ValueError): sprinkler_net.evidence(-1)
def test_sprinkler_net(proposal_size, evidence_index): rng = utils.RandomState(seed=0) net = sprinkler_net.get(rng) evidence = sprinkler_net.evidence(evidence_index) run_test(rng, net, evidence, proposal_size=proposal_size)