def test_mrf_EM(): """EXAMPLE: EM learning on a MRF""" """Define MRF graph structure""" C = 0 S = 1 R = 2 W = 3 nodes = 4 adj_mat = sparse.lil_matrix((nodes, nodes), dtype=int) adj_mat[C, [R, S]] = 1 adj_mat[R, W] = 1 adj_mat[S, W] = 1 adj_mat[R, S] = 1 """Define clique domains and node sizes""" ns = 2 * np.ones((1, nodes)) clq_doms = [[0], [0, 1], [0, 2], [1, 2, 3]] """Define cliques and potentials""" clqs = [] clqs.append(cliques.discrete_clique(0, clq_doms[0], np.array([2]))) clqs.append(cliques.discrete_clique(1, clq_doms[1], np.array([2, 2]))) clqs.append(cliques.discrete_clique(2, clq_doms[2], np.array([2, 2]))) clqs.append(cliques.discrete_clique(3, clq_doms[3], np.array([2, 2, 2]))) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs) """ Load the samples, and set one sample of one node to be unobserved, this should not effect the learnt parameter much, and will demonstrate that the algorithm can handle unobserved samples. """ samples = (np.array(pylab.load('./Data/lawn_samples.txt')) - 1).tolist() samples[0][0] = [] """Learn the parameters""" net.learn_params_EM(samples[:]) """Initialize the inference engine""" net.init_inference_engine(exact=True) """Create and enter evidence""" evidences = create_all_evidence(4, 2) mlcs = np.array([[0, 0, 0, 0]]) for evidence in evidences: mlc = net.max_sum(evidence) mlcs = np.vstack((mlcs, mlc)) """Read in expected values""" exp_mlcs = np.array(pylab.load('./Data/mrf_em_exact_max_sum_res.txt')) """Assert that the output matched the expected values""" assert_array_equal(mlcs, exp_mlcs)
def test_mrf_exact_sum_product(): """EXAMPLE: Junction tree sum-product on MRF""" """Define MRF graph structure""" C = 0 S = 1 R = 2 W = 3 nodes = 4 adj_mat = sparse.lil_matrix((nodes, nodes), dtype=int) adj_mat[C, [R, S]] = 1 adj_mat[R, W] = 1 adj_mat[S, W] = 1 adj_mat[R, S] = 1 """Define clique domains and node sizes""" ns = 2 * np.ones((1, nodes)) clq_doms = [[0, 1, 2], [1, 2, 3]] """Define cliques and potentials""" clqs = [] T = np.zeros((2, 2, 2)) T[:, :, 0] = np.array([[0.2, 0.2], [0.09, 0.01]]) T[:, :, 1] = np.array([[0.05, 0.05], [0.36, 0.04]]) clqs.append(cliques.discrete_clique(0, clq_doms[0], np.array([2, 2, 2]), T)) T[:, :, 0] = np.array([[1, 0.1], [0.1, 0.01]]) T[:, :, 1] = np.array([[0, 0.9], [0.9, 0.99]]) clqs.append(cliques.discrete_clique(1, clq_doms[1], np.array([2, 2, 2]), T)) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs) net.init_inference_engine(exact=True) """Create and enter evidence""" evidences = create_all_evidence(4, 2) results = [] for evidence in evidences: net.sum_product(evidence) result = [] result.append(np.max(net.marginal_nodes([0]).T)) result.append(np.max(net.marginal_nodes([1]).T)) result.append(np.max(net.marginal_nodes([2]).T)) result.append(np.max(net.marginal_nodes([3]).T)) results.append(result) results = np.array(results) """Get the expected results""" exp_results = np.array(pylab.load('./Data/mrf_exact_sum_product_res.txt')) """Assert that the output matched the expected values""" assert_array_equal(results, exp_results)
def test_mrf_approx_max_sum(): """EXAMPLE: Loopy belief max-sum on MRF""" """Define MRF graph structure""" C = 0 S = 1 R = 2 W = 3 nodes = 4 adj_mat = sparse.lil_matrix((nodes, nodes), dtype=int) adj_mat[C, [R, S]] = 1 adj_mat[R, W] = 1 adj_mat[S, W] = 1 adj_mat[R, S] = 1 """Define clique domains and node sizes""" ns = 2 * np.ones((1, nodes)) clq_doms = [[0, 1, 2], [1, 2, 3]] """Define cliques and potentials""" clqs = [] T = np.zeros((2, 2, 2)) T[:, :, 0] = np.array([[0.2, 0.2], [0.09, 0.01]]) T[:, :, 1] = np.array([[0.05, 0.05], [0.36, 0.04]]) clqs.append(cliques.discrete_clique(0, clq_doms[0], np.array([2, 2, 2]), T)) T[:, :, 0] = np.array([[1, 0.1], [0.1, 0.01]]) T[:, :, 1] = np.array([[0, 0.9], [0.9, 0.99]]) clqs.append(cliques.discrete_clique(1, clq_doms[1], np.array([2, 2, 2]), T)) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs) net.init_inference_engine(exact=False) """Create and enter evidence""" evidences = create_all_evidence(4, 2) mlcs = np.array([0, 0, 0, 0]) for evidence in evidences: mlc = net.max_sum(evidence) mlcs = np.vstack((mlcs, mlc)) """Read in expected values""" exp_mlcs = np.array(pylab.load('./Data/mrf_approx_max_sum_res.txt')) """Assert that the output matched the expected values""" assert_array_equal(mlcs, exp_mlcs)
nodes in the clique. A clique is a fully connected set of nodes. Therefore, for a set of node to be a clique, every node in the set must be connected to every other node in the set. """ clq_doms = [[0], [0, 1], [0, 2], [1, 2, 3]] """Create blank cliques with the required domains and sizes""" clqs = [] clqs.append(cliques.clique(0, clq_doms[0], np.array([2]))) clqs.append(cliques.clique(1, clq_doms[1], np.array([2, 2]))) clqs.append(cliques.clique(2, clq_doms[2], np.array([2, 2]))) clqs.append(cliques.clique(3, clq_doms[3], np.array([2, 2, 2]))) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs, lattice=False) """Define the samples that will be used to train the models parameters""" samples = \ [[0, 1, 0, None], [0, 1, 0, 1], [1, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 1], [0, 1, 0, 1], [1, 0, 1, 1], [0, 1, 0, 1], [0, 1, 0, 1], [1, 0, 1, 1],
Define the clique domains. The domain of a clique, is the indices of the nodes in the clique. A clique is a fully connected set of nodes. Therefore, for a set of node to be a clique, every node in the set must be connected to every other node in the set. """ clq_doms = [[0], [0, 1], [0, 2], [1, 2, 3]] """Create blank cliques with the required domains and sizes""" clqs = [] clqs.append(cliques.clique(0, clq_doms[0], np.array([2]))) clqs.append(cliques.clique(1, clq_doms[1], np.array([2, 2]))) clqs.append(cliques.clique(2, clq_doms[2], np.array([2, 2]))) clqs.append(cliques.clique(3, clq_doms[3], np.array([2, 2, 2]))) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs, lattice=False) """Define the samples that will be used to train the models parameters""" samples = \ [[0, 1, 0, 0], [0, 1, 0, 1], [1, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 1], [0, 1, 0, 1], [1, 0, 1, 1], [0, 1, 0, 1], [0, 1, 0, 1], [1, 0, 1, 1],
def denoise_image(img, depth=255, max_iter=10): """ Denoises a single channel image. Parameters ---------- img: Numpy array The image to denoise. depth: Int The number of different values a pixel can take. max_iter: Int The maximum number of times the inference algorithm can iterate. """ """ Create adjacency matrix representation of the hidden lattice graph that represents the denoised image. """ print "Creating initial adjacency matrix..." adj_mat = create_lattice_sparse_adj_matrix(img.shape[0], img.shape[1], 2) print "Determine the cliques from the adjacency matrix..." """Get the cliques as a list""" clq_doms = [] i = 0 for cols in adj_mat.rows: if len(cols) > 0: for col in cols: new_clique = [i, col] new_clique.sort() clq_doms.append(new_clique) i = i + 1 """Create list of node sizes""" print "Creating list of node sizes..." ns = depth * np.ones((1, img.shape[0]*img.shape[1]*2)) """Create list of cliques and assign potentials to them""" print "Creating the list of cliques and their potentials..." """Image model""" T_img = create_img_prob_table(depth, 1) """Noise model""" T_noise = create_img_prob_table(depth, 5) clqs = [] outer_layer = range(img.shape[0]*img.shape[1], img.shape[0]*img.shape[1]*2) for i in range(0, len(clq_doms)): if clq_doms[i][1] in outer_layer: clqs.append(cliques.discrete_clique(i, clq_doms[i], \ np.array([depth, depth]),\ T_img)) else: clqs.append(cliques.discrete_clique(i, clq_doms[i], \ np.array([depth, depth]), \ T_noise)) """Create the MRF object and set the lattice flag to TRUE""" print "Creating MRF..." net = models.mrf(adj_mat, ns, clqs, lattice=True) """Initialize the inference engine to be approximate""" net.init_inference_engine(exact=False, max_iter=max_iter) """Create the evidence, with the noisy nodes being observed""" evidence = img.flatten().tolist() N = len(evidence) for i in range(0, N): evidence.insert(0, []) """Run loopy-belief propagation""" print "Running loopy belief propagation..." mlc = net.max_sum(evidence) """ Extract denoised image from most likely configuaration of the hidden nodes. """ print "Extracting denoised image..." new_img = np.array(mlc[0:img.shape[0]*img.shape[1]]) new_img = np.array(new_img.reshape(img.shape[0], img.shape[1])) """Delete objects""" del img del adj_mat del net return new_img
def test_mrf_sumproduct(): """ Testing: SUM-PRODUCT on MRF This example is based on the lawn sprinkler example, and the Markov random field has the following structure. Cloudy - 0 / \ / \ / \ Sprinkler - 1 Rainy - 2 \ / \ / \ / Wet Grass -3 """ """Assign a unique numerical identifier to each node""" C = 0 S = 1 R = 2 W = 3 """Assign the number of nodes in the graph""" nodes = 4 """ The graph structure is represented as a adjacency matrix, dag. If adj_mat[i, j] = 1, then there exists a undirected edge from node i and node j. """ adj_mat = np.matrix(np.zeros((nodes, nodes))) adj_mat[C, [R, S]] = 1 adj_mat[R, W] = 1 adj_mat[S, W] = 1 """ Define the size of each node, which is the number of different values a node could observed at. For example, if a node is either True of False, it has only 2 possible values it could be, therefore its size is 2. All the nodes in this graph has a size 2. """ ns = 2 * np.ones(nodes) """ Define the clique domains. The domain of a clique, is the indices of the nodes in the clique. A clique is a fully connected set of nodes. Therefore, for a set of node to be a clique, every node in the set must be connected to every other node in the set. """ clq_doms = [[0, 1, 2], [1, 2, 3]] """Define potentials for the cliques""" clqs = [] T = np.zeros((2, 2, 2)) T[:, :, 0] = np.array([[0.2, 0.2], [0.09, 0.01]]) T[:, :, 1] = np.array([[0.05, 0.05], [0.36, 0.04]]) clqs.append(cliques.clique(0, clq_doms[0], np.array([2, 2, 2]), T)) T[:, :, 0] = np.array([[1, 0.1], [0.1, 0.01]]) T[:, :, 1] = np.array([[0, 0.9], [0.9, 0.99]]) clqs.append(cliques.clique(1, clq_doms[1], np.array([2, 2, 2]), T)) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs, lattice=False) """ Intialize the MRF's inference engine to use EXACT inference, by setting exact=True. """ net.init_inference_engine(exact=True) """Create and enter evidence ([] means that node is unobserved)""" all_ev = sprinkler_evidence(); all_prob = sprinkler_probs(); count = 0; errors = 0; for evidence in all_ev: """Execute the max-sum algorithm""" net.sum_product(evidence) ans = [1, 1, 1, 1] marginal = net.marginal_nodes([C]) if evidence[C] is None: ans[C] = marginal.T[1] marginal = net.marginal_nodes([S]) if evidence[S] is None: ans[S] = marginal.T[1] marginal = net.marginal_nodes([R]) if evidence[R] is None: ans[R] = marginal.T[1] marginal = net.marginal_nodes([W]) if evidence[W] is None: ans[W] = marginal.T[1] errors = errors + \ np.round(np.sum(np.array(ans) - np.array(all_prob[count])), 3) count = count + 1 assert errors == 0
def test_mrf_maxsum(): """ Testing: MAX-SUM of MRF This example is based on the lawn sprinkler example, and the Markov random field has the following structure. Cloudy - 0 / \ / \ / \ Sprinkler - 1 Rainy - 2 \ / \ / \ / Wet Grass -3 """ """Assign a unique numerical identifier to each node""" C = 0 S = 1 R = 2 W = 3 """Assign the number of nodes in the graph""" nodes = 4 """ The graph structure is represented as a adjacency matrix, dag. If adj_mat[i, j] = 1, then there exists a undirected edge from node i and node j. """ adj_mat = np.matrix(np.zeros((nodes, nodes))) adj_mat[C, [R, S]] = 1 adj_mat[R, W] = 1 adj_mat[S, W] = 1 """ Define the size of each node, which is the number of different values a node could observed at. For example, if a node is either True of False, it has only 2 possible values it could be, therefore its size is 2. All the nodes in this graph has a size 2. """ ns = 2 * np.ones(nodes) """ Define the clique domains. The domain of a clique, is the indices of the nodes in the clique. A clique is a fully connected set of nodes. Therefore, for a set of node to be a clique, every node in the set must be connected to every other node in the set. """ clq_doms = [[0, 1, 2], [1, 2, 3]] """Define potentials for the cliques""" clqs = [] T = np.zeros((2, 2, 2)) T[:, :, 0] = np.array([[0.2, 0.2], [0.09, 0.01]]) T[:, :, 1] = np.array([[0.05, 0.05], [0.36, 0.04]]) clqs.append(cliques.clique(0, clq_doms[0], np.array([2, 2, 2]), T)) T[:, :, 0] = np.array([[1, 0.1], [0.1, 0.01]]) T[:, :, 1] = np.array([[0, 0.9], [0.9, 0.99]]) clqs.append(cliques.clique(1, clq_doms[1], np.array([2, 2, 2]), T)) """Create the MRF""" net = models.mrf(adj_mat, ns, clqs, lattice=False) """ Intialize the MRF's inference engine to use EXACT inference, by setting exact=True. """ net.init_inference_engine(exact=True) """Create and enter evidence ([] means that node is unobserved)""" all_ev = sprinkler_evidence() all_mpe = sprinkler_mpe() count = 0 errors = 0 for evidence in all_ev: """Execute the max-sum algorithm""" mlc = net.max_sum(evidence) mpe = all_mpe[count] errors = errors + np.sum(np.array(mpe) - np.array(mlc)) count = count + 1 assert errors == 0