def test_inference(): # Test inference with different weights in different directions X, Y = generate_blocks_multinomial(noise=2, n_samples=1, seed=1) x, y = X[0], Y[0] n_states = x.shape[-1] edge_list = make_grid_edges(x, 4, return_lists=True) edges = np.vstack(edge_list) pw_horz = -1 * np.eye(n_states) xx, yy = np.indices(pw_horz.shape) # linear ordering constraint horizontally pw_horz[xx > yy] = 1 # high cost for unequal labels vertically pw_vert = -1 * np.eye(n_states) pw_vert[xx != yy] = 1 pw_vert *= 10 # generate edge weights edge_weights_horizontal = np.repeat(pw_horz[np.newaxis, :, :], edge_list[0].shape[0], axis=0) edge_weights_vertical = np.repeat(pw_vert[np.newaxis, :, :], edge_list[1].shape[0], axis=0) edge_weights = np.vstack([edge_weights_horizontal, edge_weights_vertical]) # do inference res = lp_general_graph(-x.reshape(-1, n_states), edges, edge_weights) for inference_method in get_installed(["lp", "ad3"]): # same inference through CRF inferface crf = DirectionalGridCRF(inference_method=inference_method) crf.initialize(X, Y) w = np.hstack([np.eye(3).ravel(), -pw_horz.ravel(), -pw_vert.ravel()]) y_pred = crf.inference(x, w, relaxed=True) if isinstance(y_pred, tuple): # ad3 produces an integer result if it found the exact solution assert_array_almost_equal(res[0], y_pred[0].reshape(-1, n_states)) assert_array_almost_equal(res[1], y_pred[1]) assert_array_equal(y, np.argmax(y_pred[0], axis=-1)) for inference_method in get_installed(["lp", "ad3", "qpbo"]): # again, this time discrete predictions only crf = DirectionalGridCRF(inference_method=inference_method) crf.initialize(X, Y) w = np.hstack([np.eye(3).ravel(), -pw_horz.ravel(), -pw_vert.ravel()]) y_pred = crf.inference(x, w, relaxed=False) assert_array_equal(y, y_pred)
def test_inference(): # Test inference with different weights in different directions X, Y = toy.generate_blocks_multinomial(noise=2, n_samples=1, seed=1) x, y = X[0], Y[0] n_states = x.shape[-1] edge_list = make_grid_edges(x, 4, return_lists=True) edges = np.vstack(edge_list) pw_horz = -1 * np.eye(n_states) xx, yy = np.indices(pw_horz.shape) # linear ordering constraint horizontally pw_horz[xx > yy] = 1 # high cost for unequal labels vertically pw_vert = -1 * np.eye(n_states) pw_vert[xx != yy] = 1 pw_vert *= 10 # generate edge weights edge_weights_horizontal = np.repeat(pw_horz[np.newaxis, :, :], edge_list[0].shape[0], axis=0) edge_weights_vertical = np.repeat(pw_vert[np.newaxis, :, :], edge_list[1].shape[0], axis=0) edge_weights = np.vstack([edge_weights_horizontal, edge_weights_vertical]) # do inference res = lp_general_graph(-x.reshape(-1, n_states), edges, edge_weights) for inference_method in get_installed(["lp", "ad3"]): # same inference through CRF inferface crf = DirectionalGridCRF(n_states=3, inference_method=inference_method) w = np.hstack([np.eye(3).ravel(), -pw_horz.ravel(), -pw_vert.ravel()]) y_pred = crf.inference(x, w, relaxed=True) if isinstance(y_pred, tuple): # ad3 produces an integer result if it found the exact solution assert_array_almost_equal(res[0], y_pred[0].reshape(-1, n_states)) assert_array_almost_equal(res[1], y_pred[1]) assert_array_equal(y, np.argmax(y_pred[0], axis=-1)) for inference_method in get_installed(["lp", "ad3", "qpbo"]): # again, this time discrete predictions only crf = DirectionalGridCRF(n_states=3, inference_method=inference_method) w = np.hstack([np.eye(3).ravel(), -pw_horz.ravel(), -pw_vert.ravel()]) y_pred = crf.inference(x, w, relaxed=False) assert_array_equal(y, y_pred)
def test_psi_discrete(): X, Y = toy.generate_blocks_multinomial(noise=2, n_samples=1, seed=1) x, y = X[0], Y[0] for inference_method in get_installed(["lp", "ad3", "qpbo"]): crf = DirectionalGridCRF(n_states=3, inference_method=inference_method) psi_y = crf.psi(x, y) assert_equal(psi_y.shape, (crf.size_psi,)) # first horizontal, then vertical # we trust the unaries ;) pw_psi_horz, pw_psi_vert = psi_y[crf.n_states * crf.n_features:].reshape( 2, crf.n_states, crf.n_states) xx, yy = np.indices(y.shape) assert_array_equal(pw_psi_vert, np.diag([9 * 4, 9 * 4, 9 * 4])) vert_psi = np.diag([10 * 3, 10 * 3, 10 * 3]) vert_psi[0, 1] = 10 vert_psi[1, 2] = 10 assert_array_equal(pw_psi_horz, vert_psi)
def test_joint_feature_discrete(): X, Y = generate_blocks_multinomial(noise=2, n_samples=1, seed=1) x, y = X[0], Y[0] for inference_method in get_installed(["lp", "ad3", "qpbo"]): crf = DirectionalGridCRF(inference_method=inference_method) crf.initialize(X, Y) joint_feature_y = crf.joint_feature(x, y) assert_equal(joint_feature_y.shape, (crf.size_joint_feature,)) # first horizontal, then vertical # we trust the unaries ;) pw_joint_feature_horz, pw_joint_feature_vert = joint_feature_y[crf.n_states * crf.n_features:].reshape( 2, crf.n_states, crf.n_states) xx, yy = np.indices(y.shape) assert_array_equal(pw_joint_feature_vert, np.diag([9 * 4, 9 * 4, 9 * 4])) vert_joint_feature = np.diag([10 * 3, 10 * 3, 10 * 3]) vert_joint_feature[0, 1] = 10 vert_joint_feature[1, 2] = 10 assert_array_equal(pw_joint_feature_horz, vert_joint_feature)
def test_multinomial_blocks_directional(): # testing cutting plane ssvm with directional CRF on easy multinomial # dataset X, Y = generate_blocks_multinomial(n_samples=10, noise=0.3, seed=0) n_labels = len(np.unique(Y)) crf = DirectionalGridCRF(n_states=n_labels, inference_method=inference_method) clf = NSlackSSVM(model=crf, max_iter=100, C=100, check_constraints=True, batch_size=1) clf.fit(X, Y) Y_pred = clf.predict(X) assert_array_equal(Y, Y_pred)
def test_joint_feature_continuous(): # FIXME # first make perfect prediction, including pairwise part X, Y = generate_blocks_multinomial(noise=2, n_samples=1, seed=1) x, y = X[0], Y[0] n_states = x.shape[-1] pw_horz = -1 * np.eye(n_states) xx, yy = np.indices(pw_horz.shape) # linear ordering constraint horizontally pw_horz[xx > yy] = 1 # high cost for unequal labels vertically pw_vert = -1 * np.eye(n_states) pw_vert[xx != yy] = 1 pw_vert *= 10 # create crf, assemble weight, make prediction for inference_method in get_installed(["lp", "ad3"]): crf = DirectionalGridCRF(inference_method=inference_method) crf.initialize(X, Y) w = np.hstack([np.eye(3).ravel(), -pw_horz.ravel(), -pw_vert.ravel()]) y_pred = crf.inference(x, w, relaxed=True) # compute joint_feature for prediction joint_feature_y = crf.joint_feature(x, y_pred) assert_equal(joint_feature_y.shape, (crf.size_joint_feature,))
def test_energy(): # make sure that energy as computed by ssvm is the same as by lp np.random.seed(0) for inference_method in get_installed(["lp", "ad3"]): found_fractional = False crf = DirectionalGridCRF(n_states=3, n_features=3, inference_method=inference_method) while not found_fractional: x = np.random.normal(size=(7, 8, 3)) unary_params = np.random.normal(size=(3, 3)) pw1 = np.random.normal(size=(3, 3)) pw2 = np.random.normal(size=(3, 3)) w = np.hstack([unary_params.ravel(), pw1.ravel(), pw2.ravel()]) res, energy = crf.inference(x, w, relaxed=True, return_energy=True) found_fractional = np.any(np.max(res[0], axis=-1) != 1) joint_feature = crf.joint_feature(x, res) energy_svm = np.dot(joint_feature, w) assert_almost_equal(energy, -energy_svm) if not found_fractional: # exact discrete labels, test non-relaxed version res, energy = crf.inference(x, w, relaxed=False, return_energy=True) joint_feature = crf.joint_feature(x, res) energy_svm = np.dot(joint_feature, w) assert_almost_equal(energy, -energy_svm)
This example illustrates the role of approximate inference and caching in exact learning of a 1-slack SSVM. Please see plot_objetive_curve.py for an interpretation of the curves. We start learning by using an undergenerating inference method, QPBO-based alpha expansion. One the algorithm can not find a violated constraint any more, we switch to a less efficient but exact inference procedure, branch-and-bound based on AD3. The switch to AD3 can be seen in the graph after the (approximate) primal objective and the cutting plane lower bound touch. (zoom in) After the switch to exact inference, the red circles show the true primal objective. """ from pystruct.models import DirectionalGridCRF import pystruct.learners as ssvm from pystruct.datasets import generate_blocks_multinomial from pystruct.plot_learning import plot_learning X, Y = generate_blocks_multinomial(noise=2, n_samples=20, seed=1) crf = DirectionalGridCRF(inference_method="qpbo", neighborhood=4) clf = ssvm.OneSlackSSVM(model=crf, n_jobs=-1, inference_cache=100, show_loss_every=10, switch_to=("ad3", {'branch_and_bound': True})) clf.fit(X, Y) plot_learning(clf, time=False)