def test_exhaustive_enumeration(self): a = DiscreteFactor([(0, 2), (1, 3)], data=np.array([[1, 2, 3], [4, 5, 6]])) b = DiscreteFactor([(0, 2), (2, 2)], data=np.array([[1, 2], [2, 1]])) # 0 1 2 | #-------+-------- # 0 0 0 | 1x1=1 # 0 0 1 | 1x2=2 # 0 1 0 | 2x1=2 # 0 1 1 | 2x2=4 # 0 2 0 | 3x1=3 # 0 2 1 | 3x2=6 # 1 0 0 | 4x2=8 # 1 0 1 | 4x1=4 # 1 1 0 | 5x2=10 # 1 1 1 | 5x1=5 # 1 2 0 | 6x2=12 # 1 2 1 | 6x1=6 model = Model([a, b]) exact_inference = ExhaustiveEnumeration(model) c = exact_inference.calibrate().belief d = DiscreteFactor([(0, 2), (1, 3), (2, 2)]) d._data = np.array([1, 2, 2, 4, 3, 6, 8, 4, 10, 5, 12, 6]).reshape(2, 3, 2) self.assertEqual(d.variables, c.variables) self.assertEqual(d.axis_to_variable, c.axis_to_variable) assert_array_almost_equal(d._data, c.data)
def test_belief_update_larger_tree(self): a = DiscreteFactor([0, 1], data=np.array([[1, 2], [2, 2]], dtype=np.float64)) b = DiscreteFactor([1, 2], data=np.array([[3, 2], [1, 2]], dtype=np.float64)) c = DiscreteFactor([2, 3], data=np.array([[1, 2], [3, 4]], dtype=np.float64)) d = DiscreteFactor([3], data=np.array([2, 1], dtype=np.float64)) e = DiscreteFactor([0], data=np.array([4, 1], dtype=np.float64)) f = DiscreteFactor([2], data=np.array([1, 2], dtype=np.float64)) # # a{0 1} - b{1 2} - c{2 3} - d{3} # | | # e{0} f{2} # model = Model([a, b, c, d, e, f]) print 'edges', model.edges update_order = DistributeCollectProtocol(model) inference = LoopyBeliefUpdateInference(model, update_order=update_order) exact_inference = ExhaustiveEnumeration(model) exhaustive_answer = exact_inference.calibrate().belief print 'bp' change = inference.calibrate() print change for factor in model.factors: print factor for variable in model.variables: marginal_beliefs = inference.get_marginals(variable) true_marginal = exhaustive_answer.marginalize([variable]) for marginal in marginal_beliefs: assert_array_almost_equal(true_marginal.normalized_data, marginal.normalized_data) expected_ln_Z = np.log(exhaustive_answer.data.sum()) self.assertAlmostEqual(expected_ln_Z, inference.partition_approximation())
def test_update_beliefs_disconnected(self): a = DiscreteFactor([(1, 2), (2, 2)], data=np.array([[1, 2], [3, 4]], dtype=np.float64)) b = DiscreteFactor([(2, 2), (3, 2)], data=np.array([[1, 2], [3, 4]], dtype=np.float64)) c = DiscreteFactor([(4, 2), (5, 2)], data=np.array([[5, 6], [8, 9]], dtype=np.float64)) d = DiscreteFactor([(5, 2), (6, 2)], data=np.array([[1, 6], [2, 3]], dtype=np.float64)) e = DiscreteFactor([(7, 2), (8, 2)], data=np.array([[2, 1], [2, 3]], dtype=np.float64)) model = Model([a, b, c, d, e]) for factor in model.factors: print 'before', factor, np.sum(factor.data) update_order = DistributeCollectProtocol(model) inference = LoopyBeliefUpdateInference(model, update_order=update_order) exact_inference = ExhaustiveEnumeration(model) exhaustive_answer = exact_inference.calibrate().belief print 'Exhaust', np.sum(exhaustive_answer.data) change = inference.calibrate() print change for factor in model.factors: print factor, np.sum(factor.data) for variable in model.variables: marginal_beliefs = inference.get_marginals(variable) true_marginal = exhaustive_answer.marginalize([variable]) for marginal in marginal_beliefs: assert_array_almost_equal(true_marginal.normalized_data, marginal.normalized_data) expected_ln_Z = np.log(exhaustive_answer.data.sum()) self.assertAlmostEqual(expected_ln_Z, inference.partition_approximation())
def test_get_log_likelihood(self): a = DiscreteFactor([1, 2], parameters=np.array([[1, 2.0], [3, 4]])) b = DiscreteFactor([2, 3], parameters=np.array([[3, 4.0], [5, 7]])) # 1 2 3 | # -------+---------- # 0 0 0 | 1 * 3 = 3 # 0 0 1 | 1 * 4 = 4 # 0 1 0 | 2 * 5 = 10 # 0 1 1 | 2 * 7 = 14 # 1 0 0 | 3 * 3 = 9 # 1 0 1 | 3 * 4 = 12 # 1 1 0 | 4 * 5 = 20 # 1 1 1 | 4 * 7 = 28 # # p(1=0, 2, 3=1) = [4, 14] / 100 # => p(1=0, 3=1) = 18 / 100 model = Model([a, b]) evidence = {1: 0, 3: 1} exact_inference = ExhaustiveEnumeration(model) c = exact_inference.calibrate(evidence).belief print c print c.data print c.get_potential(evidence.items()) learner = LearnMrfParameters(model) actual_log_likelihood, _ = learner.log_likelihood_and_gradient(evidence) print actual_log_likelihood, np.log(0.18) self.assertAlmostEqual(actual_log_likelihood, np.log(0.18))
def test_loopy_distribute_collect(self): a = DiscreteFactor([0, 1], data=np.array([[1, 2], [2, 2]], dtype=np.float64)) b = DiscreteFactor([1, 2], data=np.array([[3, 2], [1, 2]], dtype=np.float64)) c = DiscreteFactor([2, 0], data=np.array([[1, 2], [3, 4]], dtype=np.float64)) # # a{0 1} - b{1 2} # \ / # c{2 0} # # a{0 1} - {0} - c{2 0} # # # # model = Model([a, b, c]) update_order = LoopyDistributeCollectProtocol(model, max_iterations=40) inference = LoopyBeliefUpdateInference(model, update_order=update_order) inference.calibrate() exact_inference = ExhaustiveEnumeration(model) exhaustive_answer = exact_inference.calibrate().belief for factor in model.factors: print factor, np.sum(factor.data) for var in model.variables_to_factors.keys(): print var, exhaustive_answer.marginalize([var]).data print for var in model.variables_to_factors.keys(): print var, inference.get_marginals(var)[0].data for variable in model.variables: for factor in inference.get_marginals(variable): expected_table = exhaustive_answer.marginalize([variable]) actual_table = factor.marginalize([variable]) assert_array_almost_equal(expected_table.normalized_data, actual_table.normalized_data, decimal=2) expected_ln_Z = np.log(exhaustive_answer.data.sum()) self.assertAlmostEqual(expected_ln_Z, inference.partition_approximation(), places=1)
def test_belief_update_long_tree(self): label_template = np.array([['same', 'different'], ['different', 'same']]) observation_template = np.array([['obs_low'] * 32, ['obs_high'] * 32]) observation_template[0, 13:17] = 'obs_high' observation_template[1, 13:17] = 'obs_low' N = 2 pairs = [DiscreteFactor([(i, 2), (i + 1, 2)], parameters=label_template) for i in xrange(N - 1)] obs = [DiscreteFactor([(i, 2), (i + N, 32)], parameters=observation_template) for i in xrange(N)] repe = [16., 16., 14., 13., 15., 16., 14., 13., 15., 16., 15., 13., 14., 16., 16., 15., 13., 13., 14., 14., 13., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 14., 9., 4., 4., 4., 4., 5., 3., 2., 3., 2., 3., 3., 3., 3., 3., 3., 3., 3., 4., 4., 5., 5., 5.] evidence = dict((i + N, 0 if repe[i % len(repe)] >= 13 and repe[i % len(repe)] < 17 else 1) for i in xrange(N)) model = Model(pairs + obs) parameters = {'same': 2.0, 'different': -1.0, 'obs_high': 0.0, 'obs_low': -0.0} update_order = FloodingProtocol(model, max_iterations=4) inference = LoopyBeliefUpdateInference(model, update_order=update_order) inference.calibrate(evidence, parameters) exact_inference = ExhaustiveEnumeration(model) exhaustive_answer = exact_inference.calibrate(evidence, parameters).belief for i in xrange(N): expected_marginal = exhaustive_answer.marginalize([i]) for actual_marginal in inference.get_marginals(i): print i print expected_marginal.normalized_data print actual_marginal.normalized_data assert_array_almost_equal(expected_marginal.normalized_data, actual_marginal.normalized_data) expected_ln_Z = np.log(exhaustive_answer.data.sum()) self.assertAlmostEqual(expected_ln_Z, inference.partition_approximation())